Merge branch 'master' into zenops_66

This commit is contained in:
zhaoke
2023-03-13 11:17:50 +08:00
108 changed files with 1340 additions and 459 deletions
+69 -17
View File
@@ -549,10 +549,11 @@ class gitlab
* @param string $version
* @param int $count
* @param string $branch
* @param bool $getFile
* @access public
* @return array
*/
public function getCommits($version = '', $count = 0, $branch = '')
public function getCommits($version = '', $count = 0, $branch = '', $getFile = false)
{
if(!scm::checkRevision($version)) return array();
$api = "commits";
@@ -620,7 +621,7 @@ class gitlab
$log->time = date('Y-m-d H:i:s', strtotime($commit->created_at));
$commits[$commit->id] = $log;
$files[$commit->id] = $this->getFilesByCommit($log->revision);
if($getFile) $files[$commit->id] = $this->getFilesByCommit($log->revision);
}
return array('commits' => $commits, 'files' => $files);
@@ -653,10 +654,12 @@ class gitlab
* @param string $fromRevision
* @param string $toRevision
* @param int $perPage
* @param int $page
* @param bool $getUrl
* @access public
* @return array
*/
public function getCommitsByPath($path, $fromRevision = '', $toRevision = '', $perPage = 0)
public function getCommitsByPath($path, $fromRevision = '', $toRevision = '', $perPage = 0, $page = 1, $getUrl = false)
{
$path = ltrim($path, DIRECTORY_SEPARATOR);
$api = "commits";
@@ -683,6 +686,18 @@ class gitlab
if($until) $param->until = $until;
if($perPage) $param->per_page = $perPage;
if($page) $param->page = $page;
if($getUrl)
{
$params = (array) $param;
$params['private_token'] = $this->token;
$params['per_page'] = isset($params['per_page']) ? $params['per_page'] : 100;
$api = ltrim($api, '/');
$api = $this->root . $api . '?' . http_build_query($params);
return $api;
}
return $this->fetch($api, $param);
}
@@ -736,10 +751,11 @@ class gitlab
*
* @param string $path
* @param bool $recursive
* @param bool $loop
* @access public
* @return mixed
*/
public function tree($path, $recursive = 1)
public function tree($path, $recursive = 1, $loop = false)
{
$api = "tree";
@@ -747,17 +763,20 @@ class gitlab
$params['path'] = ltrim($path, '/');
$params['ref'] = $this->branch;
$params['recursive'] = (int) $recursive;
return $this->fetch($api, $params);
return $this->fetch($api, $params, $loop, $loop ? true : false);
}
/**
* Fetch data from gitlab api.
*
* @param string $api
* @param array $params
* @param bool $needToLoop
* @param bool $multi
* @access public
* @return mixed
*/
public function fetch($api, $params = array(), $needToLoop = false)
public function fetch($api, $params = array(), $needToLoop = false, $multi = false)
{
$params = (array) $params;
$params['private_token'] = $this->token;
@@ -768,19 +787,49 @@ class gitlab
if($needToLoop)
{
$allResults = array();
for($page = 1; true; $page++)
if($multi)
{
$results = json_decode(commonModel::http($api . "&page={$page}"));
if(!is_array($results)) break;
if(!empty($results)) $allResults = array_merge($allResults, $results);
if(count($results) < 100) break;
$results = commonModel::httpWithHeader($api . "&page=1");
if(empty($results['header']['X-Total-Pages'])) return array();
$totalPages = $results['header']['X-Total-Pages'];
if($totalPages == 1)
{
$allResults = json_decode($results['body']);
}
else
{
$requests = array();
for($page = 1; $page <= $totalPages; $page++)
{
$requests[$page]['url'] = $api . "&page={$page}";
}
$results = requests::request_multiple($requests, array('timeout' => 60));
foreach($results as $result)
{
if(empty($result->body)) continue;
$data = json_decode($result->body);
$allResults = array_merge($allResults, $data);
}
}
}
else
{
for($page = 1; true; $page++)
{
$results = json_decode(commonModel::http($api . "&page={$page}", null, array(), array(), 'data', 'POST', 30, true, false));
if(!is_array($results)) break;
if(!empty($results)) $allResults = array_merge($allResults, $results);
if(count($results) < 100) break;
}
}
return $allResults;
}
else
{
list($response, $httpCode) = commonModel::http($api, null, array(), array(), 'data', 'Post', 30, true);
list($response, $httpCode) = commonModel::http($api, null, array(), array(), 'data', 'POST', 30, true, false);
if(!empty(commonModel::$requestErrors))
{
commonModel::$requestErrors = array();
@@ -828,12 +877,15 @@ class gitlab
$parsedLog->time = date('Y-m-d H:i:s', strtotime($commit->committed_date));
$parsedLog->comment = $commit->message;
$parsedLog->change = array();
foreach($commit->diffs as $diff)
if(!empty($commit->diffs))
{
$parsedLog->change[$diff->path] = array();
$parsedLog->change[$diff->path]['action'] = $diff->action;
$parsedLog->change[$diff->path]['kind'] = $diff->type;
$parsedLog->change[$diff->path]['oldPath'] = $diff->oldPath;
foreach($commit->diffs as $diff)
{
$parsedLog->change[$diff->path] = array();
$parsedLog->change[$diff->path]['action'] = $diff->action;
$parsedLog->change[$diff->path]['kind'] = $diff->type;
$parsedLog->change[$diff->path]['oldPath'] = $diff->oldPath;
}
}
$parsedLogs[] = $parsedLog;
}
+14 -1
View File
@@ -320,6 +320,11 @@ class adminModel extends model
{
$menu['disabled'] = true;
if(!isset($menu['link'])) $menu['link'] = '';
if($menuKey == 'company')
{
$dept = $this->dao->select('id')->from(TABLE_DEPT)->fetch();
if($dept and common::hasPriv('company', 'browse')) $menu['link'] = helper::createLink('company', 'browse');
}
/* Set links to authorized navigation. */
if(isset($menu['subMenu']))
@@ -338,7 +343,15 @@ class adminModel extends model
$this->loadModel('mail');
if(!$this->config->mail->turnon and !$this->session->mailConfig) $subMenu['link'] = $this->lang->mail->common . '|mail|detect|';
}
if($menuKey == 'dev' and $subMenuKey == 'editor' and !empty($this->config->global->editor)) $subMenu['link'] = $this->lang->editor->common . '|editor|index|';
if($menuKey == 'dev' and $subMenuKey == 'editor')
{
if(!empty($this->config->global->editor)) $subMenu['link'] = $this->lang->editor->common . '|editor|index|';
if(empty($this->config->global->editor) and !$this->app->user->admin)
{
unset($menu['subMenu']['editor']);
continue;
}
}
$link = array();
if(isset($menu['tabMenu'][$subMenuKey]))
+8 -1
View File
@@ -1,3 +1,10 @@
body {padding-bottom: 0px; background-color: #fff;}
::-webkit-scrollbar {width: 10px; height: 10px;}
::-webkit-scrollbar-button {width: 0; height: 0;}
::-webkit-scrollbar-thumb:vertical {min-height: 28px; background-color: rgba(0, 0, 0, 0.2); background-clip: padding-box; border-radius: 2px; -webkit-box-shadow: inset 1px 1px 0 rgb(0 0 0 / 10%), inset 0 -1px 0 rgb(0 0 0 / 7%);}
::-webkit-scrollbar-track:hover {background-color:rgba(0,0,0,.05);-webkit-box-shadow:inset 1px 0 0 rgba(0,0,0,.1);}
::-webkit-scrollbar-thumb:hover{background-color:rgba(0,0,0,.4);}
body.m-api-debug {padding-bottom: 0px; background-color: #fff;}
#api p {margin: 5px 0 2px 0;}
.c-name {width: 80px;}
.m-api-debug .main-header {padding: 10px 20px;}
+1
View File
@@ -215,3 +215,4 @@ $lang->api_lib_release->version = 'Version';
$lang->api->error = new stdclass();
$lang->api->error->onlySelect = 'Das SQL Interface erlaubt nur SELECT Abfragen.';
$lang->api->error->disabled = 'For security reasons, this feature is disabled. You can go to the config directory and modify the configuration item %s to open this function.';
$lang->api->error->notInput = 'Debugging is not supported temporarily due to field parameter type restrictions';
+1
View File
@@ -215,3 +215,4 @@ $lang->api_lib_release->version = 'Version';
$lang->api->error = new stdclass();
$lang->api->error->onlySelect = 'SQL API only allows SELECT query.';
$lang->api->error->disabled = 'For security reasons, this feature is disabled. Go to the config directory and modify the configuration item %s to enable it.';
$lang->api->error->notInput = 'Debugging is not supported temporarily due to field parameter type restrictions';
+1
View File
@@ -215,3 +215,4 @@ $lang->api_lib_release->version = 'Version';
$lang->api->error = new stdclass();
$lang->api->error->onlySelect = 'Cette interface SQL ne supporte que les requêtes SELECT.';
$lang->api->error->disabled = 'For security reasons, this feature is disabled. You can go to the config directory and modify the configuration item %s to open this function.';
$lang->api->error->notInput = 'Debugging is not supported temporarily due to field parameter type restrictions';
+1
View File
@@ -215,3 +215,4 @@ $lang->api_lib_release->version = '版本';
$lang->api->error = new stdclass();
$lang->api->error->onlySelect = 'SQL查询接口只允许SELECT查询';
$lang->api->error->disabled = '因为安全原因,该功能被禁用。可以到config目录,修改配置项 %s,打开此功能。';
$lang->api->error->notInput = '因字段参数类型限制,暂不支持调试';
+4
View File
@@ -20,7 +20,11 @@
<?php foreach($method->parameters as $param):?>
<tr>
<th class='c-name'><?php echo $param->name?></th>
<?php if(!$param->isOptional() or is_string($param->getDefaultValue())):?>
<td><?php echo html::input("$param->name", $param->isOptional() ? $param->getDefaultValue() : '', "class='form-control'")?></td>
<?php else:?>
<td><?php echo $lang->api->error->notInput . html::hidden("$param->name", '', "class='form-control'")?></td>
<?php endif;?>
</tr>
<?php endforeach;?>
<tr>
+1 -1
View File
@@ -45,7 +45,7 @@
$viewLink = $this->createLink('execution', 'task', 'executionID=' . $execution->id);
?>
<tr <?php echo $appid?>>
<td class='c-name text-left' title='<?php echo $execution->name;?>'><nobr><?php echo html::a($viewLink, $execution->name, '', "title='$execution->name'");?></nobr></td>
<td class='c-name text-left' title='<?php echo $execution->name;?>'><nobr><?php echo html::a($viewLink, $execution->name, '', "title='$execution->name' class='text-primary'");?></nobr></td>
<td class="c-date"><?php echo $execution->end;?></td>
<?php if($longBlock):?>
<td class="w-70px">
+2
View File
@@ -49,6 +49,8 @@ $().ready(function()
}
});
$('#product').change();
$('[data-toggle="popover"]').popover();
});
/**
+3 -1
View File
@@ -60,7 +60,9 @@
<tr class='hide'>
<th class='w-120px'><?php echo $lang->build->builds;?></th>
<td id='buildBox'><?php echo html::select('builds[]', array(), '', "class='form-control chosen' multiple data-placeholder='{$lang->build->placeholder->multipleSelect}'");?></td>
<td><?php echo $lang->build->notice->autoRelation;?></td>
<td>
<icon class='icon icon-help' data-toggle='popover' data-trigger='focus hover' data-placement='right' data-tip-class='text-muted popover-sm' data-content="<?php echo $lang->build->notice->autoRelation;?>"></icon>
</td>
</tr>
<tr>
<th class='w-120px'><?php echo $lang->build->name;?></th>
+3 -2
View File
@@ -209,6 +209,7 @@ $lang->stage->type = 'Stage Type';
$lang->stage->list = 'Stage List';
$lang->stage->percent = 'Workload Ratio';
$lang->execution->list = "{$lang->executionCommon} List";
$lang->execution->CFD = "Cumulative Flow Diagrams";
$lang->kanban->common = 'Kanban';
$lang->backup->common = 'Backup';
$lang->action->trash = 'Recycle';
@@ -339,7 +340,7 @@ $lang->searchObjects['caselib'] = 'Case Library';
$lang->searchObjects['testreport'] = 'Test-Bericht';
$lang->searchObjects['program'] = 'Program';
$lang->searchObjects['project'] = $lang->projectCommon;
$lang->searchObjects['execution'] = $lang->executionCommon;
$lang->searchObjects['execution'] = $lang->execution->common;
$lang->searchObjects['user'] = 'User';
$lang->searchTips = '';
@@ -363,7 +364,7 @@ $lang->visionList['lite'] = 'Operation Management Interface';
$lang->createObjects['todo'] = 'Todo';
$lang->createObjects['effort'] = 'Effort';
$lang->createObjects['bug'] = 'Bug';
$lang->createObjects['story'] = 'Story';
$lang->createObjects['story'] = $lang->SRCommon;
$lang->createObjects['task'] = 'Task';
$lang->createObjects['testcase'] = 'Case';
$lang->createObjects['execution'] = $lang->execution->common;
+3 -2
View File
@@ -209,6 +209,7 @@ $lang->stage->type = 'Stage Type';
$lang->stage->list = 'Stage List';
$lang->stage->percent = 'Workload Ratio';
$lang->execution->list = "{$lang->executionCommon} List";
$lang->execution->CFD = "Cumulative Flow Diagrams";
$lang->kanban->common = 'Kanban';
$lang->backup->common = 'Backup';
$lang->action->trash = 'Recycle';
@@ -339,7 +340,7 @@ $lang->searchObjects['caselib'] = 'Case Library';
$lang->searchObjects['testreport'] = 'Test Report';
$lang->searchObjects['program'] = 'Program';
$lang->searchObjects['project'] = $lang->projectCommon;
$lang->searchObjects['execution'] = $lang->executionCommon;
$lang->searchObjects['execution'] = $lang->execution->common;
$lang->searchObjects['user'] = 'User';
$lang->searchTips = 'ID (ctrl+g)';
@@ -363,7 +364,7 @@ $lang->visionList['lite'] = 'Operation Management Interface';
$lang->createObjects['todo'] = 'Todo';
$lang->createObjects['effort'] = 'Effort';
$lang->createObjects['bug'] = 'Bug';
$lang->createObjects['story'] = 'Story';
$lang->createObjects['story'] = $lang->SRCommon;
$lang->createObjects['task'] = 'Task';
$lang->createObjects['testcase'] = 'Case';
$lang->createObjects['execution'] = $lang->execution->common;
+3 -2
View File
@@ -209,6 +209,7 @@ $lang->stage->type = 'Stage Type';
$lang->stage->list = 'Stage List';
$lang->stage->percent = 'Workload Ratio';
$lang->execution->list = "{$lang->executionCommon} List";
$lang->execution->CFD = "Cumulative Flow Diagrams";
$lang->kanban->common = 'Kanban';
$lang->backup->common = 'Backup';
$lang->action->trash = 'Recycle';
@@ -339,7 +340,7 @@ $lang->searchObjects['caselib'] = 'Case Library';
$lang->searchObjects['testreport'] = 'CR de Test';
$lang->searchObjects['program'] = 'Program';
$lang->searchObjects['project'] = $lang->projectCommon;
$lang->searchObjects['execution'] = $lang->executionCommon;
$lang->searchObjects['execution'] = $lang->execution->common;
$lang->searchObjects['user'] = 'User';
$lang->searchTips = '';
@@ -363,7 +364,7 @@ $lang->visionList['lite'] = 'Operation Management Interface';
$lang->createObjects['todo'] = 'Todo';
$lang->createObjects['effort'] = 'Effort';
$lang->createObjects['bug'] = 'Bug';
$lang->createObjects['story'] = 'Story';
$lang->createObjects['story'] = $lang->SRCommon;
$lang->createObjects['task'] = 'Task';
$lang->createObjects['testcase'] = 'Case';
$lang->createObjects['execution'] = $lang->execution->common;
+4 -2
View File
@@ -418,6 +418,7 @@ $lang->project->noMultiple->scrum->menu->settings = $lang->scrum->menu->settin
$lang->project->noMultiple->kanban = new stdclass();
$lang->project->noMultiple->kanban->menu = new stdclass();
$lang->project->noMultiple->kanban->menu->kanban = array('link' => "{$lang->kanban->common}|execution|kanban|executionID=%s");
$lang->project->noMultiple->kanban->menu->CFD = array('link' => "{$lang->execution->CFD}|execution|cfd|executionID=%s");
$lang->project->noMultiple->kanban->menu->build = $lang->kanbanProject->menu->build;
$lang->project->noMultiple->kanban->menu->settings = $lang->kanbanProject->menu->settings;
@@ -438,8 +439,9 @@ $lang->project->noMultiple->scrum->menuOrder[50] = 'dynamic';
$lang->project->noMultiple->scrum->menuOrder[55] = 'settings';
$lang->project->noMultiple->kanban->menuOrder[5] = 'kanban';
$lang->project->noMultiple->kanban->menuOrder[10] = 'build';
$lang->project->noMultiple->kanban->menuOrder[15] = 'settings';
$lang->project->noMultiple->kanban->menuOrder[10] = 'CFD';
$lang->project->noMultiple->kanban->menuOrder[15] = 'build';
$lang->project->noMultiple->kanban->menuOrder[20] = 'settings';
/* QA menu.*/
$lang->qa->menu = new stdclass();
+4 -3
View File
@@ -209,6 +209,7 @@ $lang->stage->type = '阶段类型';
$lang->stage->list = '阶段列表';
$lang->stage->percent = '工作量占比';
$lang->execution->list = "{$lang->executionCommon}列表";
$lang->execution->CFD = "累积流图";
$lang->kanban->common = '看板';
$lang->backup->common = '备份';
$lang->action->trash = '回收站';
@@ -339,7 +340,7 @@ $lang->searchObjects['caselib'] = '用例库';
$lang->searchObjects['testreport'] = '测试报告';
$lang->searchObjects['program'] = '项目集';
$lang->searchObjects['project'] = $lang->projectCommon;
$lang->searchObjects['execution'] = $lang->executionCommon;
$lang->searchObjects['execution'] = $lang->execution->common;
$lang->searchObjects['user'] = '用户';
$lang->searchTips = '编号(ctrl+g)';
@@ -363,10 +364,10 @@ $lang->visionList['lite'] = '运营管理界面';
$lang->createObjects['todo'] = '待办';
$lang->createObjects['effort'] = '日志';
$lang->createObjects['bug'] = 'Bug';
$lang->createObjects['story'] = '需求';
$lang->createObjects['story'] = $lang->SRCommon;
$lang->createObjects['task'] = '任务';
$lang->createObjects['testcase'] = '用例';
$lang->createObjects['execution'] = '执行';
$lang->createObjects['execution'] = $lang->execution->common;
$lang->createObjects['project'] = $lang->projectCommon;
$lang->createObjects['product'] = $lang->productCommon;
$lang->createObjects['program'] = '项目集';
+31 -24
View File
@@ -912,7 +912,7 @@ class commonModel extends model
$btnTitle = isset($lang->db->custom['common']['mainNav'][$tab]) ? $lang->db->custom['common']['mainNav'][$tab] : $lang->$tab->common;
$commonKey = $tab . 'Common';
if(isset($lang->$commonKey)) $btnTitle = $lang->$commonKey;
if(isset($lang->$commonKey) and $tab != 'execution') $btnTitle = $lang->$commonKey;
$link = helper::createLink($currentModule, $currentMethod);
$className = $tab == 'devops' ? 'btn num' : 'btn';
@@ -3181,18 +3181,21 @@ EOD;
curl_close($curl);
$logFile = $app->getLogRoot() . 'saas.'. date('Ymd') . '.log.php';
if(!file_exists($logFile)) file_put_contents($logFile, '<?php die(); ?' . '>');
$fh = @fopen($logFile, 'a');
if($fh)
if($app->config->debug)
{
fwrite($fh, date('Ymd H:i:s') . ": " . $app->getURI() . "\n");
fwrite($fh, "url: " . $url . "\n");
if(!empty($data)) fwrite($fh, "data: " . print_r($data, true) . "\n");
fwrite($fh, "results:" . print_r($response, true) . "\n");
if(!empty($errors)) fwrite($fh, "errors: " . $errors . "\n");
fclose($fh);
$logFile = $app->getLogRoot() . 'saas.'. date('Ymd') . '.log.php';
if(!file_exists($logFile)) file_put_contents($logFile, '<?php die(); ?' . '>');
$fh = @fopen($logFile, 'a');
if($fh)
{
fwrite($fh, date('Ymd H:i:s') . ": " . $app->getURI() . "\n");
fwrite($fh, "url: " . $url . "\n");
if(!empty($data)) fwrite($fh, "data: " . print_r($data, true) . "\n");
fwrite($fh, "results:" . print_r($response, true) . "\n");
if(!empty($errors)) fwrite($fh, "errors: " . $errors . "\n");
fclose($fh);
}
}
if($errors) commonModel::$requestErrors[] = $errors;
@@ -3211,11 +3214,12 @@ EOD;
* @param string $method POST|PATCH|PUT
* @param int $timeout
* @param bool $httpCode
* @param bool $log
* @static
* @access public
* @return string
*/
public static function http($url, $data = null, $options = array(), $headers = array(), $dataType = 'data', $method = 'POST', $timeout = 30, $httpCode = false)
public static function http($url, $data = null, $options = array(), $headers = array(), $dataType = 'data', $method = 'POST', $timeout = 30, $httpCode = false, $log = true)
{
global $lang, $app;
if(!extension_loaded('curl'))
@@ -3265,18 +3269,21 @@ EOD;
if($httpCode) $httpCode = curl_getinfo($curl,CURLINFO_HTTP_CODE);
curl_close($curl);
$logFile = $app->getLogRoot() . 'saas.'. date('Ymd') . '.log.php';
if(!file_exists($logFile)) file_put_contents($logFile, '<?php die(); ?' . '>');
$fh = @fopen($logFile, 'a');
if($fh)
if($log or $app->config->debug)
{
fwrite($fh, date('Ymd H:i:s') . ": " . $app->getURI() . "\n");
fwrite($fh, "url: " . $url . "\n");
if(!empty($data)) fwrite($fh, "data: " . print_r($data, true) . "\n");
fwrite($fh, "results:" . print_r($response, true) . "\n");
if(!empty($errors)) fwrite($fh, "errors: " . $errors . "\n");
fclose($fh);
$logFile = $app->getLogRoot() . 'saas.'. date('Ymd') . '.log.php';
if(!file_exists($logFile)) file_put_contents($logFile, '<?php die(); ?' . '>');
$fh = @fopen($logFile, 'a');
if($fh)
{
fwrite($fh, date('Ymd H:i:s') . ": " . $app->getURI() . "\n");
fwrite($fh, "url: " . $url . "\n");
if(!empty($data)) fwrite($fh, "data: " . print_r($data, true) . "\n");
fwrite($fh, "results:" . print_r($response, true) . "\n");
if(!empty($errors)) fwrite($fh, "errors: " . $errors . "\n");
fclose($fh);
}
}
if($errors) commonModel::$requestErrors[] = $errors;
+16 -2
View File
@@ -129,7 +129,14 @@ class compileModel extends model
$url = new stdclass();
$url->userPWD = "$jenkinsUser:$jenkinsPassword";
$url->url = sprintf('%s/job/%s/buildWithParameters/api/json', $jenkinsServer, $jenkins->pipeline);
if(strpos($jenkins->pipeline, '/job/') !== false)
{
$url->url = sprintf('%s%sbuildWithParameters/api/json', $jenkinsServer, $jenkins->pipeline);
}
else
{
$url->url = sprintf('%s/job/%s/buildWithParameters/api/json', $jenkinsServer, $jenkins->pipeline);
}
return $url;
}
@@ -261,7 +268,14 @@ class compileModel extends model
$jenkinsPassword = $jenkins->token ? $jenkins->token : base64_decode($jenkins->password);
/* Get build list by API. */
$url = sprintf('%s/job/%s/api/json?tree=builds[id,number,result,queueId,timestamp]', $jenkins->url, $job->pipeline);
if(strpos($job->pipeline, '/job/') !== false)
{
$url = sprintf('%s%sapi/json?tree=builds[id,number,result,queueId,timestamp]', $jenkins->url, $job->pipeline);
}
else
{
$url = sprintf('%s/job/%s/api/json?tree=builds[id,number,result,queueId,timestamp]', $jenkins->url, $job->pipeline);
}
$response = common::http($url, '', array(CURLOPT_USERPWD => "$jenkinsUser:$jenkinsPassword"));
if(!$response) return false;
+2 -2
View File
@@ -28,7 +28,7 @@ class dev extends control
$this->view->tab = 'api';
$this->view->selectedModule = $module;
$this->view->apis = $module ? $this->dev->getAPIs($module) : array();
$this->view->modules = $this->dev->getModules();
$this->view->moduleTree = $this->dev->getTree($module, 'module');
$this->display();
}
@@ -45,7 +45,7 @@ class dev extends control
$this->view->position[] = html::a(inlink('api'), $this->lang->dev->common);
$this->view->position[] = $this->lang->dev->db;
$this->view->tables = $this->dev->getTables();
$this->view->tableTree = $this->dev->getTree($table, 'table');
$this->view->selectedTable = $table;
$this->view->tab = 'db';
$this->view->fields = $table ? $this->dev->getFields($table) : array();
+9
View File
@@ -0,0 +1,9 @@
#sidebar .module-tree, #mainContent .module-content {overflow-y: auto;}
#mainContent .module-col {padding: 0;}
#mainContent .module-content {padding: 10px; padding-right: 0; margin-right: 0;}
/* module-tree. */
#moduleTree.tree ul {margin-bottom: 0;}
#moduleTree .active {background-color: #fff;}
#menuTree > li.has-list > ul > li {padding-left: 10px;}
#menuTree > li.has-list > ul > li.has-list {padding-left: 15px;}
+1
View File
@@ -1,2 +1,3 @@
#sidebar .modulegroup {font-weight:bold; padding-top: 8px; border-top: 1px solid #ddd;}
#sidebar .active {background-color: #e9f2fb; color: #006af1;}
#sidebar .cell a {white-space: nowrap;}
+9
View File
@@ -0,0 +1,9 @@
#sidebar .module-tree, #mainContent .module-content {overflow-y: auto;}
#mainContent .module-col {padding: 0;}
#mainContent .module-content {padding: 10px; padding-right: 0; margin-right: 0;}
/* module-tree. */
#tableTree.tree ul {margin-bottom: 0;}
#tableTree .active {background-color: #fff;}
#tableTree > li.has-list > ul > li {padding-left: 10px;}
#tableTree > li.has-list > ul > li.has-list {padding-left: 15px;}
+2 -2
View File
@@ -26,8 +26,8 @@
.form-item-content {padding-left: 44px;}
.form-item-content > .form-item {gap: 64px; height: 56px; align-items: center; position: relative; width: 500px;}
.form-item-content > .form-item.w-expand {width: 700px;}
.form-item-content > .form-item > .label {flex: 0 0 160px; padding-left: 40px; background: #F8F8F8; display: flex; align-items: center; color: currentColor;}
.form-item-content > .form-item > .input-group {margin-left: 20px; width:200px; height:32px;}
.form-item-content > .form-item > .label {flex: 0 0 160px; padding-left: 40px; background: #F8F8F8; display: flex; align-items: center; color: currentColor; font-size: 13px;}
.form-item-content > .form-item > .input-group {margin-left: 20px; width:180px; height:32px;}
.form-item-content > .form-item > .input-group > .input-group-addon {flex: 1 1 30%;}
.form-item-content > .form-item > .input-control > input {margin-left: 40px;}
.form-item-content > .form-item.active .icon {display: unset;}
+45
View File
@@ -0,0 +1,45 @@
$(function()
{
initModuleTree();
setHeight();
$(window).resize(setHeight);
});
/**
* Set pane height.
*
* @access public
* @return void
*/
function setHeight()
{
var paneHeight = $(window).height() - 90;
$('#sidebar .module-tree,#mainContent .module-content').css('height', paneHeight);
}
/**
* Init module tree by zui.
*
* @access public
* @return void
*/
function initModuleTree()
{
$('#moduleTree').tree(
{
data: moduleTree,
initialState: 'active',
itemCreator: function($li, item)
{
$li.append('<a data-module="' + item.key + '" data-has-children="' + (item.children ? !!item.children.length : false) + '" href=# title="' + item.title + '">' + item.title + '</a>');
if (item.active) $li.addClass('active open in');
}
});
$('#moduleTree').on('click', 'a', function(e)
{
var target = $(e.target);
if (target.attr('data-has-children') === 'true') return;
self.location.href = createLink('dev', 'api', 'module=' + target.attr('data-module'));
})
}
+45
View File
@@ -0,0 +1,45 @@
$(function()
{
initTableTree();
setHeight();
$(window).resize(setHeight);
});
/**
* Set pane height.
*
* @access public
* @return void
*/
function setHeight()
{
var paneHeight = $(window).height() - 90;
$('#sidebar .module-tree,#mainContent .module-content').css('height', paneHeight);
}
/**
* Init table tree by zui.
*
* @access public
* @return void
*/
function initTableTree()
{
$('#tableTree').tree(
{
data: tableTree,
initialState: 'active',
itemCreator: function($li, item)
{
$li.append('<a data-module="' + item.key + '" data-has-children="' + (item.children ? !!item.children.length : false) + '" href=# title="' + item.title + '">' + item.title + '</a>');
if (item.active) $li.addClass('active open in');
}
});
$('#tableTree').on('click', 'a', function(e)
{
var target = $(e.target);
if (target.attr('data-has-children') === 'true') return;
self.location.href = createLink('dev', 'db', 'module=' + target.attr('data-module'));
})
}
+12 -1
View File
@@ -38,6 +38,9 @@ $lang->dev->fields['type'] = 'Typ';
$lang->dev->fields['length'] = 'Länge';
$lang->dev->fields['null'] = 'Null';
$lang->dev->switchList['1'] = 'On';
$lang->dev->switchList['0'] = 'Off';
$lang->dev->tableList = array();
$lang->dev->tableList['action'] = 'Aktion';
$lang->dev->tableList['bug'] = 'Bug';
@@ -166,6 +169,14 @@ $lang->dev->tableList['client'] = 'Client Version Update';
$lang->dev->tableList['conference'] = 'Conference';
$lang->dev->tableList['integration'] = 'Integration';
$lang->dev->tableList['license'] = 'License';
$lang->dev->tableList['zanode'] = 'ZAnode';
$lang->dev->tableList['dashboard'] = 'Dashboard';
$lang->dev->tableList['screen'] = 'Screen';
$lang->dev->tableList['zahost'] = 'ZAhost';
$lang->dev->tableList['approval'] = 'Approval';
$lang->dev->tableList['approvalflow'] = 'Approval Flow';
$lang->dev->tableList['chart'] = 'Chart';
$lang->dev->tableList['dataset'] = 'Dataset';
$lang->dev->groupList['my'] = 'Dashboard';
$lang->dev->groupList['program'] = 'Program';
@@ -202,4 +213,4 @@ $lang->dev->projectMenu['waterfall'] = "Waterfall / Waterfall + {$lang->proj
$lang->dev->projectMenu['kanbanProject'] = "Kanban {$lang->projectCommon}";
if($config->vision == 'lite') $lang->dev->projectMenu['kanbanProject'] = $lang->projectCommon;
$this->lang->dev->replaceLable['project-execution'] = "{$lang->executionCommon} / Stage";
if($config->vision == 'rnd') $this->lang->dev->replaceLable['project-execution'] = "{$lang->executionCommon} / Stage";
+12 -1
View File
@@ -38,6 +38,9 @@ $lang->dev->fields['type'] = 'Type';
$lang->dev->fields['length'] = 'Length';
$lang->dev->fields['null'] = 'Null';
$lang->dev->switchList['1'] = 'On';
$lang->dev->switchList['0'] = 'Off';
$lang->dev->tableList = array();
$lang->dev->tableList['action'] = 'Action';
$lang->dev->tableList['bug'] = 'Bug';
@@ -166,6 +169,14 @@ $lang->dev->tableList['client'] = 'Client Version Update';
$lang->dev->tableList['conference'] = 'Conference';
$lang->dev->tableList['integration'] = 'Integration';
$lang->dev->tableList['license'] = 'License';
$lang->dev->tableList['zanode'] = 'ZAnode';
$lang->dev->tableList['dashboard'] = 'Dashboard';
$lang->dev->tableList['screen'] = 'Screen';
$lang->dev->tableList['zahost'] = 'ZAhost';
$lang->dev->tableList['approval'] = 'Approval';
$lang->dev->tableList['approvalflow'] = 'Approval Flow';
$lang->dev->tableList['chart'] = 'Chart';
$lang->dev->tableList['dataset'] = 'Dataset';
$lang->dev->groupList['my'] = 'Dashboard';
$lang->dev->groupList['program'] = 'Program';
@@ -202,4 +213,4 @@ $lang->dev->projectMenu['waterfall'] = "Waterfall / Waterfall + {$lang->proj
$lang->dev->projectMenu['kanbanProject'] = "Kanban {$lang->projectCommon}";
if($config->vision == 'lite') $lang->dev->projectMenu['kanbanProject'] = $lang->projectCommon;
$this->lang->dev->replaceLable['project-execution'] = "{$lang->executionCommon} / Stage";
if($config->vision == 'rnd') $this->lang->dev->replaceLable['project-execution'] = "{$lang->executionCommon} / Stage";
+12 -1
View File
@@ -38,6 +38,9 @@ $lang->dev->fields['type'] = 'Type';
$lang->dev->fields['length'] = 'Length';
$lang->dev->fields['null'] = 'Null';
$lang->dev->switchList['1'] = 'On';
$lang->dev->switchList['0'] = 'Off';
$lang->dev->tableList = array();
$lang->dev->tableList['action'] = 'Action';
$lang->dev->tableList['bug'] = 'Bug';
@@ -166,6 +169,14 @@ $lang->dev->tableList['client'] = 'Client Version Update';
$lang->dev->tableList['conference'] = 'Conference';
$lang->dev->tableList['integration'] = 'Integration';
$lang->dev->tableList['license'] = 'License';
$lang->dev->tableList['zanode'] = 'ZAnode';
$lang->dev->tableList['dashboard'] = 'Dashboard';
$lang->dev->tableList['screen'] = 'Screen';
$lang->dev->tableList['zahost'] = 'ZAhost';
$lang->dev->tableList['approval'] = 'Approval';
$lang->dev->tableList['approvalflow'] = 'Approval Flow';
$lang->dev->tableList['chart'] = 'Chart';
$lang->dev->tableList['dataset'] = 'Dataset';
$lang->dev->groupList['my'] = 'Dashboard';
$lang->dev->groupList['program'] = 'Program';
@@ -202,4 +213,4 @@ $lang->dev->projectMenu['waterfall'] = "Waterfall / Waterfall + {$lang->proj
$lang->dev->projectMenu['kanbanProject'] = "Kanban {$lang->projectCommon}";
if($config->vision == 'lite') $lang->dev->projectMenu['kanbanProject'] = $lang->projectCommon;
$this->lang->dev->replaceLable['project-execution'] = "{$lang->executionCommon} / Stage";
if($config->vision == 'rnd') $this->lang->dev->replaceLable['project-execution'] = "{$lang->executionCommon} / Stage";
+9 -1
View File
@@ -169,6 +169,14 @@ $lang->dev->tableList['client'] = '客户端版本更新';
$lang->dev->tableList['conference'] = '音视频';
$lang->dev->tableList['integration'] = '集成';
$lang->dev->tableList['license'] = '授权';
$lang->dev->tableList['zanode'] = '执行节点';
$lang->dev->tableList['dashboard'] = '仪表盘';
$lang->dev->tableList['screen'] = '大屏';
$lang->dev->tableList['zahost'] = '宿主机';
$lang->dev->tableList['approval'] = '审批';
$lang->dev->tableList['approvalflow'] = '审批流';
$lang->dev->tableList['chart'] = '图表';
$lang->dev->tableList['dataset'] = '数据集';
$lang->dev->groupList['my'] = '我的地盘';
$lang->dev->groupList['program'] = '项目集';
@@ -205,4 +213,4 @@ $lang->dev->projectMenu['waterfall'] = "瀑布 / 融合瀑布{$lang->project
$lang->dev->projectMenu['kanbanProject'] = "看板{$lang->projectCommon}";
if($config->vision == 'lite') $lang->dev->projectMenu['kanbanProject'] = $lang->projectCommon;
$this->lang->dev->replaceLable['project-execution'] = "{$lang->executionCommon} / 阶段";
if($config->vision == 'rnd') $this->lang->dev->replaceLable['project-execution'] = "{$lang->executionCommon} / 阶段";
+52 -2
View File
@@ -536,13 +536,13 @@ class devModel extends model
break;
}
foreach($customeds as $type => $customed)
foreach($customeds as $customType => $customed)
{
if(is_array($customed))
{
foreach($customed as $row)
{
$langKey = $type == 'featureBar' ? "featureBar-{$method}_" : $row->section . '_';
$langKey = $customType == 'featureBar' ? "featureBar-{$method}_" : $row->section . '_';
$rowKey = $row->key;
$customedLangs[$langKey . $rowKey] = $row->value;
}
@@ -820,6 +820,16 @@ class devModel extends model
if(!in_array($type, $this->config->dev->navTypes)) return $menuTree;
$mainNav = $type == 'second' ? $this->lang->mainNav : array();
if($this->config->vision != 'open' and $type == 'second')
{
$flowNav = $this->dao->select('module')->from(TABLE_WORKFLOW)
->where('buildin')->eq(0)
->andWhere('vision')->eq($this->config->vision)
->andWhere('navigator')->in('primary,secondary')
->fetchPairs();
foreach($flowNav as $nav) unset($mainNav->$nav);
}
if($type != 'second')
{
/* Set main nav list. */
@@ -1062,4 +1072,44 @@ class devModel extends model
$menu->children = array();
return $menu;
}
/**
* Get tree by type.
*
* @param string $currentObject
* @param string $type module|table
* @access public
* @return array
*/
public function getTree($currentObject, $type)
{
$tree = array();
if(!in_array($type, array('module', 'table'))) return $tree;
$objects = $type == 'module' ? $this->getModules() : $this->getTables();
$groupList = array_merge($this->lang->dev->groupList, $this->lang->dev->endGroupList);
foreach($groupList as $moduleKey => $moduleName)
{
if(empty($objects[$moduleKey])) continue;
$module = new stdclass();
$module->key = $moduleKey;
$module->title = $moduleName;
$module->active = 0;
$module->children = array();
foreach($objects[$moduleKey] as $objectKey => $objectName)
{
$defaultValue = $type == 'module' ? $objectName : '';
$object = new stdclass();
$object->key = $objectName;
$object->title = zget($this->lang->dev->tableList, $objectKey, $defaultValue);
$object->active = $objectName == $currentObject ? 1 : 0;
if($object->active) $module->active = 1;
$module->children[] = $object;
}
$tree[] = $module;
}
return $tree;
}
}
+73 -93
View File
@@ -1,110 +1,90 @@
<?php include 'header.html.php';?>
<?php js::set('moduleTree', $moduleTree);?>
<div id='mainContent' class='main-row'>
<div class='side-col' id='sidebar'>
<div class='cell'>
<div class='cell module-tree'>
<div class="panel panel-sm with-list">
<div class='panel-heading'><i class='icon-list'></i> <strong><?php echo $lang->dev->moduleList?></strong></div>
<?php foreach($lang->dev->groupList as $group => $groupName):?>
<?php if(!empty($modules[$group])):?>
<div class='modulegroup'><?php echo $groupName?></div>
<?php foreach($modules[$group] as $module):?>
<?php
$active = ($module == $selectedModule) ? 'text-primary' : '';
$moduleName = zget($lang->dev->tableList, $module, $module);
?>
<?php echo html::a(inlink('api', "module=$module"), $moduleName, '', "class='$active'");?>
<?php endforeach;?>
<?php endif;?>
<?php endforeach;?>
<?php foreach($lang->dev->endGroupList as $group => $groupName):?>
<?php if(!empty($modules[$group])):?>
<div class='modulegroup'><?php echo $groupName?></div>
<?php foreach($modules[$group] as $module):?>
<?php
$active = ($module == $selectedModule) ? 'text-primary' : '';
$moduleName = zget($lang->dev->tableList, $module, $module);
?>
<?php echo html::a(inlink('api', "module=$module"), $moduleName, '', "class='$active'");?>
<?php endforeach;?>
<?php endif;?>
<?php endforeach;?>
<div id="moduleTree" class="menu-active-primary menu-hover-primary"></div>
</div>
</div>
</div>
<div class='main-col main-content'>
<div class='main-col main-content module-col'>
<?php if($selectedModule):?>
<?php foreach($apis as $api):?>
<div class='detail'>
<?php
$methodName = zget($api, 'name', '');
$params = array();
if(isset($api['param']))
{
foreach($api['param'] as $param) $params[] = "{$param['var']}=[{$param['var']}]";
}
$params = implode('&', $params);
?>
<div class='detail-title'>
<div class='module-content'>
<?php foreach($apis as $api):?>
<div class='detail'>
<?php
echo !empty($api['post']) ? 'GET/POST' : 'GET';
echo '&nbsp;&nbsp;' . $this->createLink($selectedModule, $methodName, $params, 'json');
$methodName = zget($api, 'name', '');
$params = array();
if(isset($api['param']))
{
foreach($api['param'] as $param) $params[] = "{$param['var']}=[{$param['var']}]";
}
$params = implode('&', $params);
?>
</div>
<div class='detail-content'>
<?php echo zget($api, 'desc', '');?>
<table class='table table-bordered'>
<tr>
<th><?php echo $lang->dev->params?></th>
<th><?php echo $lang->dev->type?></th>
<th><?php echo $lang->dev->desc?></th>
</tr>
<?php if(isset($api['param'])):?>
<?php foreach($api['param'] as $param):?>
<tr>
<td><?php echo $param['var']?></td>
<td><?php echo $param['type']?></td>
<td><?php echo $param['desc']?></td>
</tr>
<?php endforeach;?>
<?php else:?>
<tr><td colspan="3"><?php echo $lang->dev->noParams?></td></tr>
<div class='detail-title'>
<?php
echo !empty($api['post']) ? 'GET/POST' : 'GET';
echo '&nbsp;&nbsp;' . $this->createLink($selectedModule, $methodName, $params, 'json');
?>
</div>
<div class='detail-content'>
<?php echo zget($api, 'desc', '');?>
<table class='table table-bordered'>
<tr>
<th><?php echo $lang->dev->params?></th>
<th><?php echo $lang->dev->type?></th>
<th><?php echo $lang->dev->desc?></th>
</tr>
<?php if(isset($api['param'])):?>
<?php foreach($api['param'] as $param):?>
<tr>
<td><?php echo $param['var']?></td>
<td><?php echo $param['type']?></td>
<td><?php echo $param['desc']?></td>
</tr>
<?php endforeach;?>
<?php else:?>
<tr><td colspan="3"><?php echo $lang->dev->noParams?></td></tr>
<?php endif;?>
</table>
<?php if(isset($config->dev->postParams[$selectedModule][$methodName])):?>
<?php
$this->app->loadLang($selectedModule);
$this->app->loadConfig($selectedModule);
?>
<table class='table table-bordered'>
<caption><?php echo $lang->dev->post;?></caption>
<tr>
<th><?php echo $lang->dev->params?></th>
<th><?php echo $lang->dev->type?></th>
<th><?php echo $lang->dev->desc?></th>
</tr>
<?php foreach($config->dev->postParams[$selectedModule][$methodName] as $paramName => $paramType):?>
<tr>
<td><?php echo $paramName?></td>
<td><?php echo $paramType?></td>
<?php
$paramDesc = '';
$listKey = $paramName . 'List';
if(isset($lang->$selectedModule->$paramName)) $paramDesc .= $lang->$selectedModule->$paramName . ' ';
if(isset($lang->$selectedModule->$listKey)) $paramDesc .= sprintf($lang->dev->paramRange, join(' | ', array_keys($lang->$selectedModule->$listKey)));
if($paramType == 'date') $paramDesc .= $lang->dev->paramDate;
if($paramName == 'color') $paramDesc .= $lang->dev->paramColor;
if(isset($config->$selectedModule->$methodName->requiredFields) and strpos($config->$selectedModule->$methodName->requiredFields, $paramName) !== false) $paramDesc .= "<span class='red'>*{$lang->required}</span>";
if($paramName == 'product') $paramDesc .= "<span class='red'>*{$lang->required}</span>";
if($paramName == 'mailto') $paramDesc .= $lang->dev->paramMailto;
?>
<td><?php echo $paramDesc?></td>
</tr>
<?php endforeach;?>
</table>
<?php endif;?>
</table>
<?php if(isset($config->dev->postParams[$selectedModule][$methodName])):?>
<?php
$this->app->loadLang($selectedModule);
$this->app->loadConfig($selectedModule);
?>
<table class='table table-bordered'>
<caption><?php echo $lang->dev->post;?></caption>
<tr>
<th><?php echo $lang->dev->params?></th>
<th><?php echo $lang->dev->type?></th>
<th><?php echo $lang->dev->desc?></th>
</tr>
<?php foreach($config->dev->postParams[$selectedModule][$methodName] as $paramName => $paramType):?>
<tr>
<td><?php echo $paramName?></td>
<td><?php echo $paramType?></td>
<?php
$paramDesc = '';
$listKey = $paramName . 'List';
if(isset($lang->$selectedModule->$paramName)) $paramDesc .= $lang->$selectedModule->$paramName . ' ';
if(isset($lang->$selectedModule->$listKey)) $paramDesc .= sprintf($lang->dev->paramRange, join(' | ', array_keys($lang->$selectedModule->$listKey)));
if($paramType == 'date') $paramDesc .= $lang->dev->paramDate;
if($paramName == 'color') $paramDesc .= $lang->dev->paramColor;
if(isset($config->$selectedModule->$methodName->requiredFields) and strpos($config->$selectedModule->$methodName->requiredFields, $paramName) !== false) $paramDesc .= "<span class='red'>*{$lang->required}</span>";
if($paramName == 'product') $paramDesc .= "<span class='red'>*{$lang->required}</span>";
if($paramName == 'mailto') $paramDesc .= $lang->dev->paramMailto;
?>
<td><?php echo $paramDesc?></td>
</tr>
<?php endforeach;?>
</table>
<?php endif;?>
</div>
</div>
<?php endforeach;?>
</div>
<?php endforeach;?>
<?php endif;?>
</div>
</div>
+5 -27
View File
@@ -1,39 +1,17 @@
<?php include 'header.html.php';?>
<?php js::set('tableTree', $tableTree);?>
<div id='mainContent' class='main-row'>
<div class='side-col' id='sidebar'>
<div class='cell'>
<div class='cell module-tree'>
<div class="panel panel-sm with-list">
<div class='panel-heading'><i class='icon-list'></i> <strong><?php echo $lang->dev->dbList?></strong></div>
<?php foreach($lang->dev->groupList as $group => $groupName):?>
<?php if(isset($tables[$group])):?>
<div class='modulegroup'><?php echo $groupName?></div>
<?php foreach($tables[$group] as $subTable => $table):?>
<?php
$active = ($table == $selectedTable) ? 'text-primary' : '';
$tableName = zget($lang->dev->tableList, $subTable, '');
?>
<?php if(!empty($tableName)) echo html::a(inlink('db', "table=$table"), $tableName, '', "class='$active'");?>
<?php endforeach;?>
<?php endif;?>
<?php endforeach;?>
<?php foreach($lang->dev->endGroupList as $group => $groupName):?>
<?php if(isset($tables[$group])):?>
<div class='modulegroup'><?php echo $groupName?></div>
<?php foreach($tables[$group] as $subTable => $table):?>
<?php
$active = ($table == $selectedTable) ? 'text-primary' : '';
$tableName = zget($lang->dev->tableList, $subTable, '');
?>
<?php if(!empty($tableName)) echo html::a(inlink('db', "table=$table"), $tableName, '', "class='$active'");?>
<?php endforeach;?>
<?php endif;?>
<?php endforeach;?>
<div id="tableTree" class="menu-active-primary menu-hover-primary"></div>
</div>
</div>
</div>
<div class='main-col main-content'>
<div class='main-col main-content module-col'>
<?php if($selectedTable):?>
<div class='detail'>
<div class='detail module-content'>
<div class='detail-title'><?php echo $selectedTable?></div>
<div class='detail-content'>
<table class="table table-bordered">
+1 -1
View File
@@ -36,8 +36,8 @@ class editor extends control
$this->app->loadLang('dev');
$this->view->title = $this->lang->editor->common;
$this->view->position[] = $this->lang->editor->common;
$this->view->modules = $this->loadModel('dev')->getModules();
$this->view->tab = $type;
$this->view->moduleTree = $this->loadModel('dev')->getTree($type, 'module');
$this->display();
}
+6 -4
View File
@@ -1,5 +1,7 @@
body{padding-bottom:0px;background-color:#fff;}
.m-editor-edit {padding-bottom: 0px; background-color: #fff;}
#showContentEditor, #fileContentEditor {border:1px solid #ddd;}
.main-content {padding:0px;}
.checkbox-primary {display:inline-block; padding-left:12px;}
.checkbox-primary label {padding-left:12px;}
.m-editor-edit .main-content {padding:0px;}
.m-editor-edit .checkbox-primary {display:inline-block; padding-left:12px;}
.m-editor-edit .checkbox-primary label {padding-left:12px;}
.m-editor-edit .main-header {padding: 10px 20px;}
.main-content textarea.form-control {min-height: 300px; height: auto;}
+13 -5
View File
@@ -1,6 +1,14 @@
body{padding-bottom:0px;background-color:#fff;}
.expandable > ul {display: none!important}
.collapsable > ul {display: block!important}
::-webkit-scrollbar {width: 10px; height: 10px;}
::-webkit-scrollbar-button {width: 0; height: 0;}
::-webkit-scrollbar-thumb:vertical {min-height: 28px; background-color: rgba(0, 0, 0, 0.2); background-clip: padding-box; border-radius: 2px; -webkit-box-shadow: inset 1px 1px 0 rgb(0 0 0 / 10%), inset 0 -1px 0 rgb(0 0 0 / 7%);}
::-webkit-scrollbar-track:hover {background-color:rgba(0,0,0,.05);-webkit-box-shadow:inset 1px 0 0 rgba(0,0,0,.1);}
::-webkit-scrollbar-thumb:hover{background-color:rgba(0,0,0,.4);}
.expandable > ul {display: none !important}
.m-editor-extend {padding-bottom: 0px; background-color: #fff;}
.collapsable > ul {display: block !important}
.tree li:before {margin-right: 4px;}
.tree li>a{display:inline;}
.main-content{padding: 0px; padding-top: 20px;}
.tree li > a {display: inline;}
.m-editor-extend .main-header {padding: 10px 20px; }
.m-editor-extend .main-content {padding: 0px; padding-top: 10px; box-shadow: none;}
#extendTree li a {white-space: nowrap;}
+14 -2
View File
@@ -3,5 +3,17 @@ table tr > td:first-child {padding-left: 0;}
table tr > td:last-child {padding-right: 0;}
.modulegroup {font-weight:bold; padding-top:8px; border-top:1px solid #ddd;}
td.w-200px a:hover {font-weight:bold;}
.w-350px{width:350px;}
.module-col{padding-bottom:30px;}
.w-350px {width:350px;}
.with-list a {white-space: nowrap;}
#mainContent .module-col{padding: 0px; padding-left: 10px;}
#mainContent .module-content {padding: 0;}
#sidebar .module-tree {overflow-y: auto;}
#sidebar .module-tree .panel-heading {padding: 4px 10px; position: relative;}
#sidebar .module-tree .panel-heading:after {content: ''; position: absolute; inset: 0 -10px; border-bottom: 1px solid #eee;}
/* module-tree. */
#moduleTree {padding-top: 10px;}
#moduleTree.tree ul {margin-bottom: 0;}
#moduleTree .active {background-color: #fff;}
#menuTree > li.has-list > ul > li {padding-left: 10px;}
#menuTree > li.has-list > ul > li.has-list {padding-left: 15px;}
+9
View File
@@ -0,0 +1,9 @@
::-webkit-scrollbar {width: 10px; height: 10px;}
::-webkit-scrollbar-button {width: 0; height: 0;}
::-webkit-scrollbar-thumb:vertical {min-height: 28px; background-color: rgba(0, 0, 0, 0.2); background-clip: padding-box; border-radius: 2px; -webkit-box-shadow: inset 1px 1px 0 rgb(0 0 0 / 10%), inset 0 -1px 0 rgb(0 0 0 / 7%);}
::-webkit-scrollbar-track:hover {background-color:rgba(0,0,0,.05);-webkit-box-shadow:inset 1px 0 0 rgba(0,0,0,.1);}
::-webkit-scrollbar-thumb:hover{background-color:rgba(0,0,0,.4);}
.m-editor-newpage {padding-bottom:0px; background-color:#fff;}
.m-editor-newpage .main-header {padding: 10px 20px;}
.m-editor-newpage .main-content {box-shadow: none;}
-1
View File
@@ -1 +0,0 @@
$(function(){ })
+47 -9
View File
@@ -1,12 +1,50 @@
$(function()
{
var showHeight = $('#main').height() - $('#mainMenu').height() - 40;
$('#editWin').height(showHeight);
$('#extendWin').height(showHeight);
$('.side-col a').click(function()
{
$('.side-col a.active').removeClass('active');
$(this).addClass('active');
});
initModuleTree();
setHeight();
$(window).resize(setHeight);
});
/**
* Set pane height.
*
* @access public
* @return void
*/
function setHeight()
{
var paneHeight = $(window).height() - 120;
$('#sidebar .module-tree,#mainContent .module-col,#extendWin').css('height', paneHeight);
$(' #mainContent .module-content, #editWin').css('height', paneHeight - 6);
}
/**
* Init module tree by zui.
*
* @access public
* @return void
*/
function initModuleTree()
{
$('#moduleTree').tree(
{
data: moduleTree,
initialState: 'active',
itemCreator: function($li, item)
{
$li.append('<a data-module="' + item.key + '" data-has-children="' + (item.children ? !!item.children.length : false) + '" href=# title="' + item.title + '">' + item.title + '</a>');
if (item.active) $li.addClass('active open in');
}
});
$('#moduleTree').on('click', 'a', function(e)
{
var target = $(e.target);
if (target.attr('data-has-children') === 'true') return;
$('#extendWin').attr('src', createLink('editor', 'extend', 'moduleDir=' + target.attr('data-module')));
$(this).closest('.side-col').find('li.active').removeClass('active');
$(this).parent().addClass('active');
$(this).parent().parent().parent().addClass('active');
})
}
+26 -6
View File
@@ -13,6 +13,13 @@
<?php if(empty($filePath)) die();?>
<?php include $app->getModuleRoot() . 'common/view/header.lite.html.php';?>
<?php
$browser = helper::getBrowser();
if($browser['name'] == 'ie')
{
include 'ieedit.html.php';
die();
}
js::set('jsRoot', $jsRoot);
js::set('clientLang', $app->clientLang);
js::import($jsRoot . 'monaco-editor/min/vs/loader.js');
@@ -74,7 +81,7 @@ js::import($jsRoot . 'monaco-editor/min/vs/loader.js');
</td>
</tr>
<?php endif;?>
<tr>
<tr class='footer'>
<td class='text-center'>
<?php echo html::submitButton()?>
<?php if($action and $action != 'edit' and $action != 'newPage'):?>
@@ -111,7 +118,12 @@ $(function()
autoIndent: true,
contextmenu: true,
automaticLayout: true,
minimap: {enabled: false}
minimap: {enabled: false},
scrollBeyondLastLine: false,
scrollbar: {
verticalScrollbarSize: 10,
horizontalScrollbarSize: 10
}
});
<?php endif;?>
fileContentEditor = monaco.editor.create(document.getElementById('fileContentEditor'),
@@ -122,10 +134,18 @@ $(function()
autoIndent: true,
contextmenu: true,
automaticLayout: true,
minimap: {enabled: false}
minimap: {enabled: false},
scrollBeyondLastLine: false,
scrollbar: {
verticalScrollbarSize: 10,
horizontalScrollbarSize: 10
}
});
var codeHeight = top.window.innerHeight - 280;
if($('#fileNameBox').length == 0) codeHeight += 56;
var codeHeight = parent.$('#editWin').height();
var headerHeight = $('.main-header').outerHeight();
var footerHeight = $('.footer').height();
var nameBoxHeight = $('#fileNameBox').height() ? $('#fileNameBox').height() : 0;
codeHeight -= headerHeight + footerHeight + nameBoxHeight;
<?php if(!empty($showContent)):?>
contentHeight = showContentEditor.getContentHeight();
if(contentHeight > 300) contentHeight = 300;
@@ -134,7 +154,7 @@ $(function()
codeHeight -= contentHeight + 30;
if(codeHeight < 300) codeHeight = 300;
<?php endif;?>
$('#fileContentEditor').height(codeHeight);
$('#fileContentEditor').height(codeHeight - 30);
});
$('#submit').click(function()
{
+14 -1
View File
@@ -17,7 +17,7 @@
<strong><?php echo zget($lang->editor->modules, $module, isset($lang->{$module}->common) ? $lang->{$module}->common : $module);?></strong>
</div>
</div>
<div class='main-content'>
<div class='main-content extend-content'>
<?php echo $tree?>
</div>
<script>
@@ -38,6 +38,19 @@ $(function()
$this.addClass('expandable-hitarea').removeClass('collapsable-hitarea');
}
});
$('.has-list a').on('click', function()
{
$('.has-list a.text-primary').removeClass('text-primary active');
$(this).addClass('text-primary active');
}).on('mouseover', function()
{
$('.has-list a:not(.active)').removeClass('text-primary');
$(this).addClass('text-primary');
}).on('mouseout', function()
{
if(!$(this).hasClass('active')) $(this).removeClass('text-primary');
});
});
</script>
<iframe frameborder='0' name='hiddenwin' id='hiddenwin' scrolling='no' class='hidden'></iframe>
+79
View File
@@ -0,0 +1,79 @@
<?php
/**
* The editor view file of dir module of ZenTaoPMS.
*
* @copyright Copyright 2009-2015 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL (http://zpl.pub/page/zplv12.html)
* @author Yidong Wang <yidong@cnezsoft.com>
* @package editor
* @version $Id$
* @link http://www.zentao.net
*/
?>
<?php include $app->getModuleRoot() . 'common/view/header.lite.html.php';?>
<div class='main-header'>
<div class='heading'>
<i class='icon-edit'></i>
<?php if($filePath):?>
<strong><?php echo $lang->editor->filePath;?></strong>
<code><?php echo $filePath?></code>
<?php endif?>
</div>
</div>
<form method='post' target='hiddenwin' action='<?php echo inlink('save', "filePath=$safeFilePath&action=$action")?>'>
<div class='main-content'>
<table class='table table-form'>
<?php if(!empty($showContent)):?>
<tr>
<td>
<?php echo "<span class='strong'>" . $lang->editor->sourceFile . '</span>'?><br />
<textarea id='showContent' class="form-control"><?php echo $showContent?></textarea>
</td>
</tr>
<?php endif?>
<tr>
<td><?php echo html::textarea('fileContent', str_replace('&', '&amp;', $fileContent), "class='form-control'")?></td>
</tr>
<tr>
<td>
<?php if($action and $action != 'edit' and $action != 'newPage' and $action != 'override' and $action != 'extendControl'):?>
<div class='form-group'>
<div class='input-group'>
<span class='input-group-addon'><?php echo $lang->editor->fileName;?></span>
<?php echo html::input('fileName', '', "class='form-control'");?>
<span class='input-group-addon'>
<?php
if($action == 'newHook')
{
echo $lang->editor->exampleHook;
}
elseif($action and $action == 'extendOther' and strpos(basename($filePath), '.js') !== false or $action == 'newJS')
{
echo $lang->editor->exampleJs;
}
elseif($action and $action == 'extendOther' and strpos(basename($filePath), '.css') !== false or $action == 'newCSS')
{
echo $lang->editor->exampleCss;
}
else
{
echo $lang->editor->examplePHP;
}
?>
</span>
</div>
</div>
<?php endif;?>
<?php if($action and $action != 'edit' and $action != 'newPage'):?>
<div class='checkbox-primary'>
<input type='checkbox' name='override' id='override' />
<label for='override'><?php echo $lang->editor->isOverride?></span>
</div>
<?php endif;?>
</td>
</tr>
<tr><td align='center'><?php echo html::submitButton()?></td></tr>
</table>
</div>
</form>
<?php include $app->getModuleRoot() . 'common/view/footer.lite.html.php';?>
+4 -31
View File
@@ -11,6 +11,7 @@
*/
?>
<?php include $app->getModuleRoot() . 'dev/view/header.html.php';?>
<?php js::set('moduleTree', $moduleTree);?>
<?php if(common::hasPriv('editor', 'turnon')):?>
<div id='mainMenu' class='clearfix menu-secondary'>
<div class="pull-left">
@@ -23,38 +24,10 @@
<?php endif;?>
<div id='mainContent' class='main-row'>
<div class='side-col' id='sidebar'>
<div class='cell'>
<div class='cell module-tree'>
<div class='panel panel-sm with-list'>
<div class='panel-heading'><i class='icon-list'></i> <strong><?php echo $lang->editor->moduleList?></strong></div>
<?php foreach($lang->dev->groupList as $group => $groupName):?>
<?php if(!empty($modules[$group])):?>
<div class='modulegroup'><?php echo $groupName?></div>
<?php foreach($modules[$group] as $module):?>
<?php $moduleName = zget($lang->dev->tableList, $module, $module);?>
<?php echo html::a(inlink('extend', "moduleDir=$module"), $moduleName, 'extendWin');?>
<?php endforeach;?>
<?php endif;?>
<?php endforeach;?>
<?php foreach($lang->dev->endGroupList as $group => $groupName):?>
<?php if(!empty($modules[$group])):?>
<div class='modulegroup'><?php echo $groupName?></div>
<?php foreach($modules[$group] as $module):?>
<?php
$moduleName = $module;
if(isset($lang->dev->tableList[$module]))
{
$moduleName = $lang->dev->tableList[$module];
}
else
{
if(!isset($lang->{$module}->common)) $app->loadLang($module);
$moduleName = isset($lang->{$module}->common) ? $lang->{$module}->common : $module;
}
?>
<?php echo html::a(inlink('extend', "moduleDir=$module"), $moduleName, 'extendWin');?>
<?php endforeach;?>
<?php endif;?>
<?php endforeach;?>
<div id="moduleTree" class="menu-active-primary menu-hover-primary"></div>
</div>
</div>
</div>
@@ -63,7 +36,7 @@
<iframe frameborder='0' name='extendWin' id='extendWin' width='100%'></iframe>
</div>
</div>
<div class='main-col main-content'>
<div class='main-col main-content module-content'>
<iframe frameborder='0' name='editWin' id='editWin' width='100%'></iframe>
</div>
</div>
-1
View File
@@ -11,7 +11,6 @@
*/
?>
<?php include $app->getModuleRoot() . 'common/view/header.lite.html.php';?>
<style>body{padding-bottom:0px;background-color:#fff;}</style>
<div class='main-header'>
<div class='heading'><i class='icon-plus'></i> <strong><?php echo $lang->editor->newPage?></strong></div>
</div>
-1
View File
@@ -227,7 +227,6 @@ $lang->execution->build = 'Builds';
$lang->execution->testtask = 'Testaufgaben';
$lang->execution->burn = 'Burndown';
$lang->execution->computeBurn = 'Aktualisieren';
$lang->execution->CFD = 'Cumulative Flow diagrams';
$lang->execution->computeCFD = 'Compute Cumulative Flow diagrams';
$lang->execution->burnData = 'Burndown Daten';
$lang->execution->fixFirst = 'Bearbeite Mannstunden des ersten Tags';
-1
View File
@@ -227,7 +227,6 @@ $lang->execution->build = 'Build List';
$lang->execution->testtask = 'Request';
$lang->execution->burn = 'Burndown';
$lang->execution->computeBurn = 'Update';
$lang->execution->CFD = 'Cumulative Flow diagrams';
$lang->execution->computeCFD = 'Compute Cumulative Flow diagrams';
$lang->execution->burnData = 'Burndown Data';
$lang->execution->fixFirst = 'Edit 1st-Day Estimates';
-1
View File
@@ -227,7 +227,6 @@ $lang->execution->build = 'Build List';
$lang->execution->testtask = 'Request';
$lang->execution->burn = 'Burndown';
$lang->execution->computeBurn = 'Update';
$lang->execution->CFD = 'Cumulative Flow diagrams';
$lang->execution->computeCFD = 'Compute Cumulative Flow diagrams';
$lang->execution->burnData = 'Burndown Data';
$lang->execution->fixFirst = 'Edit 1st-Day Estimates';
-1
View File
@@ -227,7 +227,6 @@ $lang->execution->build = '所有版本';
$lang->execution->testtask = '测试单';
$lang->execution->burn = '燃尽图';
$lang->execution->computeBurn = '更新燃尽图';
$lang->execution->CFD = '累积流图';
$lang->execution->computeCFD = '更新累积流图';
$lang->execution->burnData = '燃尽图数据';
$lang->execution->fixFirst = '修改首天工时';
+12 -3
View File
@@ -59,7 +59,7 @@ class executionModel extends model
*/
public function getExecutionFeatures($execution)
{
$features = array('story' => true, 'task' => true, 'qa' => true, 'devops' => true, 'burn' => true, 'build' => true, 'other' => true);
$features = array('story' => true, 'task' => true, 'qa' => true, 'devops' => true, 'burn' => true, 'build' => true, 'other' => true, 'plan' => true);
/* Unset story, bug, build and testtask if type is ops. */
if($execution->lifetime == 'ops')
@@ -81,10 +81,16 @@ class executionModel extends model
if(in_array($execution->attribute, array('request', 'review')))
{
$features['story'] = false;
$features['plan'] = false;
}
}
}
if(isset($execution->projectInfo) and in_array($execution->projectInfo->model, array('waterfall', 'kanban', 'waterfallplus')) and empty($execution->projectInfo->hasProduct))
{
$features['plan'] = false;
}
return $features;
}
@@ -2890,8 +2896,11 @@ class executionModel extends model
}
/* Get stories of children task. */
$childrens = $this->dao->select('*')->from(TABLE_TASK)->where('parent')->in($parents)->fetchAll('id');
foreach($childrens as $children) $taskStories[$children->story] = $children->story;
if(!empty($parents))
{
$childrens = $this->dao->select('*')->from(TABLE_TASK)->where('parent')->in($parents)->fetchAll('id');
foreach($childrens as $children) $taskStories[$children->story] = $children->story;
}
/* Remove empty story. */
unset($taskStories[0]);
+3 -3
View File
@@ -156,7 +156,7 @@
<div class='table-col'>
<?php $hasBranch = $product->type != 'normal' and isset($branchGroups[$product->id]);?>
<div class='input-group <?php if($hasBranch) echo ' has-branch';?>'>
<span class='input-group-addon'><?php echo $lang->product->common;?></span>
<span class='input-group-addon'><?php echo $lang->productCommon;?></span>
<?php $disabled = ($isStage and !$project->division) ? "disabled='disabled'" : '';?>
<?php echo html::select("products[$i]", $allProducts, $product->id, "class='form-control chosen' $disabled onchange='loadBranches(this)' data-last='" . $product->id . "' data-type='" . $product->type . "'");?>
<?php if($isStage and !$project->division) echo html::hidden("products[$i]", $product->id);?>
@@ -190,7 +190,7 @@
</tr>
<?php $i ++;?>
<?php endforeach;?>
<?php elseif(!empty($project) and empty($project->hasProduct) and strpos($project->model, 'waterfall') === false):?>
<?php elseif(!empty($project) and empty($project->hasProduct) and !in_array($project->model, array('waterfall', 'kanban', 'waterfallplus'))):?>
<tr>
<th><?php echo $lang->execution->linkPlan;?></th>
<td id="plansBox">
@@ -209,7 +209,7 @@
<div class='table-row'>
<div class='table-col'>
<div class='input-group'>
<span class='input-group-addon'><?php echo $lang->product->common;?></span>
<span class='input-group-addon'><?php echo $lang->productCommon;?></span>
<?php echo html::select("products[0]", $allProducts, '', "class='form-control chosen' onchange='loadBranches(this)'");?>
</div>
</div>
+3 -3
View File
@@ -170,7 +170,7 @@
<div class='table-col'>
<?php $hasBranch = $product->type != 'normal' and isset($branchGroups[$product->id]);?>
<div class='input-group <?php if($hasBranch) echo ' has-branch';?>'>
<span class='input-group-addon'><?php echo $lang->product->common;?></span>
<span class='input-group-addon'><?php echo $lang->productCommon;?></span>
<?php $disabled = ($execution->type == 'stage' and !$execution->division) ? "disabled='disabled'" : '';?>
<?php echo html::select("products[$i]", $allProducts, $product->id, "class='form-control chosen' $disabled onchange='loadBranches(this)' data-last='" . $product->id . "' data-type='" . $product->type . "'");?>
<?php if($execution->type == 'stage' and !$execution->division) echo html::hidden("products[$i]", $product->id);?>
@@ -221,7 +221,7 @@
<div class='table-row'>
<div class='table-col'>
<div class='input-group'>
<span class='input-group-addon'><?php echo $lang->product->common;?></span>
<span class='input-group-addon'><?php echo $lang->productCommon;?></span>
<?php echo html::select("products[0]", $allProducts, '', "class='form-control chosen' onchange='loadBranches(this)'");?>
</div>
</div>
@@ -261,7 +261,7 @@
<div class='table-col'>
<?php $hasBranch = $product->type != 'normal' and isset($branchGroups[$product->id]);?>
<div class='input-group <?php if($hasBranch) echo ' has-branch';?>'>
<span class='input-group-addon'><?php echo $lang->product->common;?></span>
<span class='input-group-addon'><?php echo $lang->productCommon;?></span>
<?php $disabled = ($project->model == 'waterfall' or $project->model == 'waterfallplus') ? "disabled='disabled'" : '';?>
<?php echo html::select("products[$i]", $allProducts, $product->id, "class='form-control chosen' $disabled onchange='loadBranches(this)' data-last='" . $product->id . "' data-type='" . $product->type . "'");?>
<?php if($execution->type == 'stage' and !$project->division) echo html::hidden("products[$i]", $product->id);?>
+1 -1
View File
@@ -72,7 +72,7 @@ $canImportTask = common::hasPriv('execution', 'importTask') && $execution->
$canCreateBug = $features['qa'] && $productID && common::hasPriv('bug', 'create');
$canBatchCreateBug = $features['qa'] && $productID && common::hasPriv('bug', 'batchCreate') && $execution->multiple;
$canImportBug = $features['qa'] && $productID && common::hasPriv('execution', 'importBug');
$canImportBug = $features['qa'] && $productID && common::hasPriv('execution', 'importBug') && $execution->multiple;
$hasBugButton = $features['qa'] && ($canCreateBug || $canBatchCreateBug);
$canCreateStory = $features['story'] && $productID && common::hasPriv('story', 'create');
+10 -10
View File
@@ -97,13 +97,13 @@ $dataType = '';
<td style='padding-left:15px;'>
<table class='table-1'>
<tr>
<td><span><input type="checkbox" name="story<?php echo $content->id?>[]" value="developing" <?php echo $content->stage == 'developing' ? "checked" : ''?> id="story3developing"><label for="story3developing"> <?php echo $lang->story->stageList['developing']?></label></span></td>
<td><span><input type="checkbox" name="story<?php echo $content->id?>[]" value="developed" <?php echo $content->stage == 'developed' ? "checked" : ''?> id="story3developed"><label for="story3developed"> <?php echo $lang->story->stageList['developed']?></label></span></td>
<td><span><input type="checkbox" name="story<?php echo $content->id?>[]" value="testing" <?php echo $content->stage == 'testing' ? "checked" : ''?> id="story3testing"><label for="story3testing"> <?php echo $lang->story->stageList['testing']?></label></span><br /></td>
<td><span><input type="checkbox" name="story<?php echo $content->id?>[]" value="developing" <?php echo $content->stage == 'developing' ? "checked" : ''?> id="story<?php echo $content->id;?>developing"><label for="story<?php echo $content->id;?>developing"> <?php echo $lang->story->stageList['developing']?></label></span></td>
<td><span><input type="checkbox" name="story<?php echo $content->id?>[]" value="developed" <?php echo $content->stage == 'developed' ? "checked" : ''?> id="story<?php echo $content->id;?>developed"><label for="story<?php echo $content->id;?>developed"> <?php echo $lang->story->stageList['developed']?></label></span></td>
<td><span><input type="checkbox" name="story<?php echo $content->id?>[]" value="testing" <?php echo $content->stage == 'testing' ? "checked" : ''?> id="story<?php echo $content->id;?>testing"><label for="story<?php echo $content->id;?>testing"> <?php echo $lang->story->stageList['testing']?></label></span><br /></td>
</tr>
<tr>
<td><span><input type="checkbox" name="story<?php echo $content->id?>[]" value="tested" <?php echo $content->stage == 'tested' ? "checked" : ''?> id="story3tested"><label for="story3tested"> <?php echo $lang->story->stageList['tested']?></label></span></td>
<td><span><input type="checkbox" name="story<?php echo $content->id?>[]" value="verified" <?php echo $content->stage == 'verified' ? "checked" : ''?> id="story3verified"><label for="story3verified"> <?php echo $lang->story->stageList['verified']?></label></span></td>
<td><span><input type="checkbox" name="story<?php echo $content->id?>[]" value="tested" <?php echo $content->stage == 'tested' ? "checked" : ''?> id="story<?php echo $content->id;?>tested"><label for="story<?php echo $content->id;?>tested"> <?php echo $lang->story->stageList['tested']?></label></span></td>
<td><span><input type="checkbox" name="story<?php echo $content->id?>[]" value="verified" <?php echo $content->stage == 'verified' ? "checked" : ''?> id="story<?php echo $content->id;?>verified"><label for="story<?php echo $content->id;?>verified"> <?php echo $lang->story->stageList['verified']?></label></span></td>
<td></td>
</tr>
</table>
@@ -171,13 +171,13 @@ $dataType = '';
<td style='padding-left:15px;'>
<table class='table-1'>
<tr>
<td><span><input type="checkbox" name="story<?php echo $i?>[]" value="developing" id="story3developing"><label for="story3developing"> <?php echo $lang->story->stageList['developing']?></label></span></td>
<td><span><input type="checkbox" name="story<?php echo $i?>[]" value="developed" id="story3developed"><label for="story3developed"> <?php echo $lang->story->stageList['developed']?></label></span></td>
<td><span><input type="checkbox" name="story<?php echo $i?>[]" value="testing" id="story3testing"><label for="story3testing"> <?php echo $lang->story->stageList['testing']?></label></span><br /></td>
<td><span><input type="checkbox" name="story<?php echo $i?>[]" value="developing" id="story<?php echo $content->id;?>developing"><label for="story<?php echo $content->id;?>developing"> <?php echo $lang->story->stageList['developing']?></label></span></td>
<td><span><input type="checkbox" name="story<?php echo $i?>[]" value="developed" id="story<?php echo $content->id;?>developed"><label for="story<?php echo $content->id;?>developed"> <?php echo $lang->story->stageList['developed']?></label></span></td>
<td><span><input type="checkbox" name="story<?php echo $i?>[]" value="testing" id="story<?php echo $content->id;?>testing"><label for="story<?php echo $content->id;?>testing"> <?php echo $lang->story->stageList['testing']?></label></span><br /></td>
</tr>
<tr>
<td><span><input type="checkbox" name="story<?php echo $i?>[]" value="tested" id="story3tested"><label for="story3tested"> <?php echo $lang->story->stageList['tested']?></label></span></td>
<td><span><input type="checkbox" name="story<?php echo $i?>[]" value="verified" id="story3verified"><label for="story3verified"> <?php echo $lang->story->stageList['verified']?></label></span></td>
<td><span><input type="checkbox" name="story<?php echo $i?>[]" value="tested" id="story<?php echo $content->id;?>tested"><label for="story<?php echo $content->id;?>tested"> <?php echo $lang->story->stageList['tested']?></label></span></td>
<td><span><input type="checkbox" name="story<?php echo $i?>[]" value="verified" id="story<?php echo $content->id;?>verified"><label for="story<?php echo $content->id;?>verified"> <?php echo $lang->story->stageList['verified']?></label></span></td>
<td></td>
</tr>
</table>
+1 -1
View File
@@ -18,7 +18,7 @@
<div class='main-header'>
<h2><?php echo $lang->printKanban->common;?></h2>
</div>
<form target='_blank' method='post'>
<form class="no-stash" target='_blank' method='post'>
<table class='table table-form'>
<tr>
<td class='text-right w-100px'><?php echo $lang->printKanban->content?>:</td>
+1 -1
View File
@@ -345,7 +345,7 @@
</div>
</div>
<?php endif;?>
<?php if(!(strpos($execution->projectInfo->model, 'waterfall') !== false and (empty($execution->projectInfo->hasProduct) or in_array($execution->attribute, array('request', 'review'))))):?>
<?php if($features['plan']):?>
<div class="detail">
<div class="detail-title"><strong><?php echo $lang->execution->linkPlan;?></strong></div>
<div class="detail-content">
+48 -4
View File
@@ -20,6 +20,8 @@ class gitlabModel extends model
public $developerAccess = 30;
public $maintainerAccess = 40;
protected $projects = array();
/**
* Get a gitlab by id.
*
@@ -385,6 +387,45 @@ class gitlabModel extends model
return $branches;
}
/**
* Get Gitlab commits.
*
* @param object $repo
* @param string $entry
* @param string $revision
* @param string $type
* @param object $pager
* @param string $begin
* @param string $end
* @access public
* @return array
*/
public function getCommits($repo, $entry, $revision = 'HEAD', $type = 'dir', $pager = null, $begin = 0, $end = 0)
{
$scm = $this->app->loadClass('scm');
$scm->setEngine($repo);
$comments = $scm->engine->getCommitsByPath($entry, '', '', isset($pager->recPerPage) ? $pager->recPerPage : 10, isset($pager->pageID) ? $pager->pageID : 1);
$designNames = $this->dao->select("commit, name")->from(TABLE_DESIGN)->where('deleted')->eq(0)->fetchPairs();
$designIds = $this->dao->select("commit, id")->from(TABLE_DESIGN)->where('deleted')->eq(0)->fetchPairs();
$commitIds = array();
foreach($comments as $comment)
{
$comment->revision = $comment->id;
$comment->originalComment = $comment->title;
$comment->comment = $this->loadModel('repo')->replaceCommentLink($comment->title);
$comment->committer = $comment->committer_name;
$comment->time = date("Y-m-d H:i:s", strtotime($comment->committed_date));
$comment->designName = zget($designNames, $comment->revision, '');
$comment->designID = zget($designIds, $comment->revision, '');
$commitIds[] = $comment->id;
}
$commitCounts = $this->dao->select('revision,commit')->from(TABLE_REPOHISTORY)->where('revision')->in($commitIds)->fetchPairs();
foreach($comments as $comment) $comment->commit = !empty($commitCounts[$comment->id]) ? $commitCounts[$comment->id] : '';
return $comments;
}
/**
* Create a gitlab.
*
@@ -424,7 +465,7 @@ class gitlabModel extends model
if(strpos($host, 'http://') !== 0 and strpos($host, 'https://') !== 0) return false;
$url = sprintf($host, $api);
return json_decode(commonModel::http($url, $data, $options));
return json_decode(commonModel::http($url, $data, $options, $headers = array(), $dataType = 'data', $method = 'POST', $timeout = 30, $httpCode = false, $log = false));
}
/**
@@ -461,7 +502,7 @@ class gitlabModel extends model
$gitlab = $this->loadModel('gitlab')->getByID($gitlabID);
if(!$gitlab) return '';
$url = rtrim($gitlab->url, '/') . "/api/v4/todos?project_id=$projectID&type=MergeRequest&state=pending&private_token={$gitlab->token}&sudo={$sudo}";
return json_decode(commonModel::http($url));
return json_decode(commonModel::http($url, $data = null, $optionsi = array(), $headers = array(), $dataType = 'data', $method = 'POST', $timeout = 30, $httpCode = false, $log = false));
}
/**
@@ -708,7 +749,7 @@ class gitlabModel extends model
$allResults = array();
for($page = 1; true; $page++)
{
$results = json_decode(commonModel::http($url . "&simple={$simple}&page={$page}&per_page=100"));
$results = json_decode(commonModel::http($url . "&simple={$simple}&page={$page}&per_page=100", $data = null, $optionsi = array(), $headers = array(), $dataType = 'data', $method = 'POST', $timeout = 30, $httpCode = false, $log = false));
if(!is_array($results)) break;
if(!empty($results)) $allResults = array_merge($allResults, $results);
if(count($results) < 100) break;
@@ -986,8 +1027,11 @@ class gitlabModel extends model
*/
public function apiGetSingleProject($gitlabID, $projectID)
{
if(isset($this->projects[$gitlabID][$projectID])) return $this->projects[$gitlabID][$projectID];
$url = sprintf($this->getApiRoot($gitlabID, false), "/projects/$projectID");
return json_decode(commonModel::http($url));
$this->projects[$gitlabID][$projectID] = json_decode(commonModel::http($url, $data = null, $optionsi = array(), $headers = array(), $dataType = 'data', $method = 'POST', $timeout = 30, $httpCode = false, $log = false));
return $this->projects[$gitlabID][$projectID];
}
/**
+1 -1
View File
@@ -31,7 +31,7 @@
<tr>
<th class='c-issue'><?php echo $lang->gitlab->gitlabIssue;?></th>
<th class='c-type'><?php echo $lang->gitlab->objectType;?></th>
<th class='c-product'><?php echo $lang->product->common;?></th>
<th class='c-product'><?php echo $lang->productCommon;?></th>
<th class='c-execution'><?php echo $lang->execution->common;?></th>
</tr>
</thead>
+3 -3
View File
@@ -125,9 +125,9 @@ class jenkins extends control
*/
public function ajaxGetJenkinsTasks($id)
{
if(empty($id)) return print(json_encode(array('' => '')));
if(empty($id)) return print('');
$tasks = $this->jenkins->getTasks($id);
echo json_encode($tasks);
$this->view->tasks = $this->jenkins->getTasks($id, 3);
$this->display();
}
}
+58 -4
View File
@@ -51,10 +51,11 @@ class jenkinsModel extends model
* Get jenkins tasks.
*
* @param int $id
* @param int $depth
* @access public
* @return array
*/
public function getTasks($id)
public function getTasks($id, $depth = 0)
{
$jenkins = $this->getById($id);
@@ -63,14 +64,67 @@ class jenkinsModel extends model
$jenkinsPassword = $jenkins->token ? $jenkins->token : $jenkins->password;
$userPWD = "$jenkinsUser:$jenkinsPassword";
$response = common::http($jenkinsServer . '/api/json/items/list', '', array(CURLOPT_USERPWD => $userPWD));
$response = common::http($jenkinsServer . '/api/json/items/list' . ($depth ? "?depth=1" : ''), '', array(CURLOPT_USERPWD => $userPWD), $headers = array(), $dataType = 'data', $method = 'POST', $timeout = 30, $httpCode = false, $log = false);
$response = json_decode($response);
$tasks = array();
if(isset($response->jobs))
if($depth)
{
foreach($response->jobs as $job) $tasks[basename($job->url)] = $job->name;
/* Support up to 4 levels. */
if(isset($response->jobs)) $tasks = $this->getDepthJobs($response->jobs, $userPWD, 1);
}
else
{
if(isset($response->jobs))
{
foreach($response->jobs as $job) $tasks[basename($job->url)] = $job->name;
}
}
return $tasks;
}
/**
* Get jobs by depth.
*
* @param object $jobs
* @param string $userPWD
* @param int $depth
* @access protected
* @return array
*/
protected function getDepthJobs($jobs, $userPWD, $depth = 1)
{
if($depth > 4) return array();
$tasks = array();
foreach($jobs as $job)
{
if(empty($job->url)) continue;
$isJob = true;
if(stripos($job->_class, '.multibranch') !== false or stripos($job->_class, '.folder') !== false or stripos($job->_class, '.OrganizationFolder') !== false) $isJob = false;
if(!empty($job->buildable) and $job->buildable == true) $isJob = true;
if($isJob)
{
$parms = parse_url($job->url);
$tasks[$parms['path']] = $job->name;
}
else
{
if($depth > 1)
{
$response = common::http($job->url . 'api/json', '', array(CURLOPT_USERPWD => $userPWD), $headers = array(), $dataType = 'data', $method = 'POST', $timeout = 30, $httpCode = false, $log = false);
$job = json_decode($response);
}
$tasks[basename($job->url)] = array();
if(empty($job->jobs)) continue;
$tasks[basename($job->url)] = $this->getDepthJobs($job->jobs, $userPWD, $depth + 1);
}
}
return $tasks;
}
@@ -0,0 +1,96 @@
<?php
/**
* The jenkins task view file of repo module of ZenTaoPMS.
*
* @copyright Copyright 2009-2022 QingDao Nature Easy Soft Network Technology Co,LTD (www.cnezsoft.com)
* @license LGPL (http://www.gnu.org/licenses/lgpl.html)
* @author Gang Zeng <zenggang@cnezsoft.com>
* @package repo
* @version $Id$
* @link http://www.zentao.net
*/
?>
<style>
#dropMenuTasks .tree li {padding: 3px 0 0 10px;}
#dropMenuTasks .tree li.has-list.open:before {border-left: 0px;}
#dropMenuTasks .tree li > a {max-width: 100%; line-height: 20px; border-radius: 2px; padding-top: 5px;}
#dropMenuTasks .col-left {padding: 0;}
#dropMenuTasks .label {margin-left: 3px;}
#dropMenuTasks .hide-in-search {padding-left: 8px;}
#dropMenuTasks .hide-in-search .hidden {display: block !important; visibility: inherit !important;}
#dropMenuTasksRepo > div.table-row > div > div > ul > li > div {padding-left: 10px;}
#dropMenuTasks ul.tree-angles {margin-bottom: 0;}
#dropMenuTasks {margin: 0;}
#dropMenuTasks ul > li > ul > li > a:hover {color: white; background-color: #0c64eb; text-decoration: none;}
#dropMenuTasks .tree .has-list > ul > li {padding-top: 0;}
.search-list .list-group {padding: 7px 10px;}
#dropMenuTasks .label-type {margin: 1px 10px; line-height: 20px;}
.tree li>.list-toggle {top: 0px;}
.tree .one-level>.list-toggle {top: 3px;}
</style>
<div class="table-row">
<div class="table-col col-left">
<div class="list-group" id="jenkinsTaskList">
<ul class='tree tree-angles' data-ride='tree' data-idx='0'>
<?php foreach($tasks as $groupName => $task):?>
<?php if(empty($task)) continue;?>
<?php if(is_array($task)):?>
<li data-idx='$groupName' data-id='<?php echo $groupName?>' class='has-list open in one-level'>
<i class='list-toggle icon'></i>
<div class='label-type'>
<a class='text-muted not-list-item'><?php echo $groupName;?></a>
</div>
<ul data-idx='<?php echo $groupName;?>'>
<?php foreach($task as $task2name => $task2):?>
<?php if(is_array($task2)):?>
<li data-idx='$groupName' data-id='<?php echo $task2name?>' class='has-list open in'>
<i class='list-toggle icon'></i>
<div class='label-type'>
<a class='text-muted not-list-item'><?php echo $task2name;?></a>
</div>
<ul data-idx='<?php echo $task2name;?>'>
<?php foreach($task2 as $task3name => $task3):?>
<?php if(is_array($task3)):?>
<li data-idx='$groupName' data-id='<?php echo $task3name?>' class='has-list open in'>
<i class='list-toggle icon'></i>
<div class='label-type'>
<a class='text-muted not-list-item'><?php echo $task3name;?></a>
</div>
<ul data-idx='<?php echo $task3name;?>'>
<?php foreach($task3 as $task4name => $task4):?>
<?php if(is_array($task4)) continue;?>
<li data-idx='<?php echo $task4name;?>' data-id='<?php echo $task4name;?>'>
<a href='###' id='<?php echo $task4name?>' class='' text-ellipsis' onclick='setJenkinsJob("<?php echo $task4;?>","<?php echo $task4name;?>")' title='<?php echo $task4;?>' data-key='<?php echo $task4;?>'><?php echo $task4;?></a>
</li>
<?php endforeach;?>
</ul>
</li>
<?php else:?>
<li data-idx='<?php echo $task3name;?>' data-id='<?php echo $task3name;?>'>
<a href='###' id='<?php echo $task3name?>' onclick='setJenkinsJob("<?php echo $task3;?>","<?php echo $task3name;?>")' class='' text-ellipsis' title='<?php echo $task3;?>' data-key='<?php echo $task3;?>'><?php echo $task3;?></a>
</li>
<?php endif;?>
<?php endforeach;?>
</ul>
</li>
<?php else:?>
<li data-idx='<?php echo $task2name;?>' data-id='<?php echo $task2name;?>'>
<a href='###' onclick='setJenkinsJob("<?php echo $task2;?>","<?php echo $task2name;?>")' id='<?php echo $task2name?>' class='' text-ellipsis' title='<?php echo $task2;?>' data-key='<?php echo $task2;?>'><?php echo $task2;?></a>
</li>
<?php endif;?>
<?php endforeach;?>
</ul>
</li>
<?php else:?>
<li data-idx='<?php echo $task;?>' data-id='<?php echo $task;?>'>
<a href='###' id='<?php echo $task;?>' class='text-ellipsis' onclick='setJenkinsJob("<?php echo $task;?>","<?php echo $groupName;?>")' title='<?php echo $task;?>' data-key='<?php echo $task;?>' ><?php echo $task;?></a>
</li>
<?php endif;?>
<?php endforeach;?>
</ul>
</div>
</div>
</div>
<script>
$('#jenkinsTaskList .tree').tree();
</script>
+5 -1
View File
@@ -60,6 +60,10 @@ class job extends control
$branch = $this->gitlab->apiGetSingleBranch($job->server, $pipeline->project, $pipeline->reference);
if($branch and isset($branch->can_push) and !$branch->can_push) $job->canExec = false;
}
elseif($job->engine == 'jenkins')
{
if(strpos($job->pipeline, '/job/') !== false) $job->pipeline = trim(str_replace('/job/', '/', $job->pipeline), '/');
}
}
$this->view->title = $this->lang->ci->job . $this->lang->colon . $this->lang->job->browse;
@@ -115,7 +119,7 @@ class job extends control
}
$this->app->loadLang('action');
$repoList = $this->loadModel('repo')->getList($this->projectID);
$repoList = $this->loadModel('repo')->getList($this->projectID, false);
$repoPairs = array(0 => '');
$gitlabRepos = array(0 => '');
$repoTypes = array();
+5
View File
@@ -2,9 +2,14 @@
.only-pick-time thead th, .only-pick-time tfoot th {color: transparent !important;}
.checkbox-primary.checkbox-inline {display: inline-block !important;}
.checkbox-primary.checkbox-inline label {padding-left: 5px !important;}
.jktask-label {min-width: 50px; max-width: 300px; border-radius: 0px 4px 4px 0px;}
.input-group-addon {border-radius: 2px 0px 0px 2px !important;}
button.text-right {min-width: 100px; text-align: right;}
#server_chosen .chosen-single {border-right: 0px;}
#pipelineBox {width: 385px;}
#svnDirBox .input-group {width: unset !important;}
#jenkinsServerTR .input-group-addon {border-left-width: 0 !important;}
#jenkinsServerTR .dropdown {position: relative;}
#jenkinsServerTR .table-col:first-child {width: 375.5px;}
.chosen-container .chosen-drop{z-index: 1100;} /* from c20b7e7a5 */
+24 -16
View File
@@ -18,7 +18,7 @@ $(document).ready(function()
$('#frameBox .loading').remove();
$('#frameBox .input-group').append(html);
$('#frameBox #frame').chosen();
$('#frame').change();
}
getFrameSelect('');
@@ -171,23 +171,16 @@ $(document).ready(function()
$('#jkServer').change(function()
{
var jenkinsID = $(this).val();
$('#jenkinsServerTR #jkTask').remove();
$('#jenkinsServerTR #jkTask_chosen').remove();
$('#jenkinsServerTR .dropdown,.input-group-addon').hide();
$('#jenkinsServerTR .input-group').append("<div class='load-indicator loading'></div>");
$.getJSON(createLink('jenkins', 'ajaxGetJenkinsTasks', 'jenkinsID=' + jenkinsID), function(tasks)
{
html = "<select id='jkTask' name='jkTask' class='form-control'>";
for(taskKey in tasks)
{
var task = tasks[taskKey];
html += "<option value='" + taskKey + "'>" + task + "</option>";
}
html += '</select>';
$('#jenkinsServerTR .loading').remove();
$('#jenkinsServerTR .input-group').append(html);
setJenkinsJob('', '');
$('#jenkinsServerTR #jkTask').chosen({drop_direction: 'auto'});
})
$.get(createLink('jenkins', 'ajaxGetJenkinsTasks', 'jenkinsID=' + jenkinsID), function(tasks)
{
$('#jenkinsServerTR .loading').remove();
$('#dropMenuTasks').html(tasks);
$('#jenkinsServerTR .dropdown,.input-group-addon').show();
});
/* There has been a problem with handling the prompt label. */
$('#jkTaskLabel').remove();
@@ -253,3 +246,18 @@ $(document).ready(function()
$('#engine').change();
$('#triggerType').change();
});
/**
* Set jenkins job.
*
* @param string $name
* @param string $task
* @access public
* @return void
*/
function setJenkinsJob(name, task)
{
if(name) $('.jktask-label').removeClass('text-right');
$('#jkTask').val(task);
$('.jktask-label .text').html(name);
}
+6 -2
View File
@@ -106,13 +106,17 @@
</tr>
<tr id="jenkinsServerTR">
<th><?php echo $lang->job->jkHost; ?></th>
<td colspan='2' class='required'>
<td colspan='2'>
<div class='table-row'>
<div class='table-col'><?php echo html::select('jkServer', $jenkinsServerList, '', "class='form-control chosen'"); ?></div>
<div class='table-col'>
<div class='input-group'>
<span class='input-group-addon'><?php echo $lang->job->pipeline;?></span>
<?php echo html::select('jkTask', array('' => ''), '', "class='form-control chosen'"); ?>
<div class='dropdown'>
<?php echo html::hidden('jkTask');?>
<button data-toggle='dropdown' type='button' class='btn jktask-label required text-right' title=''><span class='text'></span> <span class='caret' style='margin-bottom: -1px'></span></button>
<div id='dropMenuTasks' class='dropdown-menu search-list' data-ride='searchList' data-url=''></div>
</div>
</div>
</div>
</div>
+28 -7
View File
@@ -34,16 +34,38 @@ class mr extends control
$this->app->loadClass('pager', $static = true);
$pager = new pager($recTotal, $recPerPage, $pageID);
$repos = $this->loadModel('repo')->getListBySCM(array('Gitlab', 'Gitea', 'Gogs'));
if(empty($repos)) $this->locate($this->repo->createLink('create'));
$repoCount = $this->dao->select('*')->from(TABLE_REPO)->where('deleted')->eq('0')
->andWhere('SCM')->in(array('Gitlab', 'Gitea', 'Gogs'))
->andWhere('synced')->eq(1)
->orderBy('id')
->count();
if($repoCount == 0) $this->locate($this->repo->createLink('create'));
$repoID = $this->repo->saveState($repoID, $objectID);
$repoID = $this->loadModel('repo')->saveState($repoID, $objectID);
$repo = $this->repo->getRepoByID($repoID);
if(!in_array(strtolower($repo->SCM), $this->config->mr->gitServiceList)) $repo = $repos[0];
if(!in_array(strtolower($repo->SCM), $this->config->mr->gitServiceList))
{
$repoID = $this->dao->select('id')->from(TABLE_REPO)->where('deleted')->eq('0')->andWhere('SCM')->in(array('Gitlab', 'Gitea', 'Gogs'))->andWhere('synced')->eq(1)->orderBy('id')->fetch('id');
$repo = $this->repo->getRepoByID($repoID);
}
$this->loadModel('ci')->setMenu($repo->id);
$projects = $this->mr->getAllProjects($repoID, $repo->SCM);
$MRList = $this->mr->getList($mode, $param, $orderBy, $pager, empty($projects) ? false : $projects, $repoID);
$filterProjects = empty($repo->serviceProject) ? array() : array($repo->serviceHost => array($repo->serviceProject => $repo->serviceProject));
$MRList = $this->mr->getList($mode, $param, $orderBy, $pager, $filterProjects, $repoID);
if($repo->SCM == 'Gitlab')
{
$projectIds = array();
foreach($MRList as $MR)
{
$projectIds[$MR->sourceProject] = $MR->sourceProject;
$projectIds[$MR->targetProject] = $MR->targetProject;
}
$projects = $this->mr->getGitlabProjects($repo->serviceHost, $projectIds);
}
else
{
$projects = $this->mr->getAllProjects($repoID, $repo->SCM);
}
/* Save current URI to session. */
$this->session->set('mrList', $this->app->getURI(true), 'repo');
@@ -87,7 +109,6 @@ class mr extends control
$this->view->param = $param;
$this->view->repoID = $repoID;
$this->view->objectID = $objectID;
$this->view->repos = $repos;
$this->view->repo = $repo;
$this->view->orderBy = $orderBy;
$this->view->openIDList = $openIDList;
+16 -3
View File
@@ -143,10 +143,11 @@ class mrModel extends model
* Get gitlab projects.
*
* @param int $hostID
* @param array $projectIds
* @access public
* @return array
*/
public function getGitlabProjects($hostID = 0)
public function getGitlabProjects($hostID = 0, $projectIds = array())
{
$allProjects = array();
$allGroups = array();
@@ -164,7 +165,19 @@ class mrModel extends model
$minProject = min($projectCount->minSource, $projectCount->minTarget);
$maxProject = max($projectCount->maxSource, $projectCount->maxTarget);
}
$allProjects[$hostID] = $this->gitlab->apiGetProjects($hostID, 'false', $minProject, $maxProject);
if($projectIds)
{
foreach($projectIds as $projectID)
{
$project = $this->gitlab->apiGetSingleProject($hostID, $projectID);
if(isset($project->id)) $allProjects[$hostID][] = $project;
}
}
else
{
$allProjects[$hostID] = $this->gitlab->apiGetProjects($hostID, 'false', $minProject, $maxProject);
}
/* If not an administrator, need to obtain group member information. */
$groupIDList = array(0 => 0);
@@ -747,7 +760,7 @@ class mrModel extends model
$url = sprintf($this->loadModel('gitea')->getApiRoot($hostID), "/repos/$projectID/pulls");
}
$response = json_decode(commonModel::http($url));
$response = json_decode(commonModel::http($url, $data = null, $options = array(), $headers = array(), $dataType = 'data', $method = 'POST', $timeout = 30, $httpCode = false, $log = false));
if(empty($response)) $response = array();
if($scm == 'Gitea')
{
+2 -2
View File
@@ -1305,8 +1305,8 @@ class product extends control
$actionURL = $this->createLink('product', 'all', "browseType=bySearch&orderBy=order_asc&queryID=myQueryID");
$this->product->buildProductSearchForm($param, $actionURL);
$this->view->title = $this->lang->product->common;
$this->view->position[] = $this->lang->product->common;
$this->view->title = $this->lang->productCommon;
$this->view->position[] = $this->lang->productCommon;
$this->view->recTotal = $pager->recTotal;
$this->view->productStats = $productStats;
+1 -1
View File
@@ -62,7 +62,7 @@ $lang->product->doc = 'Dok';
$lang->product->project = $lang->executionCommon . 'Liste';
$lang->product->build = 'Build';
$lang->product->moreProduct = "More {$lang->productCommon}";
$lang->product->projectInfo = "{$lang->projectCommon}s that are linked to this {$lang->productCommon} are listed below.";
$lang->product->projectInfo = "My {$lang->projectCommon}s that are linked to this {$lang->productCommon} are listed below.";
$lang->product->progress = "Progress";
$lang->product->currentExecution = "Aktuelle Execution";
+1 -1
View File
@@ -62,7 +62,7 @@ $lang->product->doc = "{$lang->productCommon} Documents";
$lang->product->project = $lang->executionCommon . ' List';
$lang->product->build = 'Build List';
$lang->product->moreProduct = "More {$lang->productCommon}";
$lang->product->projectInfo = "{$lang->projectCommon}s that are linked to this {$lang->productCommon} are listed below.";
$lang->product->projectInfo = "My {$lang->projectCommon}s that are linked to this {$lang->productCommon} are listed below.";
$lang->product->progress = "Progress";
$lang->product->currentExecution = "Current Execution";
+1 -1
View File
@@ -62,7 +62,7 @@ $lang->product->doc = "Documents {$lang->productCommon}";
$lang->product->project = ' Liste ' . $lang->executionCommon;
$lang->product->build = 'Liste Builds';
$lang->product->moreProduct = "More {$lang->productCommon}";
$lang->product->projectInfo = "Les {$lang->projectCommon}s qui sont associés à ce {$lang->productCommon} sont listés ci-dessous.";
$lang->product->projectInfo = "My {$lang->projectCommon}s that are linked to this {$lang->productCommon} are listed below.";
$lang->product->progress = "Progress";
$lang->product->currentExecution = "Current Execution";
+1 -1
View File
@@ -62,7 +62,7 @@ $lang->product->doc = '文档列表';
$lang->product->project = $lang->executionCommon . '列表';
$lang->product->build = '版本列表';
$lang->product->moreProduct = "更多{$lang->productCommon}";
$lang->product->projectInfo = "所有与此{$lang->productCommon}关联的{$lang->projectCommon}";
$lang->product->projectInfo = "所有与此{$lang->productCommon}关联的我参与的{$lang->projectCommon}";
$lang->product->progress = "{$lang->productCommon}完成度";
$lang->product->currentExecution = "当前执行";
+1 -1
View File
@@ -661,7 +661,7 @@ class productModel extends model
if($currentModule == 'bug' and $currentMethod == 'edit') $currentMethod = 'browse';
if($currentMethod == 'report') $currentMethod = 'browse';
$currentProductName = $this->lang->product->common;
$currentProductName = $this->lang->productCommon;
if($productID)
{
$currentProduct = $this->getById($productID);
+1 -1
View File
@@ -21,7 +21,7 @@
<div class="main-header">
<h2><?php echo $lang->product->create;?></h2>
</div>
<form class="load-indicator main-form form-ajax" id="createForm" method="post" target='hiddenwin'>
<form class="load-indicator main-form form-ajax<?php if(defined('TUTORIAL')) echo ' not-watch';?>" id="createForm" method="post" target='hiddenwin'>
<table class="table table-form">
<tbody>
<?php if($this->config->systemMode == 'ALM'):?>
+1 -1
View File
@@ -33,7 +33,7 @@ $config->project->sortFields->status = 'status';
$config->project->sortFields->budget = 'budget';
$config->project->multiple['project'] = ',qa,devops,doc,build,release,dynamic,settings,';
$config->project->multiple['execution'] = ',task,kanban,burn,view,story,';
$config->project->multiple['execution'] = ',task,kanban,burn,view,story,CFD,';
global $lang;
$config->project->datatable = new stdclass();
+1 -1
View File
@@ -2907,7 +2907,7 @@ class projectModel extends model
$executionID = $this->dao->select('id')->from(TABLE_EXECUTION)
->where('project')->eq($projectID)
->andWhere('multiple')->eq('0')
->andWhere('type')->eq('sprint')
->andWhere('type')->in('kanban,sprint')
->andWhere('deleted')->eq('0')
->fetch('id');
}
+2 -2
View File
@@ -156,7 +156,7 @@
<div class='table-col'>
<?php $hasBranch = $product->type != 'normal' and isset($branchGroups[$product->id]);?>
<div class='input-group required <?php if($hasBranch) echo ' has-branch';?>'>
<span class='input-group-addon'><?php echo $lang->product->common;?></span>
<span class='input-group-addon'><?php echo $lang->productCommon;?></span>
<?php echo html::select("products[$i]", $allProducts, $product->id, "class='form-control chosen' onchange='loadBranches(this)' data-last='" . $product->id . "' data-type='" . $product->type . "'");?>
</div>
</div>
@@ -193,7 +193,7 @@
<div class='table-row'>
<div class='table-col'>
<div class='input-group required'>
<span class='input-group-addon'><?php echo $lang->product->common;?></span>
<span class='input-group-addon'><?php echo $lang->productCommon;?></span>
<?php echo html::select("products[0]", $allProducts, '', "class='form-control chosen' onchange='loadBranches(this)'");?>
<?php if(common::hasPriv('product', 'create')):?>
<span class='input-group-addon newProduct'>
+1 -1
View File
@@ -158,7 +158,7 @@
<div class='table-col'>
<?php $hasBranch = $product->type != 'normal' and isset($branchGroups[$product->id]);?>
<div class='input-group <?php if($hasBranch) echo ' has-branch';?>'>
<span class='input-group-addon'><?php echo $lang->product->common;?></span>
<span class='input-group-addon'><?php echo $lang->productCommon;?></span>
<?php echo html::select("products[$i]", $allProducts, $product->id, "class='form-control chosen' onchange='loadBranches(this)' data-last='" . $product->id . "' data-type='" . $product->type . "'");?>
</div>
</div>
+1
View File
@@ -326,6 +326,7 @@ class projectrelease extends control
$this->view->bugPager = $bugPager;
$this->view->leftBugPager = $leftBugPager;
$this->view->builds = $this->loadModel('build')->getBuildPairs($release->product, 'all', 'withbranch|hasproject', 0, 'execution', '', false);
$this->view->summary = $this->product->summary($stories);
if($this->app->getViewType() == 'json')
{
+5 -5
View File
@@ -36,13 +36,13 @@
<div class='main-col'>
<div class='main'>
<div class='tabs' id='tabsNav'>
<?php $countStories = count($stories); $countBugs = count($bugs); $countLeftBugs = count($leftBugs);?>
<?php $countBugs = count($bugs); $countLeftBugs = count($leftBugs);?>
<ul class='nav nav-tabs'>
<li <?php if($type == 'story') echo "class='active'"?>><a href='#stories' data-toggle='tab'><?php echo html::icon($lang->icons['story'], 'text-green') . ' ' . $lang->release->stories;?></a></li>
<li <?php if($type == 'bug') echo "class='active'"?>><a href='#bugs' data-toggle='tab'><?php echo html::icon($lang->icons['bug'], 'text-green') . ' ' . $lang->release->bugs;?></a></li>
<li <?php if($type == 'leftBug') echo "class='active'"?>><a href='#leftBugs' data-toggle='tab'><?php echo html::icon($lang->icons['bug'], 'text-red') . ' ' . $lang->release->generatedBugs;?></a></li>
<li <?php if($type == 'releaseInfo') echo "class='active'"?>><a href='#releaseInfo' data-toggle='tab'><?php echo html::icon($lang->icons['plan'], 'text-info') . ' ' . $lang->release->view;?></a></li>
<?php if($countStories or $countBugs or $countLeftBugs):?>
<?php if($summary or $countBugs or $countLeftBugs):?>
<li class='pull-right'><div><?php common::printIcon('projectrelease', 'export', '', '', 'button', '', '', "export btn-sm");?></div></li>
<?php endif;?>
</ul>
@@ -120,7 +120,7 @@
</tbody>
</table>
<div class='table-footer'>
<?php if($countStories and ($canBatchUnlink or $canBatchClose) and $canBeChanged):?>
<?php if($summary and ($canBatchUnlink or $canBatchClose) and $canBeChanged):?>
<div class="checkbox-primary check-all"><label><?php echo $lang->selectAll?></label></div>
<div class="table-actions btn-toolbar">
<?php
@@ -137,7 +137,7 @@
}
?>
</div>
<div class='table-statistic'><?php echo sprintf($lang->release->finishStories, $countStories);?></div>
<div class='table-statistic'><?php echo $summary;?></div>
<?php endif;?>
<?php
$this->app->rawParams['type'] = 'story';
@@ -419,7 +419,7 @@
</div>
</div>
<style>
.tabs .tab-content .tab-pane .action{position: absolute; right: <?php echo ($countStories or $countBugs or $countLeftBugs) ? '100px' : '-1px'?>; top: 0px;}
.tabs .tab-content .tab-pane .action{position: absolute; right: <?php echo ($summary or $countBugs or $countLeftBugs) ? '100px' : '-1px'?>; top: 0px;}
</style>
<?php js::set('param', helper::safe64Decode($param))?>
<?php js::set('link', $link)?>
+1
View File
@@ -254,6 +254,7 @@ class release extends control
$this->view->bugPager = $bugPager;
$this->view->leftBugPager = $leftBugPager;
$this->view->builds = $this->loadModel('build')->getBuildPairs($release->product, 'all', 'withbranch|hasproject', 0, 'execution', '', false);
$this->view->summary = $this->product->summary($stories);
if($this->app->getViewType() == 'json')
{
+5 -5
View File
@@ -38,13 +38,13 @@
<div class='main-col'>
<div class='main'>
<div class='tabs' id='tabsNav'>
<?php $countStories = count($stories); $countBugs = count($bugs); $countLeftBugs = count($leftBugs);?>
<?php $countBugs = count($bugs); $countLeftBugs = count($leftBugs);?>
<ul class='nav nav-tabs'>
<li <?php if($type == 'story') echo "class='active'"?>><a href='#stories' data-toggle='tab'><?php echo html::icon($lang->icons['story'], 'text-green') . ' ' . $lang->release->stories;?></a></li>
<li <?php if($type == 'bug') echo "class='active'"?>><a href='#bugs' data-toggle='tab'><?php echo html::icon($lang->icons['bug'], 'text-green') . ' ' . $lang->release->bugs;?></a></li>
<li <?php if($type == 'leftBug') echo "class='active'"?>><a href='#leftBugs' data-toggle='tab'><?php echo html::icon($lang->icons['bug'], 'text-red') . ' ' . $lang->release->generatedBugs;?></a></li>
<li <?php if($type == 'releaseInfo') echo "class='active'"?>><a href='#releaseInfo' data-toggle='tab'><?php echo html::icon($lang->icons['plan'], 'text-info') . ' ' . $lang->release->view;?></a></li>
<?php if($countStories or $countBugs or $countLeftBugs):?>
<?php if($summary or $countBugs or $countLeftBugs):?>
<li class='pull-right'><div><?php common::printIcon('release', 'export', '', '', 'button', '', '', "export btn-sm");?></div></li>
<?php endif;?>
</ul>
@@ -122,7 +122,7 @@
</tbody>
</table>
<div class='table-footer'>
<?php if($countStories and ($canBatchUnlink or $canBatchClose) and $canBeChanged):?>
<?php if($summary and ($canBatchUnlink or $canBatchClose) and $canBeChanged):?>
<div class="checkbox-primary check-all"><label><?php echo $lang->selectAll?></label></div>
<div class="table-actions btn-toolbar">
<?php
@@ -139,7 +139,7 @@
}
?>
</div>
<div class='table-statistic'><?php echo sprintf($lang->release->finishStories, $countStories);?></div>
<div class='table-statistic'><?php echo $summary;?></div>
<?php endif;?>
<?php
$this->app->rawParams['type'] = 'story';
@@ -436,7 +436,7 @@
</div>
</div>
<style>
.tabs .tab-content .tab-pane .action{position: absolute; right: <?php echo ($countStories or $countBugs or $countLeftBugs) ? '100px' : '-1px'?>; top: 0px;}
.tabs .tab-content .tab-pane .action{position: absolute; right: <?php echo ($summary or $countBugs or $countLeftBugs) ? '100px' : '-1px'?>; top: 0px;}
</style>
<?php js::set('param', helper::safe64Decode($param))?>
<?php js::set('link', $link)?>
+38 -5
View File
@@ -80,7 +80,7 @@ class repo extends control
$repoID = $this->repo->saveState(0, $objectID);
if($this->viewType !== 'json') $this->commonAction($repoID, $objectID);
$repoList = $this->repo->getList(0, '', $orderBy);
$repoList = $this->repo->getList(0, '', $orderBy, null, true);
$sonarRepoList = $this->loadModel('job')->getSonarqubeByRepo(array_keys($repoList));
/* Pager. */
@@ -599,17 +599,48 @@ class repo extends control
}
/* Refresh repo. */
if($refresh) $this->repo->updateCommit($repoID, $objectID, $originBranchID);
if($refresh)
{
$this->repo->updateCommit($repoID, $objectID, $originBranchID);
/* Get files info. */
$infos = $this->repo->getFileCommits($repo, $branchID, $path);
if($this->cookie->repoRefresh) setcookie('repoRefresh', 0, 0, $this->config->webRoot, '', $this->config->cookieSecure, true);
if($repo->SCM == 'Gitlab') $this->repo->checkDeletedBranches($repoID, $branches);
}
/* Set logType and revisions. */
$logType = 'dir';
$revisions = $this->repo->getCommits($repo, $path, $revision, $logType, $pager);
$lastRevision = current($revisions);
/* Get files info. */
if($repo->SCM == 'Gitlab')
{
$cacheFile = $this->repo->getCacheFile($repo->id, $path, $branchID);
$cacheRefreshTime = isset($lastRevision->time) ? date('Y-m-d H:i', strtotime($lastRevision->time)) : date('Y-m-d H:i');
if(!$cacheFile or !file_exists($cacheFile) or filemtime($cacheFile) < strtotime($cacheRefreshTime))
{
$infos = $this->repo->getFileList($repo, $branchID, $path);
if($cacheFile)
{
if(!file_exists($cacheFile . '.lock'))
{
touch($cacheFile . '.lock');
file_put_contents($cacheFile, serialize($infos));
unlink($cacheFile . '.lock');
}
}
}
else
{
$infos = unserialize(file_get_contents($cacheFile));
}
}
else
{
$infos = $this->repo->getFileCommits($repo, $branchID, $path);
}
if($this->cookie->repoRefresh) setcookie('repoRefresh', 0, 0, $this->config->webRoot, '', $this->config->cookieSecure, true);
/* Synchronous commit only in root path. */
if(in_array($repo->SCM, $this->config->repo->gitTypeList) and empty($path) and $infos and empty($revisions)) $this->locate($this->repo->createLink('showSyncCommit', "repoID=$repoID&objectID=$objectID&branch=" . helper::safe64Encode(base64_encode($this->cookie->repoBranch))));
@@ -685,6 +716,8 @@ class repo extends control
$this->view->revision = $revision;
$this->view->repoID = $repoID;
$this->view->objectID = $objectID;
$this->view->entry = $entry;
$this->view->type = $type;
$this->view->branchID = $this->cookie->repoBranch;
$this->view->entry = urldecode($entry);
$this->view->path = urldecode($entry);
+1
View File
@@ -1 +1,2 @@
.m-repo-log .btn-back {margin-right: 0; padding-top: 8px;}
#repoPageSize {right: 30px;}
+1 -1
View File
@@ -13,7 +13,7 @@ function processCheckbox()
if (checkNum >= 2)
{
$("input:checkbox[name='revision[]']").each(function(){if($(this).attr('checked') == false) $(this).attr("disabled","disabled")});
}
}
else
{
$("input:checkbox[name='revision[]']").each(function(){if($(this).attr('checked') == false) $(this).attr("enabled","enabled")});
+127 -7
View File
@@ -107,10 +107,11 @@ class repoModel extends model
* @param string $SCM Subversion|Git|Gitlab
* @param string $orderBy
* @param object $pager
* @param bool $getCodePath
* @access public
* @return array
*/
public function getList($projectID = 0, $SCM = '', $orderBy = 'id_desc', $pager = null)
public function getList($projectID = 0, $SCM = '', $orderBy = 'id_desc', $pager = null, $getCodePath = false)
{
$repos = $this->dao->select('*')->from(TABLE_REPO)
->where('deleted')->eq('0')
@@ -143,7 +144,7 @@ class repoModel extends model
}
}
if(in_array(strtolower($repo->SCM), $this->config->repo->gitServiceList)) $repo = $this->processGitService($repo);
if(in_array(strtolower($repo->SCM), $this->config->repo->gitServiceList)) $repo = $this->processGitService($repo, $getCodePath);
}
return $repos;
@@ -731,6 +732,8 @@ class repoModel extends model
*/
public function getCommits($repo, $entry, $revision = 'HEAD', $type = 'dir', $pager = null, $begin = 0, $end = 0)
{
if($repo->SCM == 'Gitlab') return $this->loadModel('gitlab')->getCommits($repo, $entry, $revision, $type, $pager, $begin, $end);
$entry = ltrim($entry, '/');
$entry = $repo->prefix . (empty($entry) ? '' : '/' . $entry);
@@ -895,10 +898,10 @@ class repoModel extends model
*/
public function getCacheFile($repoID, $path, $revision)
{
$cachePath = $this->app->getCacheRoot() . '/' . 'repo';
$cachePath = $this->app->getCacheRoot() . '/repo/' . $repoID;
if(!is_dir($cachePath)) mkdir($cachePath, 0777, true);
if(!is_writable($cachePath)) return false;
return $cachePath . '/' . $repoID . '-' . md5("{$this->cookie->repoBranch}-$path-$revision");
return $cachePath . '/' . md5("{$this->cookie->repoBranch}-$path-$revision");
}
/**
@@ -2136,20 +2139,21 @@ class repoModel extends model
* Process git service repo.
*
* @param object $repo
* @param bool $getCodePath
* @access public
* @return object
*/
public function processGitService($repo)
public function processGitService($repo, $getCodePath = true)
{
$service = $this->loadModel('pipeline')->getByID($repo->serviceHost);
if($repo->SCM == 'Gitlab')
{
$project = $this->loadModel('gitlab')->apiGetSingleProject($repo->serviceHost, $repo->serviceProject);
if($getCodePath) $project = $this->loadModel('gitlab')->apiGetSingleProject($repo->serviceHost, $repo->serviceProject);
$repo->path = $service ? sprintf($this->config->repo->{$service->type}->apiPath, $service->url, $repo->serviceProject) : '';
$repo->client = $service ? $service->url : '';
$repo->password = $service ? $service->token : '';
$repo->codePath = $project ? $project->web_url : $repo->path;
$repo->codePath = isset($project->web_url) ? $project->web_url : $repo->path;
}
elseif(in_array($repo->SCM, array('Gitea', 'Gogs')))
{
@@ -2368,6 +2372,48 @@ class repoModel extends model
return array_merge($folders, $files);
}
/**
* Get Repo file list.
*
* @param object $repo
* @param string $branch
* @param string $path
* @access public
* @return array
*/
public function getFileList($repo, $branch, $path = '')
{
$scm = $this->app->loadClass('scm');
$scm->setEngine($repo);
$paths = array();
$files = $scm->engine->tree($path, 0);
foreach($files as $file)
{
$paths[] = $file->path;
}
$requests = array();
foreach($paths as $path)
{
$requests[]['url'] = $scm->engine->getCommitsByPath($path, '', '', 1, 1, true);
}
$this->app->loadClass('requests', true);
$commits = requests::request_multiple($requests);
foreach($files as $key => $file)
{
$files[$key]->kind = $file->type == 'tree' ? 'dir' : 'file';
$commit = isset($commits[$key]->body) ? json_decode($commits[$key]->body) : array();
$files[$key]->revision = isset($commit[0]->id) ? $commit[0]->id : '';
$files[$key]->comment = isset($commit[0]->title) ? $commit[0]->title : '';
$files[$key]->account = isset($commit[0]->committer_name) ? $commit[0]->committer_name : '';
$files[$key]->date = isset($commit[0]->committed_date) ? $commit[0]->committed_date : '';
}
return $files;
}
/**
* Get html for file tree.
*
@@ -2383,6 +2429,50 @@ class repoModel extends model
$allFiles = array();
if(is_null($diffs))
{
if($repo->SCM == 'Gitlab')
{
$cacheFile = $this->getCacheFile($repo->id, 'tree-list', 'tree-list');
$lastRevision = $this->dao->select('t1.revision')->from(TABLE_REPOHISTORY)->alias('t1')
->leftJoin(TABLE_REPOBRANCH)->alias('t2')->on('t1.id=t2.revision')
->where('t1.repo')->eq($repo->id)
->andWhere('t2.branch')->eq($this->cookie->repoBranch)
->orderBy('t1.commit desc')
->fetch('revision');
if($cacheFile and file_exists($cacheFile)) $infos = unserialize(file_get_contents($cacheFile));
if(!$cacheFile or !file_exists($cacheFile) or $infos['revision'] != $lastRevision)
{
$scm = $this->app->loadClass('scm');
$scm->setEngine($repo);
$this->app->loadClass('requests', true);
$files = $scm->engine->tree('', 1, true);
$allFiles = array();
foreach($files as $file)
{
$allFiles[] = $file->path;
}
$infos = array('revision' => $lastRevision, 'files' => $allFiles);
if($cacheFile)
{
if(!file_exists($cacheFile . '.lock'))
{
touch($cacheFile . '.lock');
file_put_contents($cacheFile, serialize($infos));
unlink($cacheFile . '.lock');
}
}
}
else
{
$infos = unserialize(file_get_contents($cacheFile));
$allFiles = $infos['files'];
}
}
else
{
if($repo->SCM != 'Subversion' and empty($branch)) $branch = $this->cookie->repoBranch;
$files = $this->dao->select('t1.path,t2.time,t1.action')->from(TABLE_REPOFILES)->alias('t1')
->leftJoin(TABLE_REPOHISTORY)->alias('t2')->on('t1.revision=t2.id')
@@ -2420,6 +2510,7 @@ class repoModel extends model
$allFiles[] = $file->path;
}
}
}
}
else
{
@@ -2834,4 +2925,33 @@ class repoModel extends model
}
if($repo->SCM == 'Subversion') $this->loadModel('svn')->updateCommit($repo, $commentGroup, false);
}
/**
* Delete the deleted branch.
*
* @param int $repoID
* @param array $latestBranches
* @access public
* @return bool
*/
public function checkDeletedBranches($repoID, $latestBranches)
{
if(empty($latestBranches)) return false;
$currentBranches = $this->dao->select('branch')->from(TABLE_REPOBRANCH)->where('repo')->eq($repoID)->groupBy('branch')->fetchPairs('branch');
$deletedBranches = array_diff($currentBranches, $latestBranches);
foreach($deletedBranches as $deletedBranch)
{
if($deletedBranch == 'master') continue;
$revisionIds = $this->dao->select('revision')->from(TABLE_REPOBRANCH)->where('repo')->eq($repoID)->andWhere('branch')->eq($deletedBranch)->fetchPairs('revision');
$fileIds = $this->dao->select('id')->from(TABLE_REPOFILES)->where('revision')->in($revisionIds)->fetchPairs('id');
$this->dao->delete()->from(TABLE_REPOHISTORY)->where('id')->in($revisionIds)->exec();
$this->dao->delete()->from(TABLE_REPOFILES)->where('id')->in($fileIds)->exec();
$this->dao->delete()->from(TABLE_REPOBRANCH)->where('repo')->eq($repoID)->andWhere('branch')->eq($deletedBranch)->exec();
}
return true;
}
}
+9
View File
@@ -10,6 +10,7 @@
?>
<?php include '../../common/view/header.html.php';?>
<?php js::set('repoID', $repoID);?>
<?php js::set('paramsBase', "repoID=$repoID&objectID=$objectID&entry=" . $this->repo->encodePath($entry) . "&revision=$revision&type=$type");?>
<div id='mainMenu' class='clearfix'>
<div class="btn-toolbar pull-left">
<?php echo html::backButton("<i class='icon icon-back icon-sm'></i> " . $lang->goback, '', 'btn btn-link');?>
@@ -81,7 +82,15 @@
</table>
<div class='table-footer'>
<?php if(common::hasPriv('repo', 'diff')) echo html::submitButton($lang->repo->diff, '', count($logs) < 2 ? 'disabled btn btn-primary' : 'btn btn-primary')?>
<?php if($repo->SCM == 'Gitlab'):?>
<?php
$params = "repoID=$repoID&objectID=$objectID&entry=" . $this->repo->encodePath($entry) . "&revision=$revision&type=$type&recTotal={$pager->recTotal}";
$total = count($logs) < $pager->recPerPage ? $pager->recPerPage * $pager->pageID : $pager->recPerPage * ($pager->pageID + 1)
?>
<ul id="repoPageSize" data-page-cookie='pagerRepoLog' class="pager" data-ride="pager" data-elements="size_menu,prev_icon,next_icon" data-rec-total="<?php echo $total;?>" data-rec-per-page="<?php echo $pager->recPerPage;?>" data-page="<?php echo $pager->pageID;?>" data-link-creator="<?php echo $this->repo->createLink('log', $params . '&recPerPage={recPerPage}&pageID={page}');?>"></ul>
<?php else:?>
<?php $pager->show('right', 'pagerjs');?>
<?php endif;?>
</div>
</form>
</div>
+2 -2
View File
@@ -94,14 +94,14 @@ $lang->search->modules['testreport'] = 'Testing Report';
$lang->search->modules['productplan'] = 'Plan';
$lang->search->modules['program'] = 'Program';
$lang->search->modules['project'] = $lang->projectCommon;
$lang->search->modules['execution'] = $lang->executionCommon;
$lang->search->modules['execution'] = $lang->execution->common;
$lang->search->modules['story'] = $lang->SRCommon;
$lang->search->modules['requirement'] = $lang->URCommon;
$lang->search->objectTypeList['story'] = $lang->SRCommon;
$lang->search->objectTypeList['requirement'] = $lang->URCommon;
$lang->search->objectTypeList['stage'] = 'stage';
$lang->search->objectTypeList['sprint'] = $lang->executionCommon;
$lang->search->objectTypeList['sprint'] = $lang->execution->common;
$lang->search->objectTypeList['kanban'] = 'kanban';
$lang->search->objectTypeList['commonIssue'] = 'Issue';
$lang->search->objectTypeList['stakeholderIssue'] = 'Stakeholder Issue';
+2 -2
View File
@@ -94,14 +94,14 @@ $lang->search->modules['testreport'] = 'Testing Report';
$lang->search->modules['productplan'] = 'Plan';
$lang->search->modules['program'] = 'Program';
$lang->search->modules['project'] = $lang->projectCommon;
$lang->search->modules['execution'] = $lang->executionCommon;
$lang->search->modules['execution'] = $lang->execution->common;
$lang->search->modules['story'] = $lang->SRCommon;
$lang->search->modules['requirement'] = $lang->URCommon;
$lang->search->objectTypeList['story'] = $lang->SRCommon;
$lang->search->objectTypeList['requirement'] = $lang->URCommon;
$lang->search->objectTypeList['stage'] = 'stage';
$lang->search->objectTypeList['sprint'] = $lang->executionCommon;
$lang->search->objectTypeList['sprint'] = $lang->execution->common;
$lang->search->objectTypeList['kanban'] = 'kanban';
$lang->search->objectTypeList['commonIssue'] = 'Issue';
$lang->search->objectTypeList['stakeholderIssue'] = 'Stakeholder Issue';
+2 -2
View File
@@ -94,14 +94,14 @@ $lang->search->modules['testreport'] = 'Testing Report';
$lang->search->modules['productplan'] = 'Plan';
$lang->search->modules['program'] = 'Program';
$lang->search->modules['project'] = $lang->projectCommon;
$lang->search->modules['execution'] = $lang->executionCommon;
$lang->search->modules['execution'] = $lang->execution->common;
$lang->search->modules['story'] = $lang->SRCommon;
$lang->search->modules['requirement'] = $lang->URCommon;
$lang->search->objectTypeList['story'] = $lang->SRCommon;
$lang->search->objectTypeList['requirement'] = $lang->URCommon;
$lang->search->objectTypeList['stage'] = 'stage';
$lang->search->objectTypeList['sprint'] = $lang->executionCommon;
$lang->search->objectTypeList['sprint'] = $lang->execution->common;
$lang->search->objectTypeList['kanban'] = 'kanban';
$lang->search->objectTypeList['commonIssue'] = 'Issue';
$lang->search->objectTypeList['stakeholderIssue'] = 'Stakeholder Issue';
+2 -2
View File
@@ -94,14 +94,14 @@ $lang->search->modules['testreport'] = '测试报告';
$lang->search->modules['productplan'] = '计划';
$lang->search->modules['program'] = '项目集';
$lang->search->modules['project'] = $lang->projectCommon;
$lang->search->modules['execution'] = $lang->executionCommon;
$lang->search->modules['execution'] = $lang->execution->common;
$lang->search->modules['story'] = $lang->SRCommon;
$lang->search->modules['requirement'] = $lang->URCommon;
$lang->search->objectTypeList['story'] = $lang->SRCommon;
$lang->search->objectTypeList['requirement'] = $lang->URCommon;
$lang->search->objectTypeList['stage'] = '阶段';
$lang->search->objectTypeList['sprint'] = $lang->executionCommon;
$lang->search->objectTypeList['sprint'] = $lang->execution->common;
$lang->search->objectTypeList['kanban'] = '看板';
$lang->search->objectTypeList['commonIssue'] = '问题';
$lang->search->objectTypeList['stakeholderIssue'] = '干系人问题';
+1 -1
View File
@@ -59,7 +59,7 @@
<?php if(!empty($product->shadow)):?>
<td class='nobr' title="<?php echo $products[$story2Link->product]?>"><?php echo html::a($this->createLink('product', 'browse', "productID=$story2Link->product&branch=$story2Link->branch"), $products[$story2Link->product], '_blank');?></td>
<?php endif;?>
<td class='text-left nobr' title="<?php echo $story2Link->title?>"><?php echo html::a($storyLink, $story2Link->title);?></td>
<td class='text-left nobr' title="<?php echo $story2Link->title?>"><?php echo $story2Link->title;?></td>
<td><?php echo $this->processStatus('story', $story2Link);?></td>
<td><?php echo zget($users, $story2Link->openedBy);?></td>
<td><?php echo zget($users, $story2Link->assignedTo);?></td>
+1 -1
View File
@@ -21,7 +21,7 @@
#byTypeTab li.split{border-top: 1px solid #eee;}
</style>
<div id='mainMenu' class='clearfix'>
<?php if(!in_array($this->app->rawMethod, array('groupcase', 'browseunits'))):?>
<?php if($this->app->rawMethod == 'browse'):?>
<div id="sidebarHeader">
<div class="title">
<?php
+1 -1
View File
@@ -199,7 +199,7 @@ class upgrade extends control
$this->locate(inlink('afterExec', "fromVersion=$fromVersion"));
}
$this->view->result = 'fail';
$this->view->result = 'sqlFail';
$this->view->errors = $this->upgrade->getError();
$this->display();
}
+2 -1
View File
@@ -52,7 +52,8 @@ $lang->upgrade->upgradingTips = 'The upgrade is in progress, please be patient.
$lang->upgrade->forbiddenExt = 'Die Erweiterung ist nicht kompatibel mit der Upgradeversion. Sie wurde deaktiviert:';
$lang->upgrade->updateFile = 'Updateinformation wurden hinzugefügt.';
$lang->upgrade->noticeSQL = 'Your database is inconsistent with the standard and it failed to fix it. Please run the following SQL and refresh.';
$lang->upgrade->afterDeleted = 'File is not deleted. Please refresh after you delete it.';
$lang->upgrade->afterExec = 'Please modify the database manually according to the above error information, and refresh after the modification!';
$lang->upgrade->afterExec = 'Please manually modify the database according to the above error information, and refresh after modifiy!';
$lang->upgrade->mergeProgram = 'Data Merge';
$lang->upgrade->mergeTips = 'Data Migration Tips';
$lang->upgrade->toPMS15Guide = 'ZenTao open source version 15 upgrade';
+1
View File
@@ -53,6 +53,7 @@ $lang->upgrade->forbiddenExt = 'The extension is incompatible with the version
$lang->upgrade->updateFile = 'File information has to be updated.';
$lang->upgrade->noticeSQL = 'Your database is inconsistent with the standard and it failed to fix it. Please run the following SQL and refresh.';
$lang->upgrade->afterDeleted = 'Please execute commands to delete the files. Please refresh after you delete them.';
$lang->upgrade->afterExec = 'Please modify the database manually according to the above error information, and refresh after the modification!';
$lang->upgrade->mergeProgram = 'Data Merge';
$lang->upgrade->mergeTips = 'Data Migration Tips';
$lang->upgrade->toPMS15Guide = 'ZenTao open source version 15 upgrade';
+1
View File
@@ -53,6 +53,7 @@ $lang->upgrade->forbiddenExt = 'Cette extension est incompatible avec la versi
$lang->upgrade->updateFile = "Le fichier information a besoin d'une mise à jour.";
$lang->upgrade->noticeSQL = 'Votre base de donnée est inconsistente avec le standard et il y a eu un échec pour la corriger. Exécutez la commande SQL suivante et rafraichissez.';
$lang->upgrade->afterDeleted = "Le fichier n'est pas supprimé. Recommencez après l'avoir supprimé.";
$lang->upgrade->afterExec = 'Please modify the database manually according to the above error information, and refresh after the modification!';
$lang->upgrade->mergeProgram = 'Data Merge';
$lang->upgrade->mergeTips = 'Data Migration Tips';
$lang->upgrade->toPMS15Guide = 'ZenTao open source version 15 upgrade';
+1
View File
@@ -53,6 +53,7 @@ $lang->upgrade->forbiddenExt = '以下插件与新版本不兼容,已经自
$lang->upgrade->updateFile = '需要更新附件信息。';
$lang->upgrade->noticeSQL = '检查到你的数据库跟标准不一致,尝试修复失败。请执行以下SQL语句,再刷新页面检查。';
$lang->upgrade->afterDeleted = '请执行上面命令删除文件, 删除后刷新!';
$lang->upgrade->afterExec = '请根据以上报错信息手动修改数据库,修改后刷新!';
$lang->upgrade->mergeProgram = '数据迁移';
$lang->upgrade->mergeTips = '数据迁移提示';
$lang->upgrade->toPMS15Guide = '禅道开源版15版本升级';
+3 -3
View File
@@ -16,13 +16,13 @@
<strong><?php echo $lang->upgrade->result;?></strong>
</div>
<div class='modal-body'>
<?php if($result == 'fail'):?>
<?php if(in_array($result, array('fail', 'sqlFail'))):?>
<div class='alert alert-danger mgb-10'><strong><?php echo $lang->upgrade->fail?></strong></div>
<?php echo html::textarea('errors', join("\n", $errors), "rows='10' class='form-control' readonly");?>
<?php endif;?>
</div>
<?php if($result == 'fail'):?>
<div class='modal-footer text-left'><?php echo $lang->upgrade->afterDeleted;?> <?php echo html::a('#', $this->lang->refresh, '', "class='btn btn-sm' onclick='refreshPage(this)'");?></div>
<?php if(in_array($result, array('fail', 'sqlFail'))):?>
<div class='modal-footer text-left'><?php echo $result == 'sqlFail' ? $lang->upgrade->afterExec : $lang->upgrade->afterDeleted;?> <?php echo html::a('#', $this->lang->refresh, '', "class='btn btn-sm' onclick='refreshPage(this)'");?></div>
<?php endif;?>
</div>
</div>
+2 -2
View File
@@ -39,8 +39,8 @@ $devTester = new devTest();
r($devTester->getCustomedLangTest('test')) && p() && e("0"); // 错误的类型返回数据
r($devTester->getCustomedLangTest('common')) && p('productCommon') && e("测试1"); // 正确的类型返回数据
r($devTester->getCustomedLangTest('second', $failModule)) && p() && e("0"); // 正确的类型,错误的模块返回数据
r($devTester->getCustomedLangTest('second', $realModule)) && p('index') && e("测试2"); // 正确的类型,正确的模块返回数据
r($devTester->getCustomedLangTest('second', $failModule)) && p() && e("0"); // 正确的类型,错误的模块返回数据
r($devTester->getCustomedLangTest('second', $realModule)) && p('menu_index') && e("测试2"); // 正确的类型,正确的模块返回数据
r($devTester->getCustomedLangTest('tag', $realModule, $failMethod)) && p() && e("0"); // 正确的类型,正确的模块,错误的方法返回数据
r($devTester->getCustomedLangTest('tag', $realModule, $realMethod)) && p('featureBar-todo_all') && e("测试3"); // 正确的类型,正确的模块,正确的方法返回数据
+29
View File
@@ -0,0 +1,29 @@
#!/usr/bin/env php
<?php
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
include dirname(dirname(dirname(__FILE__))) . '/class/dev.class.php';
su('admin');
/**
title=测试 devModel::getTree();
cid=1
pid=1
测试传入空值的情况 >> 0
测试传入错误类型的情况 >> 0
测试获取type=module模块树,并检查高亮情况 >> my,1
测试获取type=table模块树,并检查高亮情况 >> my,1
*/
global $tester;
$tester->loadModel('dev');
$activeList = array('', 'index', 'zt_todo');
$typeList = array('', 'tree', 'module', 'table');
r($tester->dev->getTree($activeList[0], $typeList[0])) && p() && e('0'); // 测试传入空值的情况
r($tester->dev->getTree($activeList[0], $typeList[1])) && p() && e('0'); // 测试传入错误类型的情况
r($tester->dev->getTree($activeList[1], $typeList[2])) && p('0:key,active') && e('my,1'); // 测试获取type=module模块树,并检查高亮情况
r($tester->dev->getTree($activeList[2], $typeList[3])) && p('0:key,active') && e('my,1'); // 测试获取type=table模块树,并检查高亮情况

Some files were not shown because too many files have changed in this diff Show More