Merge branch 'master' into 'cyy_fixbug'

# Conflicts:
#   module/doc/view/lefttree.html.php
This commit is contained in:
王怡栋
2023-04-13 05:30:11 +00:00
182 changed files with 1338 additions and 558 deletions
+22 -9
View File
@@ -28,8 +28,8 @@ class hostHeartbeatEntry extends baseEntry
/* Check param. */
$status = $this->requestBody->status;
$vms = $this->requestBody->Vms;
$zap = $this->requestBody->port;
$vms = !empty($this->requestBody->Vms) ? $this->requestBody->Vms : array();
$zap = !empty($this->requestBody->port) ? $this->requestBody->port : 0;
$now = helper::now();
if(!$status) return $this->sendError(400, 'Params error.');
@@ -37,7 +37,7 @@ class hostHeartbeatEntry extends baseEntry
$conditionValue = $secret ? $secret : $token;
$this->dao = $this->loadModel('common')->dao;
$hostInfo = $this->dao->select('id,tokenSN')->from(TABLE_ZAHOST)
$hostInfo = $this->dao->select('id,tokenSN,hostType,type')->from(TABLE_ZAHOST)
->beginIF($secret)->where('secret')->eq($secret)->fi()
->beginIF(!$secret)->where('tokenSN')->eq($token)
->andWhere('tokenTime')->gt($now)->fi()
@@ -45,13 +45,15 @@ class hostHeartbeatEntry extends baseEntry
if(empty($hostInfo->id))
{
if(empty($token)) return $this->sendError(400, 'Secret error.');
$hostInfo = $this->dao->select('id,tokenSN')->from(TABLE_ZAHOST)
$hostInfo = $this->dao->select('id,tokenSN,hostType,type')->from(TABLE_ZAHOST)
->where('oldTokenSN')->eq($token)
->andWhere('tokenTime')->gt(date(DT_DATETIME1, strtotime($now) - 30))->fi()
->fetch();
if(empty($hostInfo->id)) return $this->sendError(400, 'Secret error.');
}
$isPhysicsNode = $hostInfo->type == 'node' && $hostInfo->hostType == 'physics' ? true : false;
$host = new stdclass();
$host->status = $status;
if($secret)
@@ -69,7 +71,7 @@ class hostHeartbeatEntry extends baseEntry
foreach($vms as $vm)
{
$heartbeat = strtotime(substr($vm->heartbeat, 0, 19));
$vmData = array(
$vmData = array(
'vnc' => $vm->vncPortOnHost,
'zap' => $vm->agentPortOnHost,
'ztf' => $vm->ztfPortOnHost,
@@ -80,14 +82,25 @@ class hostHeartbeatEntry extends baseEntry
);
if(!$vm->sshPortOnHost) unset($vmData['ssh']);
if($heartbeat > 0) $vmData['heartbeat'] = date("Y-m-d H:i:s", $heartbeat);
$this->dao->update(TABLE_ZAHOST)->data($vmData)->where('mac')->eq($vm->macAddress)->exec();
if($isPhysicsNode)
{
unset($vmData['extranet']);
$this->dao->update(TABLE_ZAHOST)->data($vmData)->where('id')->eq($hostInfo->id)->exec();
}
else
{
$node = $this->loadModel('zanode')->getNodeByMac($vm->macAddress);
if(empty($node)) continue;
if(in_array($node->status, array('restoring', 'creating_img', 'creating_snap')))
$vmData->status = $vm->status = $node->status;
$this->dao->update(TABLE_ZAHOST)->data($vmData)->where('mac')->eq($vm->macAddress)->exec();
}
if($vm->status == 'running')
if($vm->status == 'running' && !$isPhysicsNode)
{
$node = $this->loadModel('zanode')->getNodeByMac($vm->macAddress);
if(!empty($node))
{
$snaps = $this->loadModel('zanode')->getSnapshotList($node->id);
+8 -1
View File
@@ -31,6 +31,7 @@ class hostSubmitEntry extends baseEntry
$image = new stdclass();
$task = $this->requestBody->task;
$image->status = $this->requestBody->status;
$image->status == 'complete' && $image->status = "completed";
$this->dao = $this->loadModel('common')->dao;
$id = $this->dao->select('id')->from(TABLE_ZAHOST)
@@ -40,10 +41,11 @@ class hostSubmitEntry extends baseEntry
if(!$id) return $this->sendError(400, 'Secret error.');
$imageInfo = $this->dao->select('`status`,`from`', 'name')->from(TABLE_IMAGE)
$imageInfo = $this->dao->select('`status`,`from`,name,host')->from(TABLE_IMAGE)
->where('id')->eq($task)
->fetch();
if(empty($imageInfo)) return $this->sendSuccess(200, 'success');
if($imageInfo->from == 'snapshot' && $imageInfo->status == 'restoring')
{
if(in_array($image->status, array('failed', 'completed'))) $image->status = $image->status == 'completed' ? 'restore_completed' : 'restore_failed';
@@ -59,6 +61,11 @@ class hostSubmitEntry extends baseEntry
$this->dao->update(TABLE_IMAGE)->data($image)->where("id")->eq($task)->exec();
if($imageInfo->from != 'zentao' && in_array($imageInfo->status, array('creating', 'restoring')))
{
$this->dao->update(TABLE_ZAHOST)->data(array("status" => "wait"))->where("id")->eq($imageInfo->host)->exec();
}
return $this->sendSuccess(200, 'success');
}
}
+7 -2
View File
@@ -56,11 +56,16 @@ class testcaseEntry extends entry
$stepType = array();
if(isset($this->requestBody->steps))
{
foreach($this->requestBody->steps as $step)
foreach($this->requestBody->steps as $key => $step)
{
if(empty($step->type)) $step->type = 'step';
if(!in_array($step->type, array('step', 'item', 'group'))) $step->type = 'step';
if($step->type == 'group' && (empty($this->requestBody->steps[$key + 1]->type) || $this->requestBody->steps[$key + 1]->type != 'item')) $step->type = 'step';
$steps[] = $step->desc;
$expects[] = $step->expect;
$stepType[] = 'item';
$stepType[] = $step->type;
}
}
+4 -3
View File
@@ -33,9 +33,10 @@ class testcasesEntry extends entry
$param = $moduleID;
}
$this->app->cookie->caseModule = 0;
$this->app->cookie->caseSuite = 0;
$this->app->cookie->preBranch = $branch;
$this->app->cookie->caseModule = 0;
$this->app->cookie->caseSuite = 0;
$this->app->cookie->preBranch = $branch;
$this->app->cookie->showAutoCase = 1;
$control = $this->loadController('testcase', 'browse');
$control->browse($productID, $this->param('branch', ''), $type, $param, $this->param('caseType', ''), $this->param('order', 'id_desc'), 0, $this->param('limit', 20), $this->param('page', 1));
+1 -1
View File
@@ -21,7 +21,7 @@ class testsuiteEntry extends entry
public function get($testsuiteID)
{
$control = $this->loadController('testsuite', 'view');
$control->view($testsuiteID, $this->param('version', 0));
$control->view($testsuiteID, $this->param('order', 'id_desc'), 0, $this->param('limit', 20), $this->param('page', 1));
$data = $this->getData();
if(!$data or (isset($data->message) and $data->message == '404 Not found')) return $this->send404();
+1 -1
View File
@@ -24,7 +24,7 @@ class testsuitesEntry extends entry
if(empty($productID)) return $this->sendError(400, 'Need product id.');
$control = $this->loadController('testsuite', 'browse');
$control->browse($productID, $this->param('order', 'id_desc'), 0, $this->param('limit', 20), $this->param('page', 1));
$control->browse($productID, 'all', $this->param('order', 'id_desc'), 0, $this->param('limit', 20), $this->param('page', 1));
$data = $this->getData();
if(isset($data->status) and $data->status == 'success')
+18 -1
View File
File diff suppressed because one or more lines are too long
+15 -15
View File
@@ -323,7 +323,7 @@ CREATE TABLE IF NOT EXISTS `zt_bug` (
-- DROP TABLE IF EXISTS `zt_build`;
CREATE TABLE IF NOT EXISTS `zt_build` (
`id` mediumint(8) unsigned NOT NULL auto_increment,
`project` mediumint(8) unsigned NOT NULL,
`project` mediumint(8) unsigned NOT NULL default '0',
`product` mediumint(8) unsigned NOT NULL default '0',
`branch` varchar(255) NOT NULL DEFAULT '0',
`execution` mediumint(8) unsigned NOT NULL default '0',
@@ -358,9 +358,9 @@ CREATE TABLE IF NOT EXISTS `zt_burn` (
-- DROP TABLE IF EXISTS `zt_case`;
CREATE TABLE IF NOT EXISTS `zt_case` (
`id` mediumint(8) unsigned NOT NULL auto_increment,
`project` mediumint(8) unsigned NOT NULL,
`project` mediumint(8) unsigned NOT NULL default '0',
`product` mediumint(8) unsigned NOT NULL default '0',
`execution` mediumint(8) unsigned NOT NULL,
`execution` mediumint(8) unsigned NOT NULL default '0',
`branch` mediumint(8) unsigned NOT NULL default '0',
`lib` mediumint(8) unsigned NOT NULL default '0',
`module` mediumint(8) unsigned NOT NULL default '0',
@@ -661,13 +661,13 @@ CREATE TABLE IF NOT EXISTS `zt_doc` (
`path` char(255) NOT NULL DEFAULT '',
`grade` tinyint(3) unsigned NOT NULL DEFAULT '0',
`order` smallint(5) unsigned NOT NULL DEFAULT '0',
`views` smallint(5) unsigned NOT NULL,
`views` smallint(5) unsigned NOT NULL DEFAULT '0',
`assetLib` mediumint(8) unsigned NOT NULL DEFAULT '0',
`assetLibType` varchar(30) NOT NULL DEFAULT '',
`from` mediumint(8) unsigned NOT NULL DEFAULT '0',
`fromVersion` smallint(6) NOT NULL DEFAULT '1',
`draft` longtext NOT NULL,
`collector` text NOT NULL,
`collector` text NULL,
`addedBy` varchar(30) NOT NULL,
`addedDate` datetime NOT NULL,
`assignedTo` varchar(30) NOT NULL DEFAULT '',
@@ -985,8 +985,8 @@ CREATE TABLE IF NOT EXISTS `zt_kanbancard` (
`pri` mediumint(8) unsigned NOT NULL,
`assignedTo` text NOT NULL,
`desc` mediumtext NOT NULL,
`begin` date NOT NULL,
`end` date NOT NULL,
`begin` date NULL,
`end` date NULL,
`estimate` float unsigned NOT NULL,
`progress` float unsigned NOT NULL DEFAULT '0',
`color` char(7) NOT NULL,
@@ -1095,8 +1095,8 @@ CREATE TABLE IF NOT EXISTS `zt_module` (
`order` smallint(5) unsigned NOT NULL default '0',
`type` char(30) NOT NULL,
`from` mediumint(8) unsigned NOT NULL default '0',
`owner` varchar(30) NOT NULL,
`collector` text NOT NULL,
`owner` varchar(30) NOT NULL DEFAULT '',
`collector` text NULL,
`short` varchar(30) NOT NULL DEFAULT '',
`deleted` enum('0','1') NOT NULL default '0',
PRIMARY KEY (`id`),
@@ -1592,12 +1592,12 @@ CREATE TABLE IF NOT EXISTS `zt_story` (
`closedDate` datetime NULL,
`closedReason` varchar(30) NOT NULL DEFAULT '',
`activatedDate` datetime NULL,
`toBug` mediumint(8) unsigned NOT NULL,
`childStories` varchar(255) NOT NULL,
`linkStories` varchar(255) NOT NULL,
`linkRequirements` varchar(255) NOT NULL,
`twins` varchar(255) NOT NULL,
`duplicateStory` mediumint(8) unsigned NOT NULL,
`toBug` mediumint(8) unsigned NOT NULL DEFAULT '0',
`childStories` varchar(255) NOT NULL DEFAULT '',
`linkStories` varchar(255) NOT NULL DEFAULT '',
`linkRequirements` varchar(255) NOT NULL DEFAULT '',
`twins` varchar(255) NOT NULL DEFAULT '',
`duplicateStory` mediumint(8) unsigned NOT NULL DEFAULT '0',
`version` smallint(6) NOT NULL DEFAULT '1',
`storyChanged` enum('0','1') NOT NULL DEFAULT '0',
`feedbackBy` varchar(100) NOT NULL DEFAULT '',
+1 -1
View File
@@ -135,7 +135,7 @@ class dm extends dao
}
/* Format alias. */
if($alias and ctype_alnum($alias)) $alias = '"' . $alias . '"';
if($alias and !is_numeric($alias) and ctype_alnum($alias)) $alias = '"' . $alias . '"';
return $originField . ' ' . $alias;
}
+1 -1
View File
@@ -836,7 +836,7 @@ class gitlab
return array();
}
if($httpCode == 500) return array();
if($httpCode == 500 or $httpCode == 404) return array();
return json_decode($response);
}
}
+2 -2
View File
@@ -219,7 +219,7 @@ class blockModel extends model
->orWhere('t3.status')->ne('suspended')
->markRight(1)
->andWhere('t1.status')->in('wait,doing')
->andWhere('t1.deadline')->ne('0000-00-00')
->andWhere('t1.deadline')->notZeroDate()
->andWhere('t1.deadline')->lt($today)
->andWhere('t1.deleted')->eq(0)
->andWhere('t3.deleted')->eq(0)
@@ -228,7 +228,7 @@ class blockModel extends model
->leftJoin(TABLE_PRODUCT)->alias('t2')->on('t1.product=t2.id')
->where('t1.assignedTo')->eq($this->app->user->account)
->andWhere('t1.status')->eq('active')
->andWhere('t1.deadline')->ne('0000-00-00')
->andWhere('t1.deadline')->notZeroDate()
->andWhere('t1.deadline')->lt($today)
->andWhere('t1.deleted')->eq(0)
->andWhere('t2.deleted')->eq(0)
+2 -5
View File
@@ -414,11 +414,8 @@ class buildModel extends model
$build->bugs = '';
$build = fixer::input('post')
->setDefault('project', 0)
->setDefault('execution', 0)
->setDefault('product', 0)
->setDefault('branch', 0)
->setDefault('builds', '')
->setDefault('project,execution,product,branch', 0)
->setDefault('builds,stories,bugs', '')
->cleanInt('product')
->add('createdBy', $this->app->user->account)
->add('createdDate', helper::now())
+1 -1
View File
@@ -4,7 +4,7 @@ $lang->chart->query = 'Query';
$lang->chart->toDesign = 'To Design';
$lang->chart->group = 'Group';
$lang->chart->field = 'Field';
$lang->chart->field = 'Related Field';
$lang->chart->agg = 'Aggregate';
$lang->chart->chooseField = 'Choose field';
$lang->chart->aggType = 'Aggregate type';
+1 -1
View File
@@ -4,7 +4,7 @@ $lang->chart->query = 'Query';
$lang->chart->toDesign = 'To Design';
$lang->chart->group = 'Group';
$lang->chart->field = 'Field';
$lang->chart->field = 'Related Field';
$lang->chart->agg = 'Aggregate';
$lang->chart->chooseField = 'Choose field';
$lang->chart->aggType = 'Aggregate type';
+1 -1
View File
@@ -4,7 +4,7 @@ $lang->chart->query = 'Query';
$lang->chart->toDesign = 'To Design';
$lang->chart->group = 'Group';
$lang->chart->field = 'Field';
$lang->chart->field = 'Related Field';
$lang->chart->agg = 'Aggregate';
$lang->chart->chooseField = 'Choose field';
$lang->chart->aggType = 'Aggregate type';
+1 -1
View File
@@ -489,7 +489,7 @@ $lang->devops->menu->set['subMenu']->repo = array('link' => "{$lang->devops
$lang->devops->menu->set['subMenu']->gitlab = array('link' => 'GitLab|gitlab|browse', 'subModule' => 'gitlab');
$lang->devops->menu->set['subMenu']->gogs = array('link' => 'Gogs|gogs|browse', 'subModule' => 'gogs');
$lang->devops->menu->set['subMenu']->gitea = array('link' => 'Gitea|gitea|browse', 'subModule' => 'gitea');
$lang->devops->menu->set['subMenu']->jenkins = array('link' => 'Jenkins|jenkins|browse', 'subModule' => '');
$lang->devops->menu->set['subMenu']->jenkins = array('link' => 'Jenkins|jenkins|browse', 'subModule' => 'jenkins');
$lang->devops->menu->set['subMenu']->sonarqube = array('link' => 'SonarQube|sonarqube|browse', 'subModule' => 'sonarqube');
$lang->devops->menu->set['subMenu']->setrules = array('link' => "{$lang->devops->rules}|repo|setrules");
+5 -4
View File
@@ -412,14 +412,15 @@ class doc extends control
{
$excludedModel = $this->config->vision == 'lite' ? '' : 'kanban';
$objects = $this->project->getPairsByProgram('', 'all', false, 'order_asc', $excludedModel);
$this->view->executions = array();
if($lib->type == 'execution')
{
$execution = $this->loadModel('execution')->getById($lib->execution);
$objectID = $execution->project;
$libs = $this->doc->getLibs('execution', $extra = "withObject,$unclosed", $libID, $lib->execution);
$this->view->execution = $execution;
$this->view->execution = $execution;
$this->view->executions = array(0 => '') + $this->execution->getPairs($objectID, 'sprint,stage', 'multiple,leaf,noprefix');
}
$this->view->executions = array(0 => '') + $this->loadModel('execution')->getPairs($objectID, 'sprint,stage', 'multiple,leaf,noprefix');
}
elseif($linkType == 'execution')
{
@@ -1210,13 +1211,13 @@ class doc extends control
$methodName = 'mySpace';
}
$crumbs[] = html::a(inLink($methodName, $linkParams), html::image("static/svg/wiki-file-lib.svg") . $lib->name);
$crumbs[] = html::a(inLink($methodName, $linkParams), html::image("static/svg/wiki-file-lib.svg") . $lib->name, '', 'title =' . $lib -> name);
$moduleList = $this->loadModel('tree')->getParents($doc->module);
foreach($moduleList as $module)
{
$withModuleParams = $linkParams . "&moduleID=$module->id";
$crumbs[] = html::a(inLink($methodName, $withModuleParams), $module->name);
$crumbs[] = html::a(inLink($methodName, $withModuleParams), $module->name . '&nbsp', '', 'title =' . $module->name);
}
$spaceType = $objectType . 'Space';
+3 -2
View File
@@ -104,8 +104,9 @@ ol, ul {margin-bottom: 0}
#subHeader .list-group>a.selected {color: #e9f2fb !important;}
#pageNav #dropMenu .table-col .list-group .icon-move {display:block; float: left; font-size: 12px; padding: 3px 4px 3px 1px;}
#content .detail-content.article-content {overflow-y: auto; height: calc(100vh - 300px);}
#content .detail-content.article-content {overflow-y: auto; height: calc(100vh - 200px);}
#aclBox .acl-tip {color: #838a9d;}
.ajaxCollect > img.star-empty {margin-right: 0px;}
#outlineMenu {background: #fff; position: absolute; height: calc(100vh - 200px)!important; overflow-y: auto; top: 50px; right: 20px;}
#outlineMenu {background: #fff; position: absolute; height: calc(100vh - 180px)!important; overflow-y: auto; top: 50px; right: 25px;}
.pl-0px {padding-left:0px !important;}
.icon {cursor: pointer;}
+4 -1
View File
@@ -63,10 +63,13 @@
.info .version, .info .crumbs {float: left;}
.crumbs img {margin-right: 3px; margin-bottom: 4px;}
.crumbs {float: left; display: flex;height: 32px; width: 670px; align-items: center; overflow: hidden;}
.crumbs {float: left; display: flex;height: 32px; width: 640px; align-items: center; overflow: hidden;}
.crumbs .crumb-item {padding: 6px 2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; flex: none; display: flex;}
.crumb-item .separator {flex: 0 0 15px; display: flex; justify-content: center; align-items: center;}
.crumb-item a {flex: none}
.main-col {position: relative;}
#autoBox {display: flex; overflow: hidden; text-overflow: ellipsis; padding-right: 15px; position: relative;}
#autoBox > .ellipsis {position: absolute; top: 3px; right: 0; width: 10px; background: #F4F5F7; height: 100%;}
.detail+.detail {padding-top: 0;}
.comment-edit-form .form-actions {display: flex;}
+10 -4
View File
@@ -29,7 +29,12 @@ function loadObjectModules(objectType, objectID, docType)
function loadExecutions(projectID)
{
var link = createLink('project', 'ajaxGetExecutions', "projectID=" + projectID + "&executionID=0&mode=multiple,leaf,noprefix&type=sprint,stage");
$('#executionBox').load(link, function(){$('#executionBox').find('select').attr('data-placeholder', holders.execution).attr('onchange', "loadObjectModules('execution', this.value)").picker()});
$('#executionBox').load(link, function()
{
var $extension = $('#executionBox').find('select');
$extension.attr('data-placeholder', holders.execution).attr('onchange', "loadObjectModules('execution', this.value)").picker();
if($extension.hasClass('disabled')) $('#executionBox').find('.picker').addClass('disabled');
});
loadObjectModules('project', projectID);
}
@@ -421,9 +426,10 @@ function updateCrumbs()
if(widthSum >= crumbMaxWidth)
{
$(crumbItem).addClass('in-auto-box');
var $autoCrumbItems = $('#crumbs > .in-auto-box');
$lastChild.before('<div id="autoBox" class="flex-auto"><div class="ellipsis">...<div></div>');
$('#autoBox').prepend($autoCrumbItems);
return;
}
}
var $autoCrumbItems = $('#crumbs > .in-auto-box');
$lastChild.before('<div id="autoBox" class="flex-auto"><div class="ellipsis">...<div></div>');
$('#autoBox').prepend($autoCrumbItems);
}
+1
View File
@@ -6,6 +6,7 @@ $(function()
setTimeout(function(){$('.CodeMirror').height($(document).height() - 112);}, 100);
$('iframe.ke-edit-iframe').contents().find('.article-content').css('padding', '20px 20px 0 20px');
if(objectType == 'project') loadExecutions($('#project').val());
setSavePath();
/* Change for show create error. */
+15 -8
View File
@@ -141,21 +141,24 @@ $(function()
$('.outline').height($('.article-content').height());
$('body').on('click', '.outline-toggle i.icon-angle-right', function()
$('body').on('click', '.outline-toggle i.icon-menu-arrow-left', function()
{
$('.outline').css({'min-width' : '180px', 'border-left' : '2px solid #efefef'});
$(this).removeClass('icon-angle-right').addClass('icon-angle-left').css('left', '-9px');
$(this).removeClass('icon-menu-arrow-left').addClass('icon-menu-arrow-right').css('left', '-9px');
$('.outline-content').show();
if($('#sidebar>.cell').is(':visible')) $('#sidebar .icon.icon-angle-right').trigger("click");
}).on('click', '.outline-toggle i.icon-angle-left', function()
if($('#sidebar>.cell').is(':visible')) $('#sidebar .icon.icon-menu-arrow-right').trigger("click");
}).on('click', '.outline-toggle i.icon-menu-arrow-right', function()
{
$(this).removeClass('icon-angle-left').addClass('icon-angle-right');
$(this).removeClass('icon-menu-arrow-right').addClass('icon-menu-arrow-left');
$('.outline').css({'min-width' : '180px', 'border-left' : 'none'});
$('.outline-content').hide();
}).on('click', '#outline li', function(e)
{
$('#outline li.active').removeClass('active');
$(e.target).closest('li').addClass('active');
}).on('click', '.comment-edit-form .btn-hide-form', function()
{
$('.comment-edit-form #submit').attr('disabled', false);
});
$('#outline li.has-list').addClass('open in');
@@ -190,15 +193,14 @@ $(function()
});
})
$('#sidebar .icon.icon-angle-right').click(function()
$('#sidebar .icon.icon-menu-arrow-left').click(function()
{
if($('#sidebar>.cell').is(':hidden') && $('.outline-content').is(':visible'))
{
$('.outline .outline-toggle i.icon-angle-left').trigger("click");
$('.outline .outline-toggle i.icon-menu-arrow-right').trigger("click");
}
})
$('.outline .outline-toggle i.icon-angle-right').trigger("click");
$('#history').append('<a id="closeBtn" href="###" class="btn btn-link"><i class="icon icon-close"></i></a>');
$('#hisTrigger').on('click', function()
{
@@ -226,4 +228,9 @@ $(function()
$('#hisTrigger').removeClass('text-primary');
})
$('#history').find('.btn.pull-right').removeClass('pull-right');
if($('.files-list').length)
{
$('#content .detail-content.article-content').css('height', 'calc(100vh - 300px)');
}
$('.outline .outline-toggle i.icon-menu-arrow-left').trigger("click");
})
+2 -1
View File
@@ -852,7 +852,7 @@ class docModel extends model
$now = helper::now();
$doc = fixer::input('post')
->callFunc('title', 'trim')
->setDefault('content', '')
->setDefault('content,template,templateType,chapterType', '')
->add('addedBy', $this->app->user->account)
->add('addedDate', $now)
->add('editedBy', $this->app->user->account)
@@ -891,6 +891,7 @@ class docModel extends model
$docContent->title = $doc->title;
$docContent->content = $doc->contentType == 'html' ? $doc->content : $doc->contentMarkdown;
$docContent->type = $doc->contentType;
$docContent->digest = '';
$docContent->version = 1;
unset($doc->contentMarkdown, $doc->contentType, $doc->url);
+1 -1
View File
@@ -158,7 +158,7 @@
<?php echo $outline;?>
</div>
</div>
<div class="outline-toggle"><i class="icon icon-angle-right"></i></div>
<div class="outline-toggle"><i class="icon icon-menu-arrow-left"></i></div>
<?php endif;?>
<div id="history" class='panel hidden' style="margin-left: 2px;">
<?php
+1
View File
@@ -149,6 +149,7 @@
</div>
<?php js::set('textType', $config->doc->textTypes);?>
<?php js::set('docType', $docType);?>
<?php js::set('objectType', $objectType);?>
<?php js::set('holders', $lang->doc->placeholder);?>
<?php js::set('type', 'doc');?>
<?php js::set('requiredFields', ',' . $config->doc->create->requiredFields . ',');?>
+1 -1
View File
@@ -24,7 +24,7 @@
.tree-icon {position: absolute; right: 0;}
.tree li.has-input {overflow: hidden;}
.tree li.has-input > input.input-bro {margin-left: 15px;}
.img-lib {flex: 0 0 14px; height: 14px; margin-right: 5px; margin-bottom: 2px;}
.img-lib {flex: 0 0 14px; height: 14px; margin-right: 5px; margin-bottom: 5px;}
.file-icon {width: 14px;}
.tree-icon {position: absolute; right: 0;}
.tree li > a {max-width: 100%; padding: 2px;}
+1 -1
View File
@@ -29,7 +29,7 @@
<div id="crumbs" class="crumbs">
<?php foreach($crumbs as $crumbKey => $crumb):?>
<div class="crumb-item">
<?php if($crumbKey != 0) echo '<div class="separator"> > </div>'?>
<?php if($crumbKey != 0) echo '<div class="separator">> </div>'?>
<?php echo $crumb;?>
</div>
<?php endforeach;?>
+2
View File
@@ -0,0 +1,2 @@
.main-content>.center-block {max-width: 800px;}
#giteaForm table {width: 600px;}
-1
View File
@@ -22,7 +22,6 @@
<tr>
<th><?php echo $lang->gitea->name;?></th>
<td class='required'><?php echo html::input('name', '', "class='form-control'");?></td>
<td class="tips-git"></td>
</tr>
<tr>
<th><?php echo $lang->gitea->url;?></th>
+26 -5
View File
@@ -132,7 +132,7 @@ class gitlab extends control
* @access public
* @return void
*/
public function bindUser($gitlabID)
public function bindUser($gitlabID, $type = 'all')
{
$userPairs = $this->loadModel('user')->getPairs('noclosed|noletter');
@@ -140,7 +140,7 @@ class gitlab extends control
$user = $this->gitlab->apiGetCurrentUser($gitlab->url, $gitlab->token);
if(!isset($user->is_admin) or !$user->is_admin) return print(js::alert($this->lang->gitlab->tokenLimit) . js::locate($this->createLink('gitlab', 'edit', array('gitlabID' => $gitlabID))));
$zentaoUsers = $this->dao->select('account,email,realname')->from(TABLE_USER)->fetchAll('account');
$zentaoUsers = $this->dao->select('account,email,realname')->from(TABLE_USER)->where('deleted')->eq('0')->fetchAll('account');
if($_POST)
{
@@ -188,11 +188,32 @@ class gitlab extends control
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => $this->server->http_referer));
}
$gitlabUsers = $this->gitlab->apiGetUsers($gitlabID);
$bindedUsers = $this->gitlab->getUserAccountIdPairs($gitlabID);
$matchedResult = $this->gitlab->getMatchedUsers($gitlabID, $gitlabUsers, $zentaoUsers);
$matchedResult = array_column(json_decode(json_encode($matchedResult), true), null, "email");
$gitlabUsers = array_filter($gitlabUsers, function($item) use($bindedUsers, $userPairs, $type)
{
if($type == 'all') return true;
if(in_array($item->id, $bindedUsers))
{
$zentaoAccount = isset($item->zentaoAccount) ? zget($userPairs, $item->zentaoAccount, '') : '';
return $type == 'binded' ? !empty($zentaoAccount) : empty($zentaoAccount);
}
return $type == 'binded' ? false : true;
});
$this->view->title = $this->lang->gitlab->bindUser;
$this->view->zentaoUsers = $zentaoUsers;
$this->view->userPairs = $userPairs;
$this->view->gitlabUsers = $this->gitlab->apiGetUsers($gitlabID);
$this->view->bindedUsers = $this->gitlab->getUserAccountIdPairs($gitlabID);
$this->view->matchedResult = $this->gitlab->getMatchedUsers($gitlabID, $this->view->gitlabUsers, $zentaoUsers);
$this->view->type = $type;
$this->view->gitlabID = $gitlabID;
$this->view->gitlabUsers = $gitlabUsers;
$this->view->bindedUsers = $bindedUsers;
$this->view->matchedResult = $matchedResult;
$this->display();
}
+7
View File
@@ -1,2 +1,9 @@
#publicTip {padding-left: 10px;}
.table-form>tbody>tr>th {width: 110px;}
.gitlab-bind .btn-info{background-color: unset;color:unset;padding: 6px 6px;}
.gitlab-bind .btn-info.active{color: #2e7fff;background-color: rgba(239,239,239,.8);
border-color: rgba(0,0,0,0);}
.gitlab-bind-all{padding: 1px 6px;margin-left: 5px;border-radius: 10px;background: white;}
.img-circle {border-radius: 50%;}
.gitlab-account-desc{color: #9EA3B0;font-size: 12px;}
.gitlab-user-select .chosen-container{max-width: 200px;}
+2
View File
@@ -0,0 +1,2 @@
.main-content>.center-block {max-width: 800px;}
#gitlabForm table {width: 600px;}
+11
View File
@@ -0,0 +1,11 @@
$(document).ready(function()
{
$('.gitlab-user-bind').change(function()
{
var user = zentaoUsers[$(this).val()];
if(user !== undefined)
{
$(this).parent().parent().find('.email').text(user.email)
}
});
});
+5 -2
View File
@@ -5,7 +5,7 @@ $lang->gitlab->search = 'Search';
$lang->gitlab->create = 'Create GitLab';
$lang->gitlab->edit = 'Edit GitLab';
$lang->gitlab->view = 'View GitLab';
$lang->gitlab->bindUser = 'Bind User';
$lang->gitlab->bindUser = 'Permission Setting';
$lang->gitlab->webhook = 'Webhook';
$lang->gitlab->bindProduct = "Import {$lang->productCommon}";
$lang->gitlab->importIssue = 'Import Issue';
@@ -13,9 +13,12 @@ $lang->gitlab->delete = 'Delete GitLab';
$lang->gitlab->confirmDelete = 'Do you want to delete this GitLab server?';
$lang->gitlab->gitlabAvatar = 'Avatar';
$lang->gitlab->gitlabAccount = 'GitLab Account';
$lang->gitlab->gitlabEmail = 'Email';
$lang->gitlab->gitlabEmail = 'GitLab User\'s Email';
$lang->gitlab->zentaoEmail = 'Zentao User\'s Email';
$lang->gitlab->zentaoAccount = 'Zentao Account';
$lang->gitlab->accountDesc = '(Automatically match users with the same email)';
$lang->gitlab->bindingStatus = 'Binding Status';
$lang->gitlab->all = 'All';
$lang->gitlab->notBind = 'Not bind';
$lang->gitlab->binded = 'Binded';
$lang->gitlab->bindedError = 'The bound user has been deleted or modified. Please bind again.';
+5 -2
View File
@@ -5,7 +5,7 @@ $lang->gitlab->search = 'Search';
$lang->gitlab->create = 'Create GitLab';
$lang->gitlab->edit = 'Edit GitLab';
$lang->gitlab->view = 'View GitLab';
$lang->gitlab->bindUser = 'Bind User';
$lang->gitlab->bindUser = 'Permission Setting';
$lang->gitlab->webhook = 'Webhook';
$lang->gitlab->bindProduct = "Import {$lang->productCommon}";
$lang->gitlab->importIssue = 'Import Issue';
@@ -13,9 +13,12 @@ $lang->gitlab->delete = 'Delete GitLab';
$lang->gitlab->confirmDelete = 'Do you want to delete this GitLab server?';
$lang->gitlab->gitlabAvatar = 'Avatar';
$lang->gitlab->gitlabAccount = 'GitLab Account';
$lang->gitlab->gitlabEmail = 'Email';
$lang->gitlab->gitlabEmail = 'GitLab User\'s Email';
$lang->gitlab->zentaoEmail = 'Zentao User\'s Email';
$lang->gitlab->zentaoAccount = 'Zentao Account';
$lang->gitlab->accountDesc = '(Automatically match users with the same email)';
$lang->gitlab->bindingStatus = 'Binding Status';
$lang->gitlab->all = 'All';
$lang->gitlab->notBind = 'Not bind';
$lang->gitlab->binded = 'Binded';
$lang->gitlab->bindedError = 'The bound user has been deleted or modified. Please bind again.';
+5 -2
View File
@@ -5,7 +5,7 @@ $lang->gitlab->search = 'Search';
$lang->gitlab->create = 'Create GitLab';
$lang->gitlab->edit = 'Edit GitLab';
$lang->gitlab->view = 'View GitLab';
$lang->gitlab->bindUser = 'Bind User';
$lang->gitlab->bindUser = 'Permission Setting';
$lang->gitlab->webhook = 'Webhook';
$lang->gitlab->bindProduct = "Import {$lang->productCommon}";
$lang->gitlab->importIssue = 'Import Issue';
@@ -13,9 +13,12 @@ $lang->gitlab->delete = 'Delete GitLab';
$lang->gitlab->confirmDelete = 'Do you want to delete this GitLab server?';
$lang->gitlab->gitlabAvatar = 'Avatar';
$lang->gitlab->gitlabAccount = 'GitLab Account';
$lang->gitlab->gitlabEmail = 'Email';
$lang->gitlab->gitlabEmail = 'GitLab User\'s Email';
$lang->gitlab->zentaoEmail = 'Zentao User\'s Email';
$lang->gitlab->zentaoAccount = 'Zentao Account';
$lang->gitlab->accountDesc = '(System will automatically match users with the same email address)';
$lang->gitlab->bindingStatus = 'Binding Status';
$lang->gitlab->all = 'All';
$lang->gitlab->notBind = 'Not bind';
$lang->gitlab->binded = 'Binded';
$lang->gitlab->bindedError = 'The bound user has been deleted or modified. Please bind again.';
+4 -1
View File
@@ -13,9 +13,12 @@ $lang->gitlab->delete = 'Delete GitLab';
$lang->gitlab->confirmDelete = 'Do you want to delete this GitLab server?';
$lang->gitlab->gitlabAvatar = 'Avatar';
$lang->gitlab->gitlabAccount = 'GitLab Account';
$lang->gitlab->gitlabEmail = 'Email';
$lang->gitlab->gitlabEmail = 'GitLab User\'s Email';
$lang->gitlab->zentaoEmail = 'Zentao User\'s Email';
$lang->gitlab->zentaoAccount = 'Zentao Account';
$lang->gitlab->accountDesc = '(System will automatically match users with the same email address)';
$lang->gitlab->bindingStatus = 'Binding Status';
$lang->gitlab->all = 'All';
$lang->gitlab->notBind = 'Not bind';
$lang->gitlab->binded = 'Binded';
$lang->gitlab->bindedError = 'The bound user has been deleted or modified. Please bind again.';
+5 -2
View File
@@ -5,7 +5,7 @@ $lang->gitlab->search = '搜索';
$lang->gitlab->create = '添加GitLab';
$lang->gitlab->edit = '编辑GitLab';
$lang->gitlab->view = '查看GitLab';
$lang->gitlab->bindUser = '绑定用户';
$lang->gitlab->bindUser = '权限设置';
$lang->gitlab->webhook = 'Webhook';
$lang->gitlab->bindProduct = "关联{$lang->productCommon}";
$lang->gitlab->importIssue = '关联issue';
@@ -13,9 +13,12 @@ $lang->gitlab->delete = '删除GitLab';
$lang->gitlab->confirmDelete = '确认删除该GitLab吗?';
$lang->gitlab->gitlabAvatar = '头像';
$lang->gitlab->gitlabAccount = 'GitLab用户';
$lang->gitlab->gitlabEmail = '邮箱';
$lang->gitlab->gitlabEmail = 'GitLab用户邮箱';
$lang->gitlab->zentaoEmail = '禅道用户邮箱';
$lang->gitlab->zentaoAccount = '禅道用户';
$lang->gitlab->accountDesc = '(系统会将相同邮箱地址的用户自动匹配)';
$lang->gitlab->bindingStatus = '绑定状态';
$lang->gitlab->all = '全部';
$lang->gitlab->notBind = '未绑定';
$lang->gitlab->binded = '已绑定';
$lang->gitlab->bindedError = '绑定的用户已删除或者已修改,请重新绑定';
+2
View File
@@ -13,7 +13,9 @@ $lang->gitlab->delete = '刪除GitLab';
$lang->gitlab->confirmDelete = '確認刪除該GitLab嗎?';
$lang->gitlab->gitlabAccount = 'GitLab用戶';
$lang->gitlab->zentaoAccount = '禪道用戶';
$lang->gitlab->accountDesc = '(系統會將相同郵箱地址的用戶自動匹配)';
$lang->gitlab->bindingStatus = '綁定狀態';
$lang->gitlab->all = '全部';
$lang->gitlab->binded = '已綁定';
$lang->gitlab->bindedError = '綁定的用戶已刪除或者已修改,請重新綁定';
$lang->gitlab->serverFail = '連接GitLab伺服器異常,請檢查GitLab伺服器。';
+22
View File
@@ -1034,6 +1034,28 @@ class gitlabModel extends model
return $this->projects[$gitlabID][$projectID];
}
/**
* Multi get projects by repos.
*
* @param object $repos
* @access public
* @return void
*/
public function apiMultiGetProjects($repos)
{
$requests = array();
foreach($repos as $id => $repo)
{
$requests[$id]['url'] = sprintf($this->getApiRoot($repo->serviceHost, false), "/projects/{$repo->serviceProject}");
}
$this->app->loadClass('requests', true);
$results = requests::request_multiple($requests);
foreach($results as $id => $result)
{
if(!empty($result->body) and substr($result->body, 0, 1) == '{') $this->projects[$repos[$id]->serviceHost][$repos[$id]->serviceProject] = json_decode($result->body);
}
}
/**
* Get single user by API.
*
+42 -18
View File
@@ -11,19 +11,45 @@
*/
?>
<?php include '../../common/view/header.html.php';?>
<?php $browseLink = $this->createLink('gitlab', 'browse', ""); ?>
<?php js::set('zentaoUsers', $zentaoUsers);?>
<div id="mainContent" class="main-content">
<div class="main-header">
<h2><?php echo $lang->gitlab->bindUser;?></h2>
<div class="main-header gitlab-bind">
<?php
echo html::linkButton('<i class="icon icon-back icon-sm"></i> ' . $lang->goback, $browseLink, 'self', "data-app='{$app->tab}'", 'btn btn-secondary');
$allLink = $this->createLink('gitlab', 'binduser', "gitlabID={$gitlabID}&type=all");
$bindedLink = $this->createLink('gitlab', 'binduser', "gitlabID={$gitlabID}&type=binded");
$notBindLink = $this->createLink('gitlab', 'binduser', "gitlabID={$gitlabID}&type=notBind");
if($type == 'all')
{
echo html::linkButton('' . $lang->gitlab->all . "<span class='gitlab-bind-all'>" . count($gitlabUsers) . "</span>", $allLink, 'self', "data-app='{$app->tab}'", 'btn btn-info active');
echo html::linkButton('' . $lang->gitlab->notBind, $notBindLink, 'self', "data-app='{$app->tab}'", 'btn btn-info');
echo html::linkButton('' . $lang->gitlab->binded, $bindedLink, 'self', "data-app='{$app->tab}'", 'btn btn-info');
}
else if($type == 'binded')
{
echo html::linkButton('' . $lang->gitlab->all, $allLink, 'self', "data-app='{$app->tab}'", 'btn btn-info');
echo html::linkButton('' . $lang->gitlab->notBind, $notBindLink, 'self', "data-app='{$app->tab}'", 'btn btn-info');
echo html::linkButton('' . $lang->gitlab->binded . "<span class='gitlab-bind-all'>" . count($gitlabUsers) . "</span>", $bindedLink, 'self', "data-app='{$app->tab}'", 'btn btn-info active');
}
else
{
echo html::linkButton('' . $lang->gitlab->all, $allLink, 'self', "data-app='{$app->tab}'", 'btn btn-info');
echo html::linkButton('' . $lang->gitlab->notBind . "<span class='gitlab-bind-all'>" . count($gitlabUsers) . "</span>", $notBindLink, 'self', "data-app='{$app->tab}'", 'btn btn-info active');
echo html::linkButton('' . $lang->gitlab->binded, $bindedLink, 'self', "data-app='{$app->tab}'", 'btn btn-info');
}
?>
</div>
<form method='post' class='load-indicator main-form form-ajax' enctype='multipart/form-data'>
<div class="table-responsive">
<table class="table table-borderless w-800px">
<table class="table table-borderless">
<thead>
<tr>
<th class='w-60px'><?php echo $lang->gitlab->gitlabAvatar;?></th>
<th><?php echo $lang->gitlab->gitlabAccount;?></th>
<th><?php echo $lang->gitlab->gitlabEmail;?></th>
<th class='w-150px'><?php echo $lang->gitlab->zentaoAccount;?></th>
<th><?php echo $lang->gitlab->zentaoEmail;?></th>
<th class="w-400px"><?php echo $lang->gitlab->zentaoAccount;?> <span class="gitlab-account-desc"><?php echo $lang->gitlab->accountDesc;?></span></th>
<th><?php echo $lang->gitlab->bindingStatus;?></th>
</tr>
</thead>
@@ -32,29 +58,27 @@
<?php if(isset($gitlabUser->zentaoAccount)) continue;?>
<?php echo html::hidden("gitlabUserNames[$gitlabUser->id]", $gitlabUser->realname);?>
<tr>
<td><?php echo html::image($gitlabUser->avatar, "height=40");?></td>
<td class='text-left'>
<strong><?php echo $gitlabUser->realname;?></strong>
<br>
<?php echo $gitlabUser->account;?>
<td>
<?php echo html::image($gitlabUser->avatar, "height=20 width=20 class='img-circle'");?>
<?php echo $gitlabUser->realname . '@' . $gitlabUser->account;?>
</td>
<td><?php echo $gitlabUser->email;?></td>
<td><?php echo html::select("zentaoUsers[$gitlabUser->id]", $userPairs, '', "class='form-control select chosen'" );?></td>
<td><?php echo $lang->gitlab->notBind;?></td>
<td class="email"><?php echo !empty($matchedResult[$gitlabUser->email]) ? $matchedResult[$gitlabUser->email]['email'] : '';?></td>
<td class='gitlab-user-select'><?php echo html::select("zentaoUsers[$gitlabUser->id]", $userPairs, '', "class='form-control select chosen gitlab-user-bind'" );?></td>
<td><?php echo '<span class="text-red">' . $lang->gitlab->notBind . '</span>';?></td>
</tr>
<?php endforeach;?>
<?php foreach($gitlabUsers as $gitlabUser):?>
<?php if(!isset($gitlabUser->zentaoAccount)) continue;?>
<?php echo html::hidden("gitlabUserNames[$gitlabUser->id]", $gitlabUser->realname);?>
<tr>
<td><?php echo html::image($gitlabUser->avatar, "height=40");?></td>
<td>
<strong><?php echo $gitlabUser->realname;?></strong>
<br>
<?php echo $gitlabUser->account;?>
<?php echo html::image($gitlabUser->avatar, "height=20 width=20 class='img-circle'");?>
<?php echo $gitlabUser->realname . '@' . $gitlabUser->account;?>
</td>
<td><?php echo $gitlabUser->email;?></td>
<td><?php echo html::select("zentaoUsers[$gitlabUser->id]", $userPairs, $gitlabUser->zentaoAccount, "class='form-control select chosen'" );?></td>
<td class="email"><?php echo !empty($matchedResult[$gitlabUser->email]) ? $matchedResult[$gitlabUser->email]['email'] : '';?></td>
<td class='gitlab-user-select'><?php echo html::select("zentaoUsers[$gitlabUser->id]", $userPairs, $gitlabUser->zentaoAccount, "class='form-control select chosen gitlab-user-bind'" );?></td>
<td>
<?php if(in_array($gitlabUser->id, $bindedUsers)):?>
<?php $zentaoAccount = zget($userPairs, $gitlabUser->zentaoAccount, '');?>
@@ -64,7 +88,7 @@
<?php echo '<span class="text-red">' . $lang->gitlab->bindedError . '</span>';?>
<?php endif;?>
<?php else:?>
<?php echo $lang->gitlab->notBind;?>
<?php echo '<span class="text-red">' . $lang->gitlab->notBind . '</span>';?>
<?php endif;?>
</td>
</tr>
+1 -1
View File
@@ -56,7 +56,7 @@
<td class='c-actions'>
<?php
common::printIcon('gitlab', 'edit', "gitlabID=$id", '', 'list', 'edit');
echo common::buildIconButton('gitlab', 'bindUser', "gitlabID=$id", '', 'list', 'link');
echo common::buildIconButton('gitlab', 'bindUser', "gitlabID=$id", '', 'list', 'lock');
common::printIcon('gitlab', 'delete', "gitlabID=$id", '', 'list', 'trash', 'hiddenwin');
?>
</td>
-1
View File
@@ -23,7 +23,6 @@
<tr>
<th><?php echo $lang->gitlab->name;?></th>
<td class='required'><?php echo html::input('name', '', "class='form-control' placeholder='{$lang->gitlab->placeholder->name}'");?></td>
<td class="tips-git"></td>
</tr>
<tr>
<th><?php echo $lang->gitlab->url;?></th>
+2
View File
@@ -0,0 +1,2 @@
.main-content>.center-block {max-width: 800px;}
#gogsForm table {width: 600px;}
-1
View File
@@ -22,7 +22,6 @@
<tr>
<th><?php echo $lang->gogs->name;?></th>
<td class='required'><?php echo html::input('name', '', "class='form-control'");?></td>
<td class="tips-git"></td>
</tr>
<tr>
<th><?php echo $lang->gogs->url;?></th>
+21 -19
View File
@@ -1305,26 +1305,28 @@ $lang->resource->repo->linkStory = 'linkStory';
$lang->resource->repo->linkBug = 'linkBug';
$lang->resource->repo->linkTask = 'linkTask';
$lang->resource->repo->unlink = 'unlink';
$lang->resource->repo->import = 'importAction';
$lang->repo->methodOrder[5] = 'create';
$lang->repo->methodOrder[10] = 'edit';
$lang->repo->methodOrder[15] = 'delete';
$lang->repo->methodOrder[20] = 'showSyncCommit';
$lang->repo->methodOrder[25] = 'maintain';
$lang->repo->methodOrder[30] = 'browse';
$lang->repo->methodOrder[35] = 'view';
$lang->repo->methodOrder[40] = 'diff';
$lang->repo->methodOrder[45] = 'log';
$lang->repo->methodOrder[50] = 'revision';
$lang->repo->methodOrder[55] = 'blame';
$lang->repo->methodOrder[60] = 'download';
$lang->repo->methodOrder[65] = 'setRules';
$lang->repo->methodOrder[70] = 'apiGetRepoByUrl';
$lang->repo->methodOrder[75] = 'downloadCode';
$lang->repo->methodOrder[80] = 'linkStory';
$lang->repo->methodOrder[85] = 'linkBug';
$lang->repo->methodOrder[90] = 'linkTask';
$lang->repo->methodOrder[95] = 'unlink';
$lang->repo->methodOrder[5] = 'create';
$lang->repo->methodOrder[10] = 'edit';
$lang->repo->methodOrder[15] = 'delete';
$lang->repo->methodOrder[20] = 'showSyncCommit';
$lang->repo->methodOrder[25] = 'maintain';
$lang->repo->methodOrder[30] = 'browse';
$lang->repo->methodOrder[35] = 'view';
$lang->repo->methodOrder[40] = 'diff';
$lang->repo->methodOrder[45] = 'log';
$lang->repo->methodOrder[50] = 'revision';
$lang->repo->methodOrder[55] = 'blame';
$lang->repo->methodOrder[60] = 'download';
$lang->repo->methodOrder[65] = 'setRules';
$lang->repo->methodOrder[70] = 'apiGetRepoByUrl';
$lang->repo->methodOrder[75] = 'downloadCode';
$lang->repo->methodOrder[80] = 'linkStory';
$lang->repo->methodOrder[85] = 'linkBug';
$lang->repo->methodOrder[90] = 'linkTask';
$lang->repo->methodOrder[95] = 'unlink';
$lang->repo->methodOrder[100] = 'import';
$lang->resource->ci = new stdclass();
$lang->resource->ci->commitResult = 'commitResult';
+2
View File
@@ -0,0 +1,2 @@
.main-content>.center-block {max-width: 800px;}
#jenkinsForm table {width: 600px;}
+2 -6
View File
@@ -22,12 +22,10 @@
<tr>
<th><?php echo $lang->jenkins->name; ?></th>
<td class='required'><?php echo html::input('name', '', "class='form-control'"); ?></td>
<td></td>
</tr>
<tr>
<th><?php echo $lang->jenkins->url; ?></th>
<td class='required'><?php echo html::input('url', '', "class='form-control'"); ?></td>
<td></td>
</tr>
<tr>
<th><?php echo $lang->jenkins->account;?></th>
@@ -35,13 +33,11 @@
</tr>
<tr>
<th><?php echo $lang->jenkins->token;?></th>
<td><?php echo html::input('token', '', "class='form-control'");?></td>
<td><?php echo $lang->jenkins->tokenFirst;?></td>
<td><?php echo html::input('token', '', "class='form-control' placeholder='{$lang->jenkins->tokenFirst}'");?></td>
</tr>
<tr>
<th><?php echo $lang->jenkins->password;?></th>
<td><?php echo html::password('password', '', "class='form-control'");?></td>
<td><?php echo $lang->jenkins->tips;?></td>
<td><?php echo html::password('password', '', "class='form-control' placeholder='{$lang->jenkins->tips}'");?></td>
</tr>
<tr>
<td colspan='2' class='text-center form-actions'>
+5 -1
View File
@@ -483,7 +483,8 @@ class kanbanModel extends model
->add('assignedDate', $now)
->add('color', '#fff')
->trim('name,estimate')
->setDefault('estimate', 0)
->setDefault('estimate,fromID', 0)
->setDefault('fromType', '')
->stripTags($this->config->kanban->editor->createcard['id'], $this->config->allowedTags)
->join('assignedTo', ',')
->setIF(is_numeric($this->post->estimate), 'estimate', (float)$this->post->estimate)
@@ -504,6 +505,9 @@ class kanbanModel extends model
$card = $this->loadModel('file')->processImgURL($card, $this->config->kanban->editor->createcard['id'], $this->post->uid);
if(!$card->begin) unset($card->begin);
if(!$card->end) unset($card->end);
$this->dao->insert(TABLE_KANBANCARD)->data($card)->autoCheck()
->checkIF($card->estimate != '', 'estimate', 'float')
->batchCheck($this->config->kanban->createcard->requiredFields, 'notempty')
+3 -6
View File
@@ -170,16 +170,13 @@ class productModel extends model
{
if(defined('TUTORIAL')) return $productID;
$product = $this->getById($productID);
if($productID == 0 and $this->cookie->preProductID and isset($products[$this->cookie->preProductID])) $productID = $this->cookie->preProductID;
if($productID == 0 and $this->session->product == '') $productID = key($products);
if(!empty($product) and $product->shadow) $productID = key($products);
$this->session->set('product', (int)$productID, $this->app->tab);
if(!isset($products[$this->session->product]))
{
if(!empty($product) and $product->id != $productID) $product = $this->getById($productID);
$product = $this->getById($productID);
if(empty($product) or $product->deleted == 1) $productID = key($products);
$this->session->set('product', (int)$productID, $this->app->tab);
@@ -1772,14 +1769,14 @@ class productModel extends model
$bugs = $this->dao->select('count(*) AS count')->from(TABLE_BUG)->where('product')->eq($productID)->andWhere('deleted')->eq(0)->fetch();
$docs = $this->dao->select('count(*) AS count')->from(TABLE_DOC)->where('product')->eq($productID)->andWhere('deleted')->eq(0)->fetch();
$releases = $this->dao->select('count(*) AS count')->from(TABLE_RELEASE)->where('deleted')->eq(0)->andWhere('product')->eq($productID)->fetch();
$projects = $this->dao->select('count("t1.*") AS count')->from(TABLE_PROJECTPRODUCT)->alias('t1')
$projects = $this->dao->select('count(*) AS count')->from(TABLE_PROJECTPRODUCT)->alias('t1')
->leftJoin(TABLE_PROJECT)->alias('t2')->on('t1.project = t2.id')
->where('t2.deleted')->eq(0)
->andWhere('t1.product')->eq($productID)
->andWhere('t2.type')->eq('project')
->fetch();
$executions = $this->dao->select('count("t1.*") AS count')->from(TABLE_PROJECTPRODUCT)->alias('t1')
$executions = $this->dao->select('count(*) AS count')->from(TABLE_PROJECTPRODUCT)->alias('t1')
->leftJoin(TABLE_PROJECT)->alias('t2')->on('t1.project = t2.id')
->where('t2.deleted')->eq(0)
->andWhere('t1.product')->eq($productID)
+5 -2
View File
@@ -2348,16 +2348,19 @@ class project extends control
* @param int $projectID
* @param int $executionID
* @param string $mode
* @param string $type
* @param string $type all|sprint|stage|kanban
* @access public
* @return void
*/
public function ajaxGetExecutions($projectID, $executionID = 0, $mode = '', $type = 'all')
{
$project = $this->project->getById($projectID);
$executions = array('' => '') + $this->loadModel('execution')->getPairs($projectID, $type, $mode);
if($this->app->getViewType() == 'json') return print(json_encode($executionList));
return print(html::select('execution', $executions, $executionID, "class='form-control'"));
$disabled = $project->multiple ? '' : 'disabled';
return print(html::select('execution', $executions, $executionID, "class='form-control $disabled' $disabled"));
}
/**
+1 -1
View File
@@ -1957,7 +1957,7 @@ class projectModel extends model
{
$beginTimeStamp = strtotime($project->begin);
$tasks = $this->dao->select('id,estStarted,deadline,status')->from(TABLE_TASK)
->where('deadline')->ne('0000-00-00')
->where('deadline')->notZeroDate()
->andWhere('status')->in('wait,doing')
->andWhere('project')->eq($projectID)
->fetchAll();
+55 -4
View File
@@ -139,7 +139,7 @@ class repo extends control
$this->app->loadLang('action');
if($this->app->tab == 'project')
if($this->app->tab == 'project' or $this->app->tab == 'execution')
{
$products = $this->loadModel('product')->getProductPairsByProject($objectID);
}
@@ -154,7 +154,7 @@ class repo extends control
$this->view->users = $this->loadModel('user')->getPairs('noletter|noempty|nodeleted|noclosed');
$this->view->products = $products;
$this->view->projects = $this->loadModel('product')->getProjectPairsByProductIDList(array_keys($products));
$this->view->relatedProjects = $this->app->tab == 'project' ? array($objectID) : array();
$this->view->relatedProjects = ($this->app->tab == 'project' or $this->app->tab == 'execution') ? array($objectID) : array();
$this->view->serviceHosts = $this->loadModel('gitlab')->getPairs();
$this->view->objectID = $objectID;
@@ -1382,6 +1382,50 @@ class repo extends control
return $this->send(array('result' => 'success', 'revision' => $revision));
}
/**
* Import repos.
*
* @param int $server
* @access public
* @return void
*/
public function import($server = 0)
{
if($_POST)
{
$this->repo->batchCreate();
if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => $this->repo->createLink('maintain')));
}
$gitlabList = $this->loadModel('gitlab')->getList();
$gitlab = empty($server) ? array_shift($gitlabList) : $this->gitlab->getById($server);
$repoList = array();
if(!empty($gitlab))
{
$repoList = $this->gitlab->apiGetProjects($gitlab->id);
$existRepoList = $this->dao->select('serviceProject,name')->from(TABLE_REPO)
->where('SCM')->eq(ucfirst($gitlab->type))
->andWhere('serviceHost')->eq($gitlab->id)
->fetchPairs();
foreach($repoList as $key => $repo)
{
if(isset($existRepoList[$repo->id])) unset($repoList[$key]);
}
}
$products = $this->loadModel('product')->getPairs('', 0, '', 'all');
$this->view->gitlabPairs = $this->gitlab->getPairs();
$this->view->products = $products;
$this->view->projects = $this->product->getProjectPairsByProductIDList(array_keys($products));
$this->view->gitlab = $gitlab;
$this->view->repoList = array_values($repoList);
$this->display();
}
/**
* Ajax sync comment.
*
@@ -1705,12 +1749,19 @@ class repo extends control
->setDefault('projects', array())
->get();
$productIds = $postData->products;
if(empty($productIds))
{
$products = $this->loadModel('product')->getPairs('', 0, '', 'all');
$productIds = array_keys($products);
}
/* Get all projects that can be accessed. */
$accessProjects = $this->loadModel('product')->getProjectPairsByProductIDList($postData->products);
$accessProjects = $this->loadModel('product')->getProjectPairsByProductIDList($productIds);
$selectedProjects = array_intersect(array_keys($accessProjects), $postData->projects);
return print (html::select('projects[]', $accessProjects, $selectedProjects, "class='form-control chosen' multiple"));
$name = isset($postData->number) ? "projects[{$postData->number}][]" : 'projects[]';
return print (html::select($name, $accessProjects, $selectedProjects, "class='form-control chosen' multiple"));
}
/**
+1
View File
@@ -13,6 +13,7 @@
#dropMenuRepo > div.table-row > div > div > ul > li > div {padding-left: 20px;}
#dropMenuRepo > div.table-row > div > div > ul > li > ul {padding-left: 10px;}
#repoList .hide-in-search .hidden {display: block !important; visibility: inherit !important;}
#mainMenu .btn-limit {max-width: unset !important;}
#branchList {line-height: 25px;}
#branchList .hide-in-search, #branchList .tree ul {padding-left: 20px;}
+8
View File
@@ -0,0 +1,8 @@
#repoList td.form-actions {padding: 7px;}
#repoList td.form-actions a {line-height: 18px;}
.main-table .table {cursor: default;}
.main-table thead>tr {border-bottom: none; height: 45px;}
.main-table tbody>tr {border-bottom: none; height: 42px;}
.icon-close {cursor: pointer;}
a.btn-active-text {line-height: 19px;}
+53
View File
@@ -0,0 +1,53 @@
/**
* Delete the project.
*
* @param object $icon
* @access public
* @return void
*/
function delItem(icon)
{
$(icon).closest('tr').remove();
checkItem();
}
/**
* Check the project.
*
* @access public
* @return void
*/
function checkItem()
{
if(!$("#repoList tbody tr").length) $("#submit").prop('disabled', true);
}
$(function()
{
checkItem();
$(document).on('change', '[id^=product]', function()
{
var i = $(this).attr('id').replace(/[^0-9]/ig, '');
var projects = $('#projects' + i).val();
var products = $(this).val();
$.post(createLink('repo', 'ajaxProjectsOfProducts'), {products, projects, 'number':i}, function(response)
{
$('#projectContainer' + i).html('').append(response);
$('#projects' + i).chosen().trigger("chosen:updated");
});
});
});
/**
* Change server.
*
* @access public
* @return void
*/
function selectServer()
{
var server = $('#servers').val();
window.location.href = createLink('repo', 'import', 'server=' + server);
}
+5
View File
@@ -46,6 +46,11 @@ $lang->repo->httpClone = 'Clone with HTTP';
$lang->repo->cloneUrl = 'Clone URL';
$lang->repo->linkTask = 'Link Task';
$lang->repo->unlinkedTasks = 'Unlinked Tasks';
$lang->repo->importAction = 'Import Repo';
$lang->repo->import = 'Import';
$lang->repo->importName = 'Name after import';
$lang->repo->importServer = 'Please select a server';
$lang->repo->gitlabList = 'Gitlab Repo';
$lang->repo->submit = 'Submit';
$lang->repo->cancel = 'Cancel';
+5
View File
@@ -46,6 +46,11 @@ $lang->repo->httpClone = 'Clone with HTTP';
$lang->repo->cloneUrl = 'Clone URL';
$lang->repo->linkTask = 'Link Task';
$lang->repo->unlinkedTasks = 'Unlinked Tasks';
$lang->repo->importAction = 'Import Repo';
$lang->repo->import = 'Import';
$lang->repo->importName = 'Name after import';
$lang->repo->importServer = 'Please select a server';
$lang->repo->gitlabList = 'Gitlab Repo';
$lang->repo->submit = 'Submit';
$lang->repo->cancel = 'Cancel';
+5
View File
@@ -46,6 +46,11 @@ $lang->repo->httpClone = 'Clone with HTTP';
$lang->repo->cloneUrl = 'Clone URL';
$lang->repo->linkTask = 'Link Task';
$lang->repo->unlinkedTasks = 'Unlinked Tasks';
$lang->repo->importAction = 'Import Repo';
$lang->repo->import = 'Import';
$lang->repo->importName = 'Name after import';
$lang->repo->importServer = 'Please select a server';
$lang->repo->gitlabList = 'Gitlab Repo';
$lang->repo->submit = 'Soumettre';
$lang->repo->cancel = 'Annuler';
+6 -1
View File
@@ -32,7 +32,7 @@ $lang->repo->blameTmpl = '第 <strong>%line</strong> 行代码相关信息
$lang->repo->notRelated = '暂时没有关联禅道对象';
$lang->repo->browseAction = '浏览代码库';
$lang->repo->createAction = '创建代码库';
$lang->repo->createAction = '添加代码库';
$lang->repo->editAction = '编辑代码库';
$lang->repo->diffAction = '版本对比';
$lang->repo->downloadAction = '下载代码库文件';
@@ -46,6 +46,11 @@ $lang->repo->httpClone = '使用HTTP克隆';
$lang->repo->cloneUrl = '克隆地址';
$lang->repo->linkTask = '关联任务';
$lang->repo->unlinkedTasks = '未关联任务';
$lang->repo->importAction = '导入代码库';
$lang->repo->import = '导入';
$lang->repo->importName = '导入后的名称';
$lang->repo->importServer = '请选择服务器';
$lang->repo->gitlabList = 'Gitlab代码库';
$lang->repo->submit = '提交';
$lang->repo->cancel = '取消';
+71
View File
@@ -120,6 +120,16 @@ class repoModel extends model
->page($pager)
->fetchAll('id');
if($getCodePath)
{
$gitlabRepos = array();
foreach($repos as $repo)
{
if($repo->SCM == 'Gitlab') $gitlabRepos[$repo->id] = $repo;
}
$this->loadModel('gitlab')->apiMultiGetProjects($gitlabRepos);
}
/* Get products. */
$productIdList = $this->loadModel('product')->getProductIDByProject($projectID, false);
foreach($repos as $i => $repo)
@@ -244,6 +254,67 @@ class repoModel extends model
return $repoID;
}
/**
* Batch create repos.
*
* @access public
* @return bool
*/
public function batchCreate()
{
$repos = fixer::input('post')->get();
$dataAry = array();
foreach($repos as $key => $val)
{
if(strpos($key, 'serviceProject') === 0)
{
$i = substr($key, 14);
if(empty($repos->{'product' . $i})) dao::$errors['product' . $i][] = sprintf($this->lang->error->notempty, $this->lang->repo->product);
if(empty($repos->{'name' . $i})) dao::$errors['name' . $i][] = sprintf($this->lang->error->notempty, $this->lang->repo->name);
if(!empty($repos->{'product' . $i}) and !empty($repos->{'name' . $i})) $dataAry[] = array('serviceProject' => $repos->{'serviceProject' . $i}, 'product' => implode(',', $repos->{'product' . $i}), 'name' => $repos->{'name' . $i}, 'projects' => empty($repos->projects[$i]) ? '' : implode(',', $repos->projects[$i]));
}
}
if(dao::isError()) return false;
foreach($dataAry as $data)
{
$repo = new stdclass();
$repo->serviceHost = $repos->serviceHost;
$repo->serviceProject = $data['serviceProject'];
$repo->product = $data['product'];
$repo->name = $data['name'];
$repo->projects = $data['projects'];
$repo->SCM = 'Gitlab';
$repo->encoding = 'utf-8';
$repo->encrypt = 'base64';
$this->dao->insert(TABLE_REPO)->data($repo)
->batchCheck($this->config->repo->create->requiredFields, 'notempty')
->check('serviceHost,serviceProject', 'notempty')
->check('name', 'unique', "`SCM` = '{$repo->SCM}'")
->check('serviceProject', 'unique', "`SCM` = '{$repo->SCM}' and `serviceHost` = '{$repo->serviceHost}'")
->autoCheck()
->exec();
if(dao::isError()) return false;
$repoID = $this->dao->lastInsertID();
if($repo->SCM == 'Gitlab')
{
/* Add webhook. */
$repo = $this->getRepoByID($repoID);
$this->loadModel('gitlab')->addPushWebhook($repo);
}
$actionID = $this->loadModel('action')->create('repo', $repoID, 'created');
}
return true;
}
/**
* Update a repo.
*
+65
View File
@@ -0,0 +1,65 @@
<?php
/**
* The import view file of repo module of ZenTaoPMS.
*
* @copyright Copyright 2009-2017 禅道软件(青岛)有限公司(ZenTao Software (Qingdao) Co., Ltd. www.cnezsoft.com)
* @license ZPL(http://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
* @author Gang Zeng <zenggang@cnezsoft.com>
* @package repo
* @version $Id$
* @link http://www.zentao.net
*/
?>
<?php include '../../common/view/header.html.php';?>
<div id="mainMenu" class="clearfix">
<div class="btn-toolbar pull-left">
<?php echo html::a($this->createLink('repo', 'import'), "<span class='text'>{$lang->repo->importAction}</span>", '', "class='btn btn-link btn-active-text'");?>
<div class='input-group w-400px'>
<span class='input-group-addon'><?php echo $lang->repo->importServer?></span>
<?php echo html::select("servers", $gitlabPairs, $gitlab->id, "class='form-control chosen' onchange='selectServer()'");?>
</div>
</div>
</div>
<div id='mainContent' class='main-row'>
<form class='main-table form-ajax' id='ajaxForm' method='post'>
<?php echo html::hidden("serviceHost", $gitlab->id);?>
<table id='repoList' class='table table-form'>
<thead>
<tr>
<th class='w-300px'><?php echo $lang->repo->gitlabList;?></th>
<th class='c-name w-300px required'><?php echo $lang->repo->importName;?></th>
<th class='text-left required'><?php echo $lang->repo->product;?></th>
<th class='text-left'><?php echo $lang->repo->projects;?></th>
<th class='c-actions-3 text-center'></th>
</tr>
</thead>
<tbody>
<?php foreach ($repoList as $key => $repo): ?>
<tr class='text'>
<td class='text-c-name' title='<?php echo $repo->name;?>'>
<?php echo html::hidden("serviceProject{$key}", $repo->id);?>
<?php echo $repo->name_with_namespace;?>
</td>
<td class='text-c-name'>
<?php echo html::input("name{$key}", $repo->name, "class='form-control'");?>
</td>
<td><?php echo html::select("product{$key}[]", $products, '', "class='form-control chosen product' multiple");?></td>
<td id='projectContainer<?php echo $key;?>'><?php echo html::select("projects[{$key}][]", $projects, '', "class='form-control chosen project' multiple");?></td>
<td class='c-actions'><i onclick="delItem(this)" class="icon-close"></i></td>
</tr>
<?php endforeach;?>
</tbody>
<tfoot>
<tr>
<td colspan='5' class='text-center form-actions'>
<?php echo html::submitButton($lang->repo->import); ?>
<?php if(!isonlybody()):?>
<?php if($this->app->tab == 'devops') echo html::a(inlink('maintain', ""), $lang->goback, '', 'class="btn btn-wide"');?>
<?php endif;?>
</td>
</tr>
</tfoot>
</table>
</form>
</div>
<?php include '../../common/view/footer.html.php';?>
+2 -1
View File
@@ -16,7 +16,8 @@
<?php echo html::a($this->createLink('repo', 'maintain'), "<span class='text'>{$lang->repo->maintain}</span>", '', "class='btn btn-link btn-active-text'");?>
</div>
<div class='btn-toolbar pull-right'>
<?php if(common::hasPriv('repo', 'create')) echo html::a(helper::createLink('repo', 'create'), "<i class='icon icon-plus'></i> " . $this->lang->repo->create, '', "class='btn btn-primary'");?>
<?php if(common::hasPriv('repo', 'import')) echo html::a(helper::createLink('repo', 'import'), "<i class='icon icon-import'></i> " . $this->lang->repo->importAction, '', "class='btn btn-link'");?>
<?php if(common::hasPriv('repo', 'create')) echo html::a(helper::createLink('repo', 'create'), "<i class='icon icon-plus'></i> " . $this->lang->repo->createAction, '', "class='btn btn-primary'");?>
</div>
</div>
<div id='mainContent'>
+2
View File
@@ -1,2 +1,4 @@
.table-form .c-name {width: 130px;}
.table-form .c-input {width: 650px;}
.main-content>.center-block {max-width: 900px;}
#sonarqubeForm table {width: 700px;}
-1
View File
@@ -22,7 +22,6 @@
<tr>
<th class='c-name'><?php echo $lang->sonarqube->name;?></th>
<td class='c-input'><?php echo html::input('name', '', "class='form-control' placeholder='{$lang->sonarqube->placeholder->name}'");?></td>
<td class="tips-git"></td>
</tr>
<tr>
<th><?php echo $lang->sonarqube->url;?></th>
+5 -2
View File
@@ -2400,8 +2400,11 @@ class testcase extends control
if(dao::isError()) return print(js::error(dao::getError()));
$nodeID = $_POST['node'];
$node = $this->zanode->getNodeByID($_POST['node']);
// if(!empty($_POST['syncToZentao']))
// $this->zanode->syncCasesToZentao($_POST['scriptPath']);
// $nodeID = $_POST['node'];
// $node = $this->zanode->getNodeByID($_POST['node']);
$locatelink = $this->createLink('testcase', 'browse', "productID={$_POST['product']}");
$locatelink = str_replace(array('?onlybody=yes', '&onlybody=yes'), '', $locatelink);
+1
View File
@@ -0,0 +1 @@
table a.refresh {border-color: white;}
+8
View File
@@ -0,0 +1,8 @@
function loadNodes()
{
var nodeLink = createLink('zanode', 'ajaxGetNodes');
$('#nodeIdBox').load(nodeLink, function()
{
$('#nodeIdBox').find('#node').picker();
});
}
+11 -6
View File
@@ -33,26 +33,31 @@
<?php endif;?>
<tr>
<th class='w-100px'><?php echo $lang->zanode->common;?></th>
<td class='required'><?php echo html::select('node', $nodeList, !empty($automation->node) ? $automation->node : '', "class='form-control picker-select'");?></td>
<td></td>
<td class='required' id='nodeIdBox'><?php echo html::select('node', $nodeList, !empty($automation->node) ? $automation->node : '', "class='form-control picker-select'");?></td>
<td>
<?php echo html::a($this->createLink('zanode', 'create'), $lang->zanode->create, '', "class='text-primary' target='_blank'");?>
<?php echo html::a("javascript:void(0)", "<i class='icon icon-refresh'></i>", '', "class='btn btn-icon refresh' data-toggle='tooltip' title='{$lang->refresh}' onclick='loadNodes()'");?>
</td>
<td></td>
</tr>
<tr>
<th>
<?php echo $lang->zanode->scriptPath;?>
</th>
<td class='required'><?php echo html::input('scriptPath', !empty($automation->scriptPath) ? $automation->scriptPath : '', "class='form-control'");?></td>
<td class='required'><?php echo html::input('scriptPath', !empty($automation->scriptPath) ? $automation->scriptPath : '', "class='form-control' placeholder='{$lang->zanode->scriptTips}'");?></td>
<td>
<icon class='icon icon-help' data-toggle='popover' data-trigger='focus hover' data-placement='left' data-tip-class='text-muted popover-sm' data-content="<?php echo $lang->zanode->scriptTips;?>"></icon>
</td>
</tr>
<!-- <tr>
<th></th>
<td><?php echo html::checkbox('syncToZentao', array(1 => $lang->zanode->syncToZentao), '');?></td>
</tr> -->
<tr>
<th>
<?php echo $lang->zanode->shell;?>
</th>
<td colspan='2'><?php echo html::textarea('shell', !empty($automation->shell) ? $automation->shell : '', "rows='6' class='form-control'");?></td>
<td colspan='2'><?php echo html::textarea('shell', !empty($automation->shell) ? $automation->shell : '', "rows='6' class='form-control' placeholder='{$lang->zanode->shellTips}'");?></td>
<td>
<icon class='icon icon-help' data-toggle='popover' data-trigger='focus hover' data-placement='left' data-tip-class='text-muted popover-sm' data-content="<?php echo $lang->zanode->shellTips;?>"></icon>
</td>
</tr>
<tr>
+5 -3
View File
@@ -1903,11 +1903,13 @@ class testtaskModel extends model
$caseID = $case->id;
$oldCase = $this->dao->select('*')->from(TABLE_CASE)->where('id')->eq($caseID)->fetch();
$this->dao->update(TABLE_CASE)->data($case)->where('id')->eq($caseID)->exec();
$case->version = $oldCase->version;
$case->openedDate = $oldCase->openedDate;
$changes = common::createChanges($oldCase, $case);
if($changes)
{
$this->dao->update(TABLE_CASE)->data($case)->where('id')->eq($caseID)->exec();
$actionID = $this->action->create('case', $caseID, 'Edited');
$this->action->logHistory($actionID, $changes);
}
@@ -2344,7 +2346,7 @@ class testtaskModel extends model
$caseStep = new stdclass();
$caseStep->type = 'step';
$caseStep->desc = '';
$caseStep->desc = $step->name;
$caseStep->expect = $step->checkPoints[0]->expect;
$case->steps[] = $caseStep;
+14 -1
View File
@@ -44,7 +44,7 @@ class zahost extends control
$showFeature = false;
$accounts = !empty($this->config->global->skipAutomation) ? $this->config->global->skipAutomation : '';
if(strpos(",$accounts,", $this->app->user->account) === false)
if(strpos(",$accounts,", $this->app->user->account) === false)
{
$showFeature = true;
$accounts .= ',' . $this->app->user->account;
@@ -109,6 +109,7 @@ class zahost extends control
}
$viewLink = $this->createLink('zahost', 'view', "hostID=$hostID");
if(isonlybody()) return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true, 'callback' => 'parent.loadHosts()'));
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => $viewLink));
}
@@ -368,4 +369,16 @@ class zahost extends control
return $this->send(array('result' => 'success', 'message' => '', 'data' => $serviceStatus));
}
/**
* Ajaxget hosts.
*
* @access public
* @return void
*/
public function ajaxGetHosts()
{
$hostList = $this->zahost->getPairs();
return print(html::select("parent", $hostList, '', "class='form-control chosen'"));
}
}
+2 -1
View File
@@ -193,7 +193,8 @@ class zahostModel extends model
*/
public function getImageList($hostID, $browseType = 'all', $param = 0, $orderBy = 'id', $pager = null)
{
$imageList = json_decode(commonModel::http($this->config->zahost->imageListUrl, array(), array()));
$imageList = json_decode(commonModel::http($this->config->zahost->imageListUrl, array(), array()));
if(empty($imageList)) return array();
$downloadedImageList = $this->dao->select('*')->from(TABLE_IMAGE)
->where('host')->eq($hostID)
+33 -2
View File
@@ -3,7 +3,7 @@ $config->zanode->create = new stdClass();
$config->zanode->edit = new stdClass();
$config->zanode->createimage = new stdClass();
$config->zanode->create->requiredFields = 'name,host,image,cpu,memory,disk,osName';
$config->zanode->create->physicsRequiredFields = 'name,extranet,cpu,memory,osName';
$config->zanode->create->physicsRequiredFields = 'name,extranet,cpu,memory,osNamePhysics';
$config->zanode->edit->requiredFields = '';
$config->zanode->createimage->requiredFields = 'name';
@@ -12,7 +12,8 @@ $config->zanode->defaultAccount = 'z';
$config->zanode->defaultWinAccount = 'admin';
$config->zanode->defaultPwd = 'CQdliYQn6tKkoFhP';
$config->zanode->initBash = 'curl -sSL https://pkg.qucheng.com/zenagent/zagent.sh | bash /dev/stdin -szvm -z%s';
$config->zanode->initBash = 'curl -sSL https://pkg.qucheng.com/zenagent/zagent.sh | bash /dev/stdin -s zvm -k %s -z %s';
$config->zanode->initPosh = 'Invoke-WebRequest -UseBasicParsing -Uri "https://pkg.qucheng.com/zenagent/zagent-vm.ps1" -OutFile "./install-zanget-vm.ps1"; &"./install-zanget-vm.ps1" -s %s -z %s';
$config->zanode->os = new stdClass();
@@ -51,3 +52,33 @@ $config->zanode->editor->create = array('id' => 'desc', 'tools' => 'simpleT
$config->zanode->editor->edit = array('id' => 'desc', 'tools' => 'simpleTools');
$config->zanode->editor->createimage = array('id' => 'desc', 'tools' => 'simpleTools');
$config->zanode->editor->view = array('id' => 'comment,lastComment', 'tools' => 'simpleTools');
$config->zanode->osType = array('linux' => 'Linux', 'windows' => 'Microsoft Windows');
$config->zanode->linuxList[''] = '';
$config->zanode->linuxList['centOS65'] = 'CentOS 6.5';
$config->zanode->linuxList['centOS66'] = 'CentOS 6.6';
$config->zanode->linuxList['centOS67'] = 'CentOS 6.7';
$config->zanode->linuxList['centOS70'] = 'CentOS 7.0';
$config->zanode->linuxList['centOS71'] = 'CentOS 7.1';
$config->zanode->linuxList['centOS79'] = 'CentOS 7.9';
$config->zanode->linuxList['ubuntu1404'] = 'Ubuntu 14.04';
$config->zanode->linuxList['ubuntu1604'] = 'Ubuntu 16.04';
$config->zanode->linuxList['ubuntu1804'] = 'Ubuntu 18.04';
$config->zanode->linuxList['ubuntu2004'] = 'Ubuntu 20.04';
$config->zanode->linuxList['debianBullseye'] = 'Debian Bullseye';
$config->zanode->linuxList['debianBuster'] = 'Debian Buster';
$config->zanode->windowsList[''] = '';
$config->zanode->windowsList['win10'] = 'Windows 10';
$config->zanode->windowsList['winserver08x64'] = 'Windows Server2008 x64';
$config->zanode->windowsList['winserver12'] = 'Windows Server2012';
$config->zanode->windowsList['winserver16'] = 'Windows Server2016';
$config->zanode->versionToOs[''] = '';
$config->zanode->versionToOs['win10'] = 'windows';
$config->zanode->versionToOs['winserver08x64'] = 'windows';
$config->zanode->versionToOs['winserver12'] = 'windows';
$config->zanode->versionToOs['winserver16'] = 'windows';
+23 -11
View File
@@ -161,17 +161,16 @@ class zanode extends control
$node = $this->zanode->getNodeByID($id);
$vnc = $this->zanode->getVncUrl($node);
/* Add action log. */
// if(!empty($vnc->token)) $this->loadModel('action')->create('zanode', $id, 'getVNC');
$this->view->url = $node->ip . ":" . $node->hzap;
$this->view->host = !empty($vnc->hostIP) ? $vnc->hostIP:'';
$this->view->token = !empty($vnc->token) ? $vnc->token:'';
$this->view->title = $this->lang->zanode->view;
$this->view->zanode = $node;
$this->view->url = $node->ip . ":" . $node->hzap;
$this->view->host = !empty($vnc->hostIP) ? $vnc->hostIP:'';
$this->view->token = !empty($vnc->token) ? $vnc->token:'';
$this->view->title = $this->lang->zanode->view;
$this->view->zanode = $node;
$this->view->snapshotList = $this->zanode->getSnapshotList($id);
$this->view->actions = $this->loadModel('action')->getList('zanode', $id);
$this->view->users = $this->loadModel('user')->getPairs('noletter');
$this->view->initBash = sprintf(zget($this->config->zanode->versionToOs, $node->osName, '') != '' ? $this->config->zanode->initPosh : $this->config->zanode->initBash, $node->secret, getWebRoot(true));
$this->view->actions = $this->loadModel('action')->getList('zanode', $id);
$this->view->users = $this->loadModel('user')->getPairs('noletter');
$this->display();
}
@@ -564,8 +563,9 @@ class zanode extends control
if ($node->status != 'running')
{
$serviceStatus['ZenAgent'] = "unknown";
$serviceStatus['ZTF'] = "unknown";
$serviceStatus['ZTF'] = "unknown";
}
$node->status = $node->status == 'online' ? 'ready' : $node->status;
$serviceStatus['node'] = $node->status;
return $this->send(array('result' => 'success', 'message' => '', 'data' => $serviceStatus));
@@ -626,4 +626,16 @@ class zanode extends control
return $this->send(array('result' => 'success', 'message' => 'success'));
}
}
/**
* Ajaxget nodes.
*
* @access public
* @return void
*/
public function ajaxGetNodes()
{
$nodeList = $this->zanode->getPairs();
return print(html::select("node", $nodeList, '', "class='form-control picker-select'"));
}
}
+4 -1
View File
@@ -1,9 +1,12 @@
.c-id {width: 70px;}
.c-memory{width: 100px;}
.c-status {width: 70px;}
.c-status {width: 90px;}
.c-cpu, .c-host {width: 100px;}
.c-ip{width: 150px;}
.c-os, .c-type {width: 120px;}
.desktop, .createImage{margin-right: 4px;}
#helpTab .icon-help {line-height: unset;}
#bysearchTab {margin-right: 0px;}
.c-actions a img{position: relative; left: -80px; filter: drop-shadow(#18a6fd 80px 0); width: 18px;}
.c-actions a.disabled img {filter: drop-shadow(#313c52 80px 0);}
+1
View File
@@ -1,4 +1,5 @@
#main{min-width: 0!important;padding:0!important;}
#main .container{padding:0!important;}
body{background-color: #fff!important;}
.c-createdBy {width: 100px;}
+2
View File
@@ -1 +1,3 @@
.icon-help{line-height: 34px;}
#osNamePhysicsContainer{display: flex;}
#osNamePhysicsContainer select{margin-right: 5px;}
+5 -3
View File
@@ -7,14 +7,16 @@
.zanode-mt-8{margin-top: 8px;}
.zanode-status-text{margin-left: 10px;font:small-caption;color:#838a9d;}
.zanode-status-text i{color:#18a6fd}
.status-notice{margin-top: 8px;margin-left: 18px;line-height: 28px;}
.status-notice{margin-top: 16px;line-height: 28px;}
.status-notice a{color: #2463c7;}
.service-status a{color: #2463c7;}
.service-status{margin-top: 10px;}
.service-status{margin-top: 5px;}
.vnc-detail{height: 60vh;min-height: 550px;}
.vnc-mask{width: 100%;height:100%;background-color: rgba(0,0,0,0);position: absolute;z-index: 1;}
.checkStatus{color: #313c52;}
.node-not-wrap{white-space: nowrap;}
.btn-info {background-color: unset;}
.btn.disabled i {color: #fff;}
#serviceContent{min-height: 120px;}
.btn-toolbar a img{margin-bottom: 2px;}
.zanode-init{padding:15px;background: #f4f5f7;margin:10px 0;}
.btn-snap-create{height: 30px;}
+52 -4
View File
@@ -1,12 +1,18 @@
function zahostType()
/**
* Change zanode type.
*
* @access public
* @return void
*/
function zanodeType()
{
if($('#type').val() == 'physics')
if($('#hostType').val() == 'physics')
{
$('#parent').closest('tr').hide();
$('#image').closest('tr').hide();
$('#extranet').closest('tr').removeClass('hidden');
$('#osName').addClass('hidden');
$('#osNamePhysics').removeClass('hidden');
$('#osNamePhysicsContainer').removeClass('hidden');
}
else
{
@@ -14,6 +20,48 @@ function zahostType()
$('#image').closest('tr').show();
$('#extranet').closest('tr').addClass('hidden');
$('#osName').removeClass('hidden');
$('#osNamePhysics').addClass('hidden');
$('#osNamePhysicsContainer').addClass('hidden');
}
}
/**
* Load hosts.
*
* @access public
* @return void
*/
function loadHosts()
{
var hostLink = createLink('zahost', 'ajaxGetHosts');
$('#hostIdBox').load(hostLink, function()
{
$('#hostIdBox').find('#parent').chosen();
});
}
$(function()
{
$('#osNamePhysicsPre').on('change', function()
{
console.log($(this).val())
if($(this).val() == 'linux')
{
$('#osNamePhysics').empty();
for(var i in linuxList)
{
console.log(linuxList[i])
$('#osNamePhysics').append('<option value="' + i + '">' + linuxList[i] + '</option>')
}
}
else
{
$('#osNamePhysics').empty();
for(var i in windowsList)
{
console.log(windowsList[i])
$('#osNamePhysics').append('<option value="' + i + '">' + windowsList[i] + '</option>')
}
}
$('#osNamePhysics').trigger('chosen:updated');
})
})
+36 -4
View File
@@ -36,7 +36,14 @@ function checkServiceStatus(){
{
if(resultData.data[key] == 'unknown')
{
$('.ztf-status').text(zanodeLang.init.unknown)
if(hostType == 'physics')
{
$('.ztf-status').text(zanodeLang.init.not_install)
}
else
{
$('.ztf-status').text(zanodeLang.init.unknown)
}
}
else
{
@@ -47,7 +54,7 @@ function checkServiceStatus(){
}
else if(key == "node")
{
if(nodeStatus != resultData.data[key] && resultData.data[key])
if(resultData.data[key] && zanodeLang.statusList[nodeStatus] != zanodeLang.statusList[resultData.data[key]])
{
window.location.reload();
}
@@ -88,14 +95,14 @@ function checkServiceStatus(){
if(!isSuccess)
{
// $('.init-fail').show();
$('.init-fail').show();
$('.init-success').hide();
}
else
{
clearInterval(checkInterval)
$('.init-success').show();
// $('.init-fail').hide();
$('.init-fail').hide();
}
setTimeout(function() {
$('#serviceContent').removeClass('loading');
@@ -161,6 +168,28 @@ $('.btn-pwd-copy').live('click', function()
}, 2000)
})
$('.btn-init-copy').live('click', function()
{
var copyText = $('#initBash');
copyText.show();
copyText .select();
document.execCommand("Copy");
copyText.hide();
$('.btn-init-copy').tooltip({
trigger: 'click',
placement: 'top',
title: zanodeLang.copied,
tipClass: 'tooltip-success'
});
$(this).tooltip('show');
var that = this;
setTimeout(function()
{
$(that).tooltip('hide')
}, 2000)
})
$('.btn-pwd-show').live('click', function()
{
var pwd = $('#pwd-copy').text();
@@ -188,6 +217,9 @@ $('#jumpManual').click(function()
$(function(){
$('#checkServiceStatus').trigger("click")
if(hostType == 'physics'){
return;
}
checkInterval = setInterval(() => {
intervalTimes++;
if(intervalTimes > 300)
+13 -4
View File
@@ -22,6 +22,7 @@ $lang->zanode->getVNC = 'Remote management';
$lang->zanode->all = 'All';
$lang->zanode->byQuery = 'Search';
$lang->zanode->osName = 'System';
$lang->zanode->osNamePhysics = 'System';
$lang->zanode->image = 'VM Image';
$lang->zanode->imageName = 'Image Name';
$lang->zanode->name = 'Name';
@@ -29,7 +30,8 @@ $lang->zanode->start = 'Start After Created';
$lang->zanode->hostName = 'Host Name';
$lang->zanode->host = $lang->zanode->hostName;
$lang->zanode->extranet = 'IP/Domain';
$lang->zanode->sshAddress = 'SSH Command';
$lang->zanode->sshCommand = 'SSH Command';
$lang->zanode->sshAddress = 'SSH Address';
$lang->zanode->osArch = 'Arch';
$lang->zanode->cpuCores = 'CPU';
$lang->zanode->defaultUser = 'Default Account Name';
@@ -53,6 +55,7 @@ $lang->zanode->confirmRestore = "The ZenAgent Node will be restored to this sna
$lang->zanode->actionSuccess = 'Success';
$lang->zanode->deleted = "Deleted";
$lang->zanode->scriptPath = "Script path";
$lang->zanode->syncToZentao = "Sync cases in the directory to Zentao";
$lang->zanode->shell = "Shell";
$lang->zanode->automation = "Automation";
$lang->zanode->install = "Install";
@@ -63,6 +66,9 @@ $lang->zanode->manual = 'Manual';
$lang->zanode->initializing = 'Initializing';
$lang->zanode->showPwd = 'Show Password';
$lang->zanode->hidePwd = 'Hide Password';
$lang->zanode->baseInfo = 'Basic information';
$lang->zanode->cpuUnit = 'CORE';
$lang->zanode->IP = 'Extranet Address';
$lang->zanode->typeList['node'] = 'Virtual machine';
$lang->zanode->typeList['physics'] = 'Physical machine';
@@ -72,6 +78,7 @@ $lang->automation->scriptPath = $lang->zanode->scriptPath;
$lang->automation->node = $lang->zanode->common;
$lang->zanode->notFoundAgent = 'No Agent service is found';
$lang->zanode->busy = 'This Node is %s, please wait for the operation to complete.';
$lang->zanode->createVmFail = 'Failed to create a ZenAgent Node';
$lang->zanode->noVncPort = 'Failed to get vnc port';
$lang->zanode->nameValid = "The name can only be letters, numbers, '-', '_', '.', and cannot start with a symbol";
@@ -134,6 +141,8 @@ $lang->zanode->statusList['destroy_fail'] = 'Destroy Fail';
$lang->zanode->statusList['wait'] = 'Initializing';
$lang->zanode->statusList['online'] = 'Online';
$lang->zanode->statusList['restoring'] = 'Restoring';
$lang->zanode->statusList['creating_snap'] = 'Creating Snapshot';
$lang->zanode->statusList['creating_img'] = 'Creating Image';
$lang->zanode->initNotice = "Succeeded. Please initialize the execution node or return to the list.";
$lang->zanode->initButton = "Initialize";
@@ -148,9 +157,9 @@ $lang->zanode->init->ready = "Ready";
$lang->zanode->init->next = "Next";
$lang->zanode->init->button = "Go To Settings";
$lang->zanode->init->initSuccessNoticeTitle = "The service is ready, and it takes two steps to execute the automated test on the execution node: <br/>1. Configure the automated test running environment according to the %s<br/>2. Go to %s";
$lang->zanode->init->initFailNoticeTitle = "Initialization failed, check the init script execution log and try the following two solutions:";
$lang->zanode->init->initFailNoticeDesc = "1. Re-execute the script <br/>2. Review the initialization FAQ";
$lang->zanode->init->initSuccessNoticeTitle = "The service is ready, and it takes two steps to execute the automated test on the execution node: <br/>1. Configure the automated test running environment according to the %s<br/>2. Go to %s";
$lang->zanode->init->initFailNotice = "FailExecute the installation service command on the node or <a href='https://github.com/easysoft/zenagent/' target='_blank'>See Help</a>.";
$lang->zanode->init->initFailNoticeOnPhysics = "The service has not been installed yet, please check the service status after executing the following command on the execution node。<a href='https://github.com/easysoft/zenagent/' target='_blank'>See Help</a>";
$lang->zanode->init->serviceStatus = array(
"ZenAgent" => 'not_install',
+13 -4
View File
@@ -22,6 +22,7 @@ $lang->zanode->getVNC = 'Remote management';
$lang->zanode->all = 'All';
$lang->zanode->byQuery = 'Search';
$lang->zanode->osName = 'System';
$lang->zanode->osNamePhysics = 'System';
$lang->zanode->image = 'VM Image';
$lang->zanode->imageName = 'Image Name';
$lang->zanode->name = 'Name';
@@ -29,7 +30,8 @@ $lang->zanode->start = 'Start After Created';
$lang->zanode->hostName = 'Host Name';
$lang->zanode->host = $lang->zanode->hostName;
$lang->zanode->extranet = 'IP/Domain';
$lang->zanode->sshAddress = 'SSH Command';
$lang->zanode->sshCommand = 'SSH Command';
$lang->zanode->sshAddress = 'SSH Address';
$lang->zanode->osArch = 'Arch';
$lang->zanode->cpuCores = 'CPU';
$lang->zanode->defaultUser = 'Default Account Name';
@@ -53,6 +55,7 @@ $lang->zanode->confirmRestore = "The ZenAgent Node will be restored to this sna
$lang->zanode->actionSuccess = 'Success';
$lang->zanode->deleted = "Deleted";
$lang->zanode->scriptPath = "Script path";
$lang->zanode->syncToZentao = "Sync cases in the directory to Zentao";
$lang->zanode->shell = "Shell";
$lang->zanode->automation = "Automation";
$lang->zanode->install = "Install";
@@ -63,6 +66,9 @@ $lang->zanode->manual = 'Manual';
$lang->zanode->initializing = 'Initializing';
$lang->zanode->showPwd = 'Show Password';
$lang->zanode->hidePwd = 'Hide Password';
$lang->zanode->baseInfo = 'Basic information';
$lang->zanode->cpuUnit = 'CORE';
$lang->zanode->IP = 'Extranet Address';
$lang->zanode->typeList['node'] = 'Virtual machine';
$lang->zanode->typeList['physics'] = 'Physical machine';
@@ -72,6 +78,7 @@ $lang->automation->scriptPath = $lang->zanode->scriptPath;
$lang->automation->node = $lang->zanode->common;
$lang->zanode->notFoundAgent = 'No Agent service is found';
$lang->zanode->busy = 'This Node is %s, please wait for the operation to complete.';
$lang->zanode->createVmFail = 'Failed to create a ZenAgent Node';
$lang->zanode->noVncPort = 'Failed to get vnc port';
$lang->zanode->nameValid = "The name can only be letters, numbers, '-', '_', '.', and cannot start with a symbol";
@@ -134,6 +141,8 @@ $lang->zanode->statusList['destroy_fail'] = 'Destroy Fail';
$lang->zanode->statusList['wait'] = 'Initializing';
$lang->zanode->statusList['online'] = 'Online';
$lang->zanode->statusList['restoring'] = 'Restoring';
$lang->zanode->statusList['creating_snap'] = 'Creating Snapshot';
$lang->zanode->statusList['creating_img'] = 'Creating Image';
$lang->zanode->initNotice = "Succeeded. Please initialize the execution node or return to the list.";
$lang->zanode->initButton = "Initialize";
@@ -148,9 +157,9 @@ $lang->zanode->init->ready = "Ready";
$lang->zanode->init->next = "Next";
$lang->zanode->init->button = "Go To Settings";
$lang->zanode->init->initSuccessNoticeTitle = "The service is ready, and it takes two steps to execute the automated test on the execution node: <br/>1. Configure the automated test running environment according to the %s<br/>2. Go to %s";
$lang->zanode->init->initFailNoticeTitle = "Initialization failed, check the init script execution log and try the following two solutions:";
$lang->zanode->init->initFailNoticeDesc = "1. Re-execute the script <br/>2. Review the initialization FAQ";
$lang->zanode->init->initSuccessNoticeTitle = "The service is ready, and it takes two steps to execute the automated test on the execution node: <br/>1. Configure the automated test running environment according to the %s<br/>2. Go to %s";
$lang->zanode->init->initFailNotice = "FailExecute the installation service command on the node or <a href='https://github.com/easysoft/zenagent/' target='_blank'>See Help</a>.";
$lang->zanode->init->initFailNoticeOnPhysics = "The service has not been installed yet, please check the service status after executing the following command on the execution node。<a href='https://github.com/easysoft/zenagent/' target='_blank'>See Help</a>";
$lang->zanode->init->serviceStatus = array(
"ZenAgent" => 'not_install',
+13 -4
View File
@@ -22,6 +22,7 @@ $lang->zanode->getVNC = 'Remote management';
$lang->zanode->all = 'All';
$lang->zanode->byQuery = 'Search';
$lang->zanode->osName = 'System';
$lang->zanode->osNamePhysics = 'System';
$lang->zanode->image = 'VM Image';
$lang->zanode->imageName = 'Image Name';
$lang->zanode->name = 'Name';
@@ -29,7 +30,8 @@ $lang->zanode->start = 'Start After Created';
$lang->zanode->hostName = 'Host Name';
$lang->zanode->host = $lang->zanode->hostName;
$lang->zanode->extranet = 'IP/Domain';
$lang->zanode->sshAddress = 'SSH Command';
$lang->zanode->sshCommand = 'SSH Command';
$lang->zanode->sshAddress = 'SSH Address';
$lang->zanode->osArch = 'Arch';
$lang->zanode->cpuCores = 'CPU';
$lang->zanode->defaultUser = 'Default Account Name';
@@ -53,6 +55,7 @@ $lang->zanode->confirmRestore = "The ZenAgent Node will be restored to this sna
$lang->zanode->actionSuccess = 'Success';
$lang->zanode->deleted = "Deleted";
$lang->zanode->scriptPath = "Script path";
$lang->zanode->syncToZentao = "Sync cases in the directory to Zentao";
$lang->zanode->shell = "Shell";
$lang->zanode->automation = "Automation";
$lang->zanode->install = "Install";
@@ -63,6 +66,9 @@ $lang->zanode->manual = 'Manual';
$lang->zanode->initializing = 'Initializing';
$lang->zanode->showPwd = 'Show Password';
$lang->zanode->hidePwd = 'Hide Password';
$lang->zanode->baseInfo = 'Basic information';
$lang->zanode->cpuUnit = 'CORE';
$lang->zanode->IP = 'Extranet Address';
$lang->zanode->typeList['node'] = 'Virtual machine';
$lang->zanode->typeList['physics'] = 'Physical machine';
@@ -72,6 +78,7 @@ $lang->automation->scriptPath = $lang->zanode->scriptPath;
$lang->automation->node = $lang->zanode->common;
$lang->zanode->notFoundAgent = 'No Agent service is found';
$lang->zanode->busy = 'This Node is %s, please wait for the operation to complete.';
$lang->zanode->createVmFail = 'Failed to create a ZenAgent Node';
$lang->zanode->noVncPort = 'Failed to get vnc port';
$lang->zanode->nameValid = "The name can only be letters, numbers, '-', '_', '.', and cannot start with a symbol";
@@ -134,6 +141,8 @@ $lang->zanode->statusList['destroy_fail'] = 'Destroy Fail';
$lang->zanode->statusList['wait'] = 'Initializing';
$lang->zanode->statusList['online'] = 'Online';
$lang->zanode->statusList['restoring'] = 'Restoring';
$lang->zanode->statusList['creating_snap'] = 'Creating Snapshot';
$lang->zanode->statusList['creating_img'] = 'Creating Image';
$lang->zanode->initNotice = "Succeeded. Please initialize the execution node or return to the list.";
$lang->zanode->initButton = "Initialize";
@@ -148,9 +157,9 @@ $lang->zanode->init->ready = "Ready";
$lang->zanode->init->next = "Next";
$lang->zanode->init->button = "Go To Settings";
$lang->zanode->init->initSuccessNoticeTitle = "The service is ready, and it takes two steps to execute the automated test on the execution node: <br/>1. Configure the automated test running environment according to the %s<br/>2. Go to %s";
$lang->zanode->init->initFailNoticeTitle = "Initialization failed, check the init script execution log and try the following two solutions:";
$lang->zanode->init->initFailNoticeDesc = "1. Re-execute the script <br/>2. Review the initialization FAQ";
$lang->zanode->init->initSuccessNoticeTitle = "The service is ready, and it takes two steps to execute the automated test on the execution node: <br/>1. Configure the automated test running environment according to the %s<br/>2. Go to %s";
$lang->zanode->init->initFailNotice = "FailExecute the installation service command on the node or <a href='https://github.com/easysoft/zenagent/' target='_blank'>See Help</a>.";
$lang->zanode->init->initFailNoticeOnPhysics = "The service has not been installed yet, please check the service status after executing the following command on the execution node。<a href='https://github.com/easysoft/zenagent/' target='_blank'>See Help</a>";
$lang->zanode->init->serviceStatus = array(
"ZenAgent" => 'not_install',
+26 -17
View File
@@ -22,6 +22,7 @@ $lang->zanode->getVNC = '远程';
$lang->zanode->all = '全部';
$lang->zanode->byQuery = '搜索';
$lang->zanode->osName = '操作系统';
$lang->zanode->osNamePhysics = '操作系统';
$lang->zanode->image = '镜像';
$lang->zanode->imageName = '镜像名称';
$lang->zanode->name = '名称';
@@ -29,7 +30,8 @@ $lang->zanode->start = '创建后自动开启';
$lang->zanode->hostName = '所属宿主机';
$lang->zanode->host = $lang->zanode->hostName;
$lang->zanode->extranet = 'IP/域名';
$lang->zanode->sshAddress = 'SSH命令';
$lang->zanode->sshCommand = 'SSH命令';
$lang->zanode->sshAddress = 'SSH地址';
$lang->zanode->osArch = '架构';
$lang->zanode->cpuCores = 'CPU';
$lang->zanode->defaultUser = '默认用户';
@@ -53,6 +55,7 @@ $lang->zanode->confirmRestore = "执行节点将会还原至此快照状态,
$lang->zanode->actionSuccess = '操作成功';
$lang->zanode->deleted = "已删除";
$lang->zanode->scriptPath = "脚本目录";
$lang->zanode->syncToZentao = "同步脚本信息到禅道";
$lang->zanode->shell = "shell命令";
$lang->zanode->automation = "自动化设置";
$lang->zanode->install = "安装";
@@ -63,6 +66,9 @@ $lang->zanode->manual = '手册';
$lang->zanode->initializing = '初始化中';
$lang->zanode->showPwd = '显示密码';
$lang->zanode->hidePwd = '隐藏密码';
$lang->zanode->baseInfo = '基础信息';
$lang->zanode->cpuUnit = '核';
$lang->zanode->IP = 'IP/域名';
$lang->zanode->typeList['node'] = '虚拟机';
$lang->zanode->typeList['physics'] = '物理机';
@@ -72,6 +78,7 @@ $lang->automation->scriptPath = $lang->zanode->scriptPath;
$lang->automation->node = $lang->zanode->common;
$lang->zanode->notFoundAgent = '没有发现Agent服务';
$lang->zanode->busy = '节点正在%s, 请等待操作完成';
$lang->zanode->createVmFail = '创建执行节点失败';
$lang->zanode->noVncPort = '无法获取执行节点端口';
$lang->zanode->nameValid = "名称只能是字母、数字,'-''_''.',且不能以符号开头";
@@ -121,19 +128,21 @@ $lang->zanode->apiError['notRunning'] = '请检查执行节点状态';
$lang->zanode->publicList[0] = '不共享';
$lang->zanode->publicList[1] = '共享';
$lang->zanode->statusList['created'] = '已创建';
$lang->zanode->statusList['launch'] = '运行中';
$lang->zanode->statusList['ready'] = '运行中';
$lang->zanode->statusList['running'] = '运行中';
$lang->zanode->statusList['suspend'] = '休眠';
$lang->zanode->statusList['offline'] = '下线';
$lang->zanode->statusList['destroy'] = '已销毁';
$lang->zanode->statusList['shutoff'] = '已关机';
$lang->zanode->statusList['shutodown'] = '已关机';
$lang->zanode->statusList['destroy_fail'] = '销毁失败';
$lang->zanode->statusList['wait'] = '初始化中';
$lang->zanode->statusList['online'] = '已上架';
$lang->zanode->statusList['restoring'] = '还原中';
$lang->zanode->statusList['created'] = '已创建';
$lang->zanode->statusList['launch'] = '运行中';
$lang->zanode->statusList['ready'] = '运行中';
$lang->zanode->statusList['running'] = '运行中';
$lang->zanode->statusList['suspend'] = '休眠';
$lang->zanode->statusList['offline'] = '下线';
$lang->zanode->statusList['destroy'] = '已销毁';
$lang->zanode->statusList['shutoff'] = '已关机';
$lang->zanode->statusList['shutodown'] = '已关机';
$lang->zanode->statusList['destroy_fail'] = '销毁失败';
$lang->zanode->statusList['wait'] = '初始化中';
$lang->zanode->statusList['online'] = '运行中';
$lang->zanode->statusList['restoring'] = '还原中';
$lang->zanode->statusList['creating_snap'] = '创建快照中';
$lang->zanode->statusList['creating_img'] = '导出镜像中';
$lang->zanode->initNotice = "保存成功,请初始化执行节点或返回列表。";
$lang->zanode->initButton = "去初始化";
@@ -148,9 +157,9 @@ $lang->zanode->init->ready = "已就绪";
$lang->zanode->init->next = "下一步";
$lang->zanode->init->button = "去设置";
$lang->zanode->init->initSuccessNoticeTitle = "服务已就绪,还需两步即可在执行节点上执行自动化测试:<br/>1、根据%s配置自动化测试运行环境。<br/>2、进行%s";
$lang->zanode->init->initFailNoticeTitle = "初始化失败,请查看初始化脚本执行日志并尝试以下两种解决方案:";
$lang->zanode->init->initFailNoticeDesc = "1、 重新执行脚本 <br/>2、 查看初始化常见问题";
$lang->zanode->init->initSuccessNoticeTitle = "服务已就绪,还需两步即可在执行节点上执行自动化测试:<br/>1、根据%s配置自动化测试运行环境。<br/>2、进行%s";
$lang->zanode->init->initFailNotice = "服务未就绪,在执行节点上执行安装服务命令或<a href='https://github.com/easysoft/zenagent/' target='_blank'>查看帮助</a>.";
$lang->zanode->init->initFailNoticeOnPhysics = "服务还没有安装,请在执行节点执行以下命令后检测服务状态。<a href='https://github.com/easysoft/zenagent/' target='_blank'>查看帮助</a>";
$lang->zanode->init->serviceStatus = array(
"ZenAgent" => 'not_install',
+81 -30
View File
@@ -12,16 +12,19 @@
class zanodemodel extends model
{
const STATUS_CREATED = 'created';
const STATUS_LAUNCH = 'launch';
const STATUS_FAIL_CREATE = 'vm_fail_create';
const STATUS_RUNNING = 'running';
const STATUS_SHUTOFF = 'shutoff';
const STATUS_BUSY = 'busy';
const STATUS_READY = 'ready';
const STATUS_UNKNOWN = 'unknown';
const STATUS_DESTROY = 'destroy';
const STATUS_DESTROY_FAIL = 'vim_destroy_fail';
const STATUS_CREATED = 'created';
const STATUS_LAUNCH = 'launch';
const STATUS_FAIL_CREATE = 'vm_fail_create';
const STATUS_RUNNING = 'running';
const STATUS_SHUTOFF = 'shutoff';
const STATUS_BUSY = 'busy';
const STATUS_READY = 'ready';
const STATUS_UNKNOWN = 'unknown';
const STATUS_DESTROY = 'destroy';
const STATUS_RESTORING = 'restoring';
const STATUS_CREATING_SNAP = 'creating_snap';
const STATUS_CREATING_IMG = 'creating_img';
const STATUS_DESTROY_FAIL = 'vim_destroy_fail';
const KVM_CREATE_PATH = '/api/v1/kvm/create';
const KVM_TOKEN_PATH = '/api/v1/virtual/getVncToken';
@@ -54,17 +57,29 @@ class zanodemodel extends model
public function create()
{
$data = fixer::input('post')
->setIF($this->post->type == 'physics', 'parent', 0)
->setIF($this->post->type == 'physics', 'osName', $this->post->osNamePhysics)
->remove('osNamePhysics')
->setIF($this->post->hostType == 'physics', 'parent', 0)
->setIF($this->post->hostType == 'physics', 'osName', $this->post->osNamePhysics)
->get();
$data->type = "node";
if($data->hostType == 'physics')
{
$data->secret = md5($data->name . time());
$data->status = "offline";
}
else
{
$data->hostType = '';
}
/* Batch check fields. */
$this->dao->update(TABLE_ZAHOST)->data($data)
->batchCheck($data->type == 'node' ? $this->config->zanode->create->requiredFields : $this->config->zanode->create->physicsRequiredFields, 'notempty');
->batchCheck($data->hostType != 'physics' ? $this->config->zanode->create->requiredFields : $this->config->zanode->create->physicsRequiredFields, 'notempty');
if(dao::isError()) return false;
unset($data->osNamePhysics);
if(!preg_match("/^(?!_)(?!-)(?!\.)[a-zA-Z0-9\_\.\-]+$/", $data->name))
{
dao::$errors[] = $this->lang->zanode->nameValid;
@@ -72,10 +87,10 @@ class zanodemodel extends model
}
/* If name already exists return error. */
$node = $this->dao->select('*')->from(TABLE_ZAHOST)->where('name')->eq($data->name)->andWhere('type')->in('node,physics')->fetch();
$node = $this->dao->select('*')->from(TABLE_ZAHOST)->where('name')->eq($data->name)->andWhere('type')->eq('node')->fetch();
if($node) return dao::$errors[] = $this->lang->zanode->nameUnique;
if($data->type == 'physics')
if($data->hostType == 'physics')
{
$ping = $this->loadModel('zahost')->checkAddress($data->extranet);
if(!$ping)
@@ -181,7 +196,12 @@ class zanodemodel extends model
$result = json_decode(commonModel::http($agnetUrl . static::KVM_EXPORT_PATH, json_encode($param,JSON_NUMERIC_CHECK), null, array("Authorization:$node->tokenSN")));
if(!empty($result) and $result->code == 'success') return $newID;
if(!empty($result) and $result->code == 'success')
{
$this->dao->update(TABLE_HOST)->set('status')->eq(static::STATUS_CREATING_IMG)->where('id')->eq($node->id)->exec();
return $newID;
}
$this->dao->delete()->from(TABLE_IMAGE)->where('id')->eq($newID)->exec();
return false;
@@ -239,11 +259,14 @@ class zanodemodel extends model
if(!empty($result) and $result->code == 'success')
{
$this->loadModel('action')->create('zanode', $zanodeID, 'createdSnapshot', '', $data->name);
$this->dao->update(TABLE_HOST)->set('status')->eq(static::STATUS_CREATING_SNAP)->where('id')->eq($node->id)->exec();
return $newID;
}
$this->dao->delete()->from(TABLE_IMAGE)->where('id')->eq($newID)->exec();
dao::$errors[] = (!empty($result) and !empty($result->msg)) ? $result->msg : $this->app->lang->fail;
return false;
}
@@ -286,11 +309,14 @@ class zanodemodel extends model
if(!empty($result) and $result->code == 'success')
{
$this->dao->update(TABLE_HOST)->set('status')->eq(static::STATUS_CREATING_SNAP)->where('id')->eq($node->id)->exec();
return $newID;
}
$this->dao->delete()->from(TABLE_IMAGE)->where('id')->eq($newID)->exec();
dao::$errors[] = (!empty($result) and !empty($result->msg)) ? $result->msg : $this->app->lang->fail;
return false;
}
@@ -415,6 +441,11 @@ class zanodemodel extends model
{
$node = $this->getNodeByID($id);
if(in_array($node->status, array('restoring', 'creating_img', 'creating_snap')))
{
return sprintf($this->lang->zanode->busy, $this->lang->zanode->statusList[$node->status]);
}
/* Prepare create params. */
$agnetUrl = 'http://' . $node->ip . ':' . $node->hzap;
$path = '/api/v1/kvm/' . $node->name . '/' . $type;
@@ -450,7 +481,7 @@ class zanodemodel extends model
{
$node = $this->getNodeByID($id);
if($node)
if($node && $node->hostType != 'physics')
{
$req = array( 'name' => $node->name );
$agnetUrl = 'http://' . $node->ip . ':' . $node->hzap;
@@ -570,11 +601,11 @@ class zanodemodel extends model
$query = str_replace('`hostID`', 't2.`id`', $query);
}
$list = $this->dao->select("t1.*, t2.name as hostName, if(t1.type='node', t2.extranet, t1.extranet) extranet,if(t1.type='node', t3.osName, t1.osName) osName")->from(TABLE_ZAHOST)->alias('t1')
$list = $this->dao->select("t1.*, t2.name as hostName, if(t1.hostType='', t2.extranet, t1.extranet) extranet,if(t1.hostType='', t3.osName, t1.osName) osName")->from(TABLE_ZAHOST)->alias('t1')
->leftJoin(TABLE_ZAHOST)->alias('t2')->on('t1.parent = t2.id')
->leftJoin(TABLE_IMAGE)->alias('t3')->on('t3.id = t1.image')
->where('t1.deleted')->eq(0)
->andWhere("((t1.type = 'node' and t2.type = 'zahost') or t1.type = 'physics')")
->andWhere("t1.type = 'node'")
->beginIF($query)->andWhere($query)->fi()
->orderBy($orderBy)
->page($pager)
@@ -587,7 +618,9 @@ class zanodemodel extends model
foreach($list as $l)
{
$host = zget($hosts, $l->parent);
$host = $l->hostType == '' ? zget($hosts, $l->parent) : clone $l;
$host->status = in_array($host->status, array('running', 'ready')) ? "online" : $host->status;
if($l->status == 'running' || $l->status == 'ready')
{
if(empty($host))
@@ -598,13 +631,13 @@ class zanodemodel extends model
if($host->status != 'online' || time() - strtotime($host->heartbeat) > 60)
{
$l->status = self::STATUS_SHUTOFF;
$l->status = $l->hostType == '' ? 'wait' : 'offline';
continue;
}
if(time() - strtotime($l->heartbeat) > 60)
{
$l->status = 'wait';
$l->status = $l->hostType == '' ? 'wait' : 'offline';
}
}
}
@@ -622,7 +655,7 @@ class zanodemodel extends model
{
return $this->dao->select('*')->from(TABLE_ZAHOST)
->where('deleted')->eq(0)
->andWhere("type")->eq('node')
->andWhere("type")->in('node,physics')
->orderBy($orderBy)
->fetchAll('id');
}
@@ -638,7 +671,7 @@ class zanodemodel extends model
{
return $this->dao->select('*')->from(TABLE_ZAHOST)
->where('deleted')->eq(0)
->andWhere("type")->eq('node')
->andWhere("type")->in('node,physics')
->orderBy($orderBy)
->fetchPairs('id', 'name');
}
@@ -654,6 +687,8 @@ class zanodemodel extends model
*/
public function getListByHost($hostID, $orderBy = 'id_desc')
{
if(!$hostID) return array();
$list = $this->dao->select('id, name, vnc, cpuCores, memory, diskSize, osName, status, heartbeat')->from(TABLE_ZAHOST)
->where('deleted')->eq(0)
->andWhere("parent")->eq($hostID)
@@ -786,15 +821,17 @@ class zanodemodel extends model
*/
public function getNodeByID($id)
{
$node = $this->dao->select("t1.*, t2.name as hostName, t2.extranet as ip,t2.zap as hzap,if(t1.type='node', t3.osName, t1.osName) osName, t2.tokenSN as tokenSN, t2.secret as secret")->from(TABLE_ZAHOST)
$node = $this->dao->select("t1.*, t2.name as hostName, if(t1.hostType='', t2.extranet, t1.extranet) ip,t2.zap as hzap,if(t1.hostType='', t3.osName, t1.osName) osName, if(t1.hostType='', t2.tokenSN, t1.tokenSN) tokenSN, if(t1.hostType='', t2.secret, t1.secret) secret")->from(TABLE_ZAHOST)
->alias('t1')
->leftJoin(TABLE_ZAHOST)->alias('t2')->on('t1.parent = t2.id')
->leftJoin(TABLE_IMAGE)->alias('t3')->on('t3.id = t1.image')
->where('t1.id')->eq($id)
->fetch();
$host = $this->loadModel("zahost")->getByID($node->type == 'node' ? $node->parent : $node->id);
if($node->status == 'running' || $node->status == 'ready')
$host = $node->hostType == '' ? $this->loadModel("zahost")->getByID($node->parent) : clone $node;
$host->status = in_array($host->status, array('running', 'ready')) ? "online" : $host->status;
if($node->status == 'running' || $node->status == 'ready' || $node->status == 'online')
{
if(empty($host) || $host->status != 'online')
{
@@ -802,7 +839,7 @@ class zanodemodel extends model
}
elseif(time() - strtotime($node->heartbeat) > 60)
{
$node->status = 'wait';
$node->status = $node->hostType == '' ? 'wait' : 'offline';
}
}
@@ -820,8 +857,11 @@ class zanodemodel extends model
$node = $this->dao->select('*')->from(TABLE_ZAHOST)
->where('mac')->eq($mac)
->fetch();
if(empty($node)) return $node;
$host = $node->hostType == '' ? $this->loadModel("zahost")->getByID($node->parent) : $node;
$host->status = in_array($host->status, array('running', 'ready')) ? "online" : $host->status;
$host = $this->loadModel("zahost")->getByID($node->parent);
if($node->status == 'running' || $node->status == 'ready')
{
if(empty($host) || $host->status != 'online')
@@ -1048,6 +1088,7 @@ class zanodemodel extends model
{
$now = helper::now();
$data = fixer::input('post')
->remove('syncToZentao')
->setDefault('createdBy', $this->app->user->account)
->setDefault('createdDate', $now)
->setDefault('node', 0)
@@ -1098,4 +1139,14 @@ class zanodemodel extends model
return dao::$errors = $this->lang->zanode->runTimeout;
}
}
/**
* Sync cases in dir to zentao.
*
* @access public
* @return void
*/
public function syncCasesToZentao($path)
{
}
}
+11 -11
View File
@@ -53,7 +53,7 @@
<tr>
<th class='c-id'><?php common::printOrderLink('t1.id', $orderBy, $vars, $lang->idAB); ?></th>
<th class='c-name'><?php common::printOrderLink('t1.name', $orderBy, $vars, $lang->zanode->name); ?></th>
<th class='c-type hidden'><?php common::printOrderLink('t1.type', $orderBy, $vars, $lang->zahost->type); ?></th>
<th class='c-type'><?php common::printOrderLink('t1.type', $orderBy, $vars, $lang->zahost->type); ?></th>
<th class='c-ip'><?php common::printOrderLink('t1.extranet', $orderBy, $vars, $lang->zanode->extranet); ?></th>
<th class='c-cpu'><?php common::printOrderLink('t1.cpuCores', $orderBy, $vars, $lang->zanode->cpuCores); ?></th>
<th class='c-memory'><?php common::printOrderLink('t1.memory', $orderBy, $vars, $lang->zanode->memory); ?></th>
@@ -69,7 +69,7 @@
<tr>
<td><?php echo $node->id; ?></td>
<td title='<?php echo $node->name ?>'><?php echo html::a($this->inlink('view', "id=$node->id"), $node->name, '', ""); ?></td>
<td class='hidden'><?php echo zget($this->lang->zanode->typeList, $node->type); ?></td>
<td><?php echo $node->hostType == 'physics' ? $this->lang->zanode->typeList['physics'] : $this->lang->zanode->typeList['node']; ?></td>
<td><?php echo $node->extranet; ?></td>
<td><?php echo zget($config->zanode->os->cpuCores, $node->cpuCores); ?></td>
<td><?php echo $node->memory . $this->lang->zahost->unitList['GB']; ?></td>
@@ -80,26 +80,26 @@
<td class='c-actions'>
<?php
$suspendAttr = "title='{$lang->zanode->suspend}' target='hiddenwin'";
$suspendAttr .= $node->type == 'physics' || $node->status != 'running' ? ' class="btn disabled"' : "class='btn' target='hiddenwin' onclick='if(confirm(\"{$lang->zanode->confirmSuspend}\")==false) return false;'";
$suspendAttr .= $node->hostType == 'physics' || $node->status != 'running' ? ' class="btn disabled"' : "class='btn' target='hiddenwin' onclick='if(confirm(\"{$lang->zanode->confirmSuspend}\")==false) return false;'";
$resumeAttr = "title='{$lang->zanode->resume}' target='hiddenwin'";
$resumeAttr .= $node->type == 'physics' || $node->status == 'running' || $node->status == 'wait' ? ' class="btn disabled"' : "class='btn' target='hiddenwin' onclick='if(confirm(\"{$lang->zanode->confirmResume}\")==false) return false;'";
$resumeAttr .= $node->hostType == 'physics' || $node->status == 'running' || $node->status == 'wait' ? ' class="btn disabled"' : "class='btn' target='hiddenwin' onclick='if(confirm(\"{$lang->zanode->confirmResume}\")==false) return false;'";
$rebootAttr = "title='{$lang->zanode->reboot}' target='hiddenwin'";
$rebootAttr .= $node->type == 'physics' || $node->status == 'shutoff' || $node->status == 'wait' ? ' class="btn disabled"' : "class='btn' target='hiddenwin' onclick='if(confirm(\"{$lang->zanode->confirmReboot}\")==false) return false;'";
$rebootAttr .= $node->hostType == 'physics' || in_array($node->status, array('wait', 'creating_img', 'creating_snap', 'restoring', 'shutoff')) ? ' class="btn disabled"' : "class='btn' target='hiddenwin' onclick='if(confirm(\"{$lang->zanode->confirmReboot}\")==false) return false;'";
$closeAttr = "title='{$lang->zanode->shutdown}'";
$closeAttr .= $node->type == 'physics' || $node->status == 'wait' ? ' class="btn disabled"' : ' class="btn iframe"';
$closeAttr .= $node->hostType == 'physics' || in_array($node->status, array('wait', 'creating_img', 'creating_snap', 'restoring')) ? ' class="btn disabled"' : ' class="btn iframe"';
$startAttr = "title='{$lang->zanode->boot}'";
$startAttr .= $node->type == 'physics' || $node->status == 'wait' ? ' class="btn disabled"' : ' class="btn iframe"';
$startAttr .= $node->hostType == 'physics' || in_array($node->status, array('wait', 'creating_img', 'creating_snap', 'restoring')) ? ' class="btn disabled"' : ' class="btn iframe"';
$snapshotAttr = "title='{$lang->zanode->createSnapshot}'";
$snapshotAttr .= $node->type == 'physics' || $node->status != 'running' ? ' class="btn disabled"' : ' class="btn iframe"';
$snapshotAttr .= $node->hostType == 'physics' || $node->status != 'running' ? ' class="btn disabled"' : ' class="btn iframe"';
$imageAttr = $node->status != 'running' ? ' class="btn btn-action iframe createImage disabled"' : ' class="btn btn-action iframe createImage"';
$imageAttr = $node->hostType == 'physics' || $node->status != 'running' && $node->status != 'creating_img' ? ' class="btn btn-action iframe createImage disabled"' : ' class="btn btn-action iframe createImage"';
common::printLink('zanode', 'getVNC', "id={$node->id}", "<i class='icon icon-remote'></i> ", (in_array($node->status ,array('running', 'launch', 'wait')) ? '_blank' : ''), "title='{$lang->zanode->getVNC}' class='btn desktop " . (in_array($node->status ,array('running', 'launch', 'wait')) ? '':'disabled') . "'", '');
common::printLink('zanode', 'getVNC', "id={$node->id}", "<i class='icon icon-remote'></i> ", (in_array($node->status ,array('running', 'launch', 'wait')) ? '_blank' : ''), "title='{$lang->zanode->getVNC}' class='btn desktop " . ($node->hostType == '' && in_array($node->status ,array('running', 'launch', 'wait')) ? '':'disabled') . "'", '');
if($node->status == "suspend")
{
common::printLink('zanode', 'resume', "zanodeID={$node->id}", "<i class='icon icon-resume'></i> ", '', $resumeAttr);
@@ -119,7 +119,7 @@
}
common::printLink('zanode', 'reboot', "zanodeID={$node->id}", "<i class='icon icon-restart'></i> ", '', $rebootAttr);
common::printLink('zanode', 'createSnapshot', "zanodeID={$node->id}", "<i class='icon icon-plus'></i> ", '', $snapshotAttr, true, true);
common::printLink('zanode', 'createSnapshot', "zanodeID={$node->id}", "<img src='static/svg/snapshot.svg' /> ", '', $snapshotAttr, true, true);
if(common::hasPriv('zanode', 'createImage') or common::hasPriv('zanode', 'destroy'))
{
+10 -6
View File
@@ -13,6 +13,8 @@
<?php include '../../common/view/header.html.php';?>
<?php include $app->getModuleRoot() . 'common/view/kindeditor.html.php';?>
<?php js::set('hostID', $hostID);?>
<?php js::set('linuxList', $config->zanode->linuxList);?>
<?php js::set('windowsList', $config->zanode->windowsList);?>
<div id='mainContent' class='main-row'>
<div class='main-col main-content'>
<div class='center-block'>
@@ -22,15 +24,15 @@
</div>
<form method='post' target='hiddenwin' id='ajaxForm' class="load-indicator main-form form-ajax">
<table class='table table-form'>
<tr class='hidden'>
<tr>
<th><?php echo $lang->zahost->type;?></th>
<td><?php echo html::select('type', $lang->zanode->typeList, 'virtual', "class='form-control chosen' onchange='zahostType()'")?></td>
<td><?php echo html::select('hostType', $lang->zanode->typeList, 'virtual', "class='form-control chosen' onchange='zanodeType()'")?></td>
<td></td>
</tr>
<tr>
<th><?php echo $lang->zanode->hostName;?></th>
<td><?php echo html::select('parent', $hostPairs, $hostID, "class='form-control chosen'")?></td>
<td></td>
<td id='hostIdBox'><?php echo html::select('parent', $hostPairs, $hostID, "class='form-control chosen'")?></td>
<td><?php echo html::a($this->createLink('zahost', 'create', array(), '', true), $lang->zahost->create, '', "class='text-primary iframe'");?></td>
</tr>
<tr>
<th class='w-120px'><?php echo $lang->zanode->name;?></th>
@@ -71,8 +73,10 @@
<tr>
<th><?php echo $lang->zanode->osName;?></th>
<td>
<?php echo html::input('osName', '', "class='form-control' readonly='readonly'")?>
<?php echo html::input('osNamePhysics', '', "class='form-control hidden'")?>
<?php echo html::input('osName', '', "class='form-control' readonly='readonly' onchange='zanodeOsChange()'")?>
<div id="osNamePhysicsContainer" class="hidden">
<?php echo html::select('', $config->zanode->osType, 'linux', "class='form-control' id='osNamePhysicsPre'") . html::select('osNamePhysics', $config->zanode->linuxList, '', "class='form-control chosen'"); ?>
</div>
</td>
</tr>
<tr>
+5 -5
View File
@@ -21,7 +21,7 @@
</div>
<form method='post' target='hiddenwin' id='ajaxForm' class="load-indicator main-form form-ajax">
<table class='table table-form'>
<?php if($zanode->type == 'node'):?>
<?php if($zanode->hostType != 'physics'):?>
<tr>
<th><?php echo $lang->zanode->hostName;?></th>
<td class='p-25f'><?php echo html::input('', $host->name, "class='form-control' readonly='readonly'");?></td>
@@ -29,17 +29,17 @@
<?php endif;?>
<tr>
<th class='w-120px'><?php echo $lang->zanode->name;?></th>
<td class='p-25f'><?php echo html::input('name', $zanode->name, "class='form-control' placeholder=\"{$lang->zanode->nameValid}\" readonly='readonly'");?></td>
<td class='p-25f'><?php echo html::input('name', $zanode->name, "class='form-control' placeholder=\"{$lang->zanode->nameValid}\" " . ($zanode->hostType != 'physics' ? "readonly='readonly'" : ''));?></td>
<td></td>
</tr>
<?php if($zanode->type == 'node'):?>
<?php if($zanode->hostType != 'physics'):?>
<tr>
<th><?php echo $lang->zanode->image;?></th>
<td class='p-25f'><?php echo html::input('', $image->name, "class='form-control' readonly='readonly'");?></td>
</tr>
<?php else:?>
<tr>
<th class='w-120px'><?php echo $lang->zahost->IP;?></th>
<th class='w-120px'><?php echo $lang->zanode->IP;?></th>
<td class='p-25f'><?php echo html::input('extranet', $zanode->extranet, "class='form-control' readonly='readonly'");?></td>
</tr>
<?php endif;?>
@@ -69,7 +69,7 @@
</tr>
<tr>
<th><?php echo $lang->zanode->osName;?></th>
<td><?php echo html::input('osName', $zanode->osName, "class='form-control' readonly='readonly'")?></td>
<td><?php echo html::input('osName', $zanode->hostType != 'physics' ? $zanode->osName : zget($config->zanode->linuxList, $zanode->osName, zget($config->zanode->windowsList, $zanode->osName)), "class='form-control' readonly='readonly'")?></td>
</tr>
<tr>
<th><?php echo $lang->zanode->desc ?></th>
+93 -21
View File
@@ -21,11 +21,13 @@
<?php js::set('nodeID', $zanode->id) ?>
<?php js::set('zanodeLang', $lang->zanode); ?>
<?php js::set('nodeStatus', $zanode->status); ?>
<?php js::set('hostType', $zanode->hostType); ?>
<?php js::set('webRoot', getWebRoot());?>
<?php $browseLink = $this->session->zanodeList ? $this->session->zanodeList : $this->createLink('zanode', 'browse', ""); ?>
<?php $browseLink = $this->session->zanodeList ? $this->session->zanodeList : $this->createLink('zanode', 'browse', "");?>
<?php
$vars = "id={$zanode->id}&orderBy=%s";
$account = strpos($zanode->osName, "windows") ? $config->zanode->defaultWinAccount : $config->zanode->defaultAccount;
$ssh = $zanode->hostType == 'physics' ? ('ssh ' . $zanode->extranet) : ($zanode->ssh ? 'ssh ' . $account . '@' . $zanode->ip . ' -p ' . $zanode->ssh : '');
?>
<div id='mainMenu' class='clearfix'>
<div class='btn-toolbar pull-left'>
@@ -43,8 +45,56 @@ $account = strpos($zanode->osName, "windows") ? $config->zanode->defaultWinAccou
<div id='mainContent' class='main-row'>
<div class="col-8 main-col">
<div class="cell">
<?php if($zanode->hostType == 'physics'):?>
<div class="detail zanode-detail">
<div class="detail-title"><?php echo $lang->zahost->baseInfo; ?></div>
<div class="detail-title"><?php echo $lang->zanode->baseInfo; ?></div>
<div class="detail-content article-content">
<div class="main-row zanode-mt-8">
<div class="col-4">
<div class="main-row">
<div class="col-4 text-right"><?php echo $lang->zanode->osName; ?>:</div>
<div class="col-7"><?php echo zget($config->zanode->linuxList, $zanode->osName, zget($config->zanode->windowsList, $zanode->osName)); ?></div>
</div>
</div>
<div class="col-4">
<div class="main-row">
<div class="col-3 text-right"><?php echo $lang->zanode->sshAddress; ?>:</div>
<div class="col-8 node-not-wrap"><?php echo $ssh;?><?php echo $ssh ? " <button type='button' class='btn btn-info btn-mini btn-ssh-copy'><i class='icon-common-copy icon-copy' title='" . $lang->zanode->copy . "'></i></button>" : ''; ?></div>
</div>
<textarea style="display:none;" id="ssh-copy"><?php echo $ssh; ?></textarea>
</div>
<div class="col-4">
<div class="main-row">
<div class="col-3 text-right"><?php echo $lang->zanode->cpuCores; ?>:</div>
<div class="col-8"><?php echo $zanode->cpuCores . ' ' . $lang->zanode->cpuUnit; ?></div>
</div>
</div>
</div>
<div class="main-row zanode-mt-8">
<div class="col-4">
<div class="main-row">
<div class="col-4 text-right"><?php echo $lang->zanode->status; ?>:</div>
<div class="col-7"><?php echo zget($lang->zanode->statusList, $zanode->status); ?></div>
</div>
</div>
<div class="col-4">
<div class="main-row">
<div class="col-3 text-right"><?php echo $lang->zanode->memory; ?>:</div>
<div class="col-8"><?php echo $zanode->memory; ?>&nbsp;GB</div>
</div>
</div>
<div class="col-4">
<div class="main-row">
<div class="col-3 text-right"><?php echo $lang->zanode->diskSize; ?>:</div>
<div class="col-8"><?php echo $zanode->diskSize; ?>&nbsp;GB</div>
</div>
</div>
</div>
</div>
</div>
<?php else: ?>
<div class="detail zanode-detail">
<div class="detail-title"><?php echo $lang->zanode->baseInfo; ?></div>
<div class="detail-content article-content">
<div class="main-row zanode-mt-8">
<div class="col-4">
@@ -55,15 +105,15 @@ $account = strpos($zanode->osName, "windows") ? $config->zanode->defaultWinAccou
</div>
<div class="col-4">
<div class="main-row">
<div class="col-3 text-right"><?php echo $lang->zanode->sshAddress; ?>:</div>
<div class="col-8 node-not-wrap"><?php echo $zanode->ssh ? 'ssh ' . $account . '@' . $zanode->ip . ' -p ' . $zanode->ssh : ''; ?><?php echo $zanode->ssh ? " <button type='button' class='btn btn-info btn-mini btn-ssh-copy'><i class='icon-common-copy icon-copy' title='" . $lang->zanode->copy . "'></i></button>" : ''; ?></div>
<div class="col-3 text-right"><?php echo $lang->zanode->sshCommand; ?>:</div>
<div class="col-8 node-not-wrap"><?php echo $ssh;?><?php echo $ssh ? " <button type='button' class='btn btn-info btn-mini btn-ssh-copy'><i class='icon-common-copy icon-copy' title='" . $lang->zanode->copy . "'></i></button>" : ''; ?></div>
</div>
<textarea style="display:none;" id="ssh-copy">ssh <?php echo $account . '@' . $zanode->ip . ' -p ' . $zanode->ssh; ?></textarea>
<textarea style="display:none;" id="ssh-copy"><?php echo $ssh; ?></textarea>
</div>
<div class="col-4">
<div class="main-row">
<div class="col-3 text-right"><?php echo $lang->zanode->cpuCores; ?>:</div>
<div class="col-8"><?php echo $zanode->cpuCores . ' ' . $lang->zahost->cpuUnit; ?></div>
<div class="col-8"><?php echo $zanode->cpuCores . ' ' . $lang->zanode->cpuUnit; ?></div>
</div>
</div>
</div>
@@ -116,6 +166,7 @@ $account = strpos($zanode->osName, "windows") ? $config->zanode->defaultWinAccou
</div>
</div>
</div>
<?php endif ?>
<div class="detail zanode-detail">
<div class="detail-title"><?php echo $lang->zanode->desc; ?></div>
<div class="detail-content article-content"><?php echo !empty($zanode->desc) ? htmlspecialchars_decode($zanode->desc) : $lang->noData; ?></div>
@@ -132,31 +183,52 @@ $account = strpos($zanode->osName, "windows") ? $config->zanode->defaultWinAccou
<?php echo $lang->zanode->init->statusTitle; ?>
<button type='button' id='checkServiceStatus' class='btn btn-info'><i class="icon icon-refresh"></i> <span class='checkStatus'><?php echo $lang->zanode->init->checkStatus;?></span></button>
</div>
<div class="detail-content statusContainer load-indicator" id='serviceContent'>
<div class="detail-content article-content statusContainer load-indicator" id='serviceContent'>
<?php if($zanode->hostType != 'physics'):?>
<div class="service-status hide">
<span class='dot-symbol dot-zenagent text-danger'></span>
<span>&nbsp;&nbsp;ZenAgent &nbsp;
<span>&nbsp;ZenAgent &nbsp;
<span class="zenagent-status"><?php echo $lang->zanode->initializing; ?></span>
</span>
</div>
<?php endif ?>
<div class="service-status hide">
<span class='dot-symbol dot-ztf text-danger'></span>
<span>&nbsp;&nbsp;ZTF &nbsp;
<span>&nbsp;ZTF &nbsp;
<span class="ztf-status"><?php echo $lang->zanode->initializing; ?></span>&nbsp;
<a class='node-init-install hide' target='hiddenwin' href='javascript:;' data-href='<?php echo $this->createLink('zanode', 'ajaxInstallService', 'nodeID=' . $zanode->id . '&service=ztf');?>'><i class="icon icon-download icon-sm ztf-install-icon"></i><span class="ztf-install"><?php echo $lang->zanode->install ?></span></a>
</span>
</div>
<div class="status-notice hide">
<span class='init-success hide'><?php echo sprintf($lang->zanode->init->initSuccessNoticeTitle, "<a id='jumpManual' href='javascript:;'>{$lang->zanode->manual}</a>", html::a(helper::createLink('testcase', 'automation', "", '', true), $lang->zanode->automation, '', "class='iframe' title='{$lang->zanode->automation}' data-width='50%'", '')); ?></span>
<span class='init-fail hide'><?php echo $lang->zanode->init->initFailNoticeTitle . '<br/>' . $lang->zanode->init->initFailNoticeDesc;?></span>
<span class='init-success hide'><?php echo sprintf($lang->zanode->init->initSuccessNoticeTitle, "<a id='jumpManual' href='javascript:;'>{$lang->zanode->manual}</a>", html::a(helper::createLink('testcase', 'automation', "", '', true), $lang->zanode->automation, '', "class='iframe' title='{$lang->zanode->automation}' data-width='800px'", '')); ?></span>
<?php if($zanode->hostType == 'physics'):?>
<div class='hide init-fail'>
<?php echo $zanode->hostType == 'physics' ? $lang->zanode->init->initFailNoticeOnPhysics : $lang->zanode->init->initFailNotice;?>
<textarea style="display:none;" id="initBash"><?php echo $initBash; ?></textarea>
<div class="zanode-init">
<?php echo "$initBash <button type='button' class='btn btn-info btn-mini btn-init-copy'><i class='icon-common-copy icon-copy' title='" . $lang->zanode->copy . "'></i></button>"; ?>
</div>
</div>
<?php endif?>
</div>
</div>
</div>
</div>
<?php if(common::hasPriv('zanode', 'browseSnapshot')):?>
<?php if(common::hasPriv('zanode', 'browseSnapshot') && $zanode->hostType == ''):?>
<div class="cell">
<div class="detail zanode-detail">
<div class="detail-title"><?php echo $lang->zanode->browseSnapshot;?></div>
<div class="detail-title">
<?php echo $lang->zanode->browseSnapshot;?>
<div class="btn-toolbar pull-right" id='createActionMenu'>
<?php
if($zanode->status == 'running'){
$snapshotAttr = "title='{$lang->zanode->createSnapshot}'";
$snapshotAttr .= $zanode->status != 'running' ? ' class="btn btn-snap-create disabled"' : ' class="btn btn-primary btn-snap-create iframe"';
common::printLink('zanode', 'createSnapshot', "zanodeID={$zanode->id}", "<i class='icon icon-plus'></i> " . $lang->zanode->createSnapshot, '', $snapshotAttr, true, true);
}
?>
</div>
</div>
<?php if(!empty($snapshotList)): ?>
<div class="detail-content article-content">
<?php echo "<iframe width='100%' id='nodesIframe' src='" . $this->createLink('zanode', 'browseSnapshot', "nodeID=$zanode->id", '', true) . "' frameborder='no' allowfullscreen='true' mozallowfullscreen='true' webkitallowfullscreen='true' allowtransparency='true' scrolling='auto' style='min-height:300px;'></iframe>";?>
@@ -175,23 +247,23 @@ $account = strpos($zanode->osName, "windows") ? $config->zanode->defaultWinAccou
<?php
if (empty($zanode->deleted)) {
$suspendAttr = "title='{$lang->zanode->suspend}' target='hiddenwin'";
$suspendAttr .= $zanode->status != 'running' ? ' class="btn disabled"' : "class='btn' target='hiddenwin' onclick='if(confirm(\"{$lang->zanode->confirmSuspend}\")==false) return false;'";
$suspendAttr .= $zanode->hostType == 'physics' || $zanode->status != 'running' ? ' class="btn disabled"' : "class='btn' target='hiddenwin' onclick='if(confirm(\"{$lang->zanode->confirmSuspend}\")==false) return false;'";
$resumeAttr = "title='{$lang->zanode->resume}' target='hiddenwin'";
$resumeAttr .= $zanode->status == 'running' ? ' class="btn disabled"' : "class='btn' target='hiddenwin' onclick='if(confirm(\"{$lang->zanode->confirmResume}\")==false) return false;'";
$resumeAttr .= $zanode->hostType == 'physics' || $zanode->status == 'running' ? ' class="btn disabled"' : "class='btn' target='hiddenwin' onclick='if(confirm(\"{$lang->zanode->confirmResume}\")==false) return false;'";
$rebootAttr = "title='{$lang->zanode->reboot}' target='hiddenwin'";
$rebootAttr .= $zanode->status == 'shutoff' || $zanode->status == 'wait' ? ' class="btn disabled"' : "class='btn' target='hiddenwin' onclick='if(confirm(\"{$lang->zanode->confirmReboot}\")==false) return false;'";
$rebootAttr .= $zanode->hostType == 'physics' || in_array($zanode->status, array('wait', 'creating_img', 'creating_snap', 'restoring', 'shutoff')) ? ' class="btn disabled"' : "class='btn' target='hiddenwin' onclick='if(confirm(\"{$lang->zanode->confirmReboot}\")==false) return false;'";
$closeAttr = "title='{$lang->zanode->shutdown}'";
$closeAttr .= $zanode->status == 'wait' ? ' class="btn disabled"' : ' class="btn iframe"';
$closeAttr .= $zanode->hostType == 'physics' || in_array($zanode->status, array('wait', 'creating_img', 'creating_snap', 'restoring')) ? ' class="btn disabled"' : ' class="btn iframe"';
$startAttr = "title='{$lang->zanode->boot}'";
$startAttr .= $zanode->status == 'wait' ? ' class="btn disabled"' : ' class="btn iframe"';
$startAttr .= $zanode->hostType == 'physics' || in_array($zanode->status, array('wait', 'creating_img', 'creating_snap', 'restoring')) ? ' class="btn disabled"' : ' class="btn iframe"';
$snapshotAttr = "title='{$lang->zanode->createSnapshot}'";
$snapshotAttr .= $zanode->status != 'running' ? ' class="btn disabled"' : ' class="btn iframe"';
common::printLink('zanode', 'getVNC', "id={$zanode->id}", "<i class='icon icon-remote'></i> " . $lang->zanode->getVNC, in_array($zanode->status ,array('running', 'launch', 'wait')) ? '_blank' : '', "title='{$lang->zanode->getVNC}' class='btn desktop " . (in_array($zanode->status ,array('running', 'launch', 'wait')) ? '':'disabled') . "'", '');
$snapshotAttr .= $zanode->hostType == 'physics' || $zanode->status != 'running' ? ' class="btn disabled"' : ' class="btn iframe"';
common::printLink('zanode', 'getVNC', "id={$zanode->id}", "<i class='icon icon-remote'></i> " . $lang->zanode->getVNC, in_array($zanode->status ,array('running', 'launch', 'wait')) ? '_blank' : '', "title='{$lang->zanode->getVNC}' class='btn desktop " . ($zanode->hostType == '' && in_array($zanode->status ,array('running', 'launch', 'wait')) ? '':'disabled') . "'", '');
if($zanode->status == "suspend")
{
@@ -212,7 +284,7 @@ $account = strpos($zanode->osName, "windows") ? $config->zanode->defaultWinAccou
}
common::printLink('zanode', 'reboot', "zanodeID={$zanode->id}", "<i class='icon icon-restart'></i> " . $lang->zanode->rebootNode, '', $rebootAttr);
common::printLink('zanode', 'createSnapshot', "zanodeID={$zanode->id}", "<i class='icon icon-plus'></i> " . $lang->zanode->createSnapshot, '', $snapshotAttr, true, true);
common::printLink('zanode', 'createSnapshot', "zanodeID={$zanode->id}", "<img src='static/svg/snapshot.svg' /> " . $lang->zanode->createSnapshot, '', $snapshotAttr, true, true);
}
?>
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
var T=Object.defineProperty;var a=Object.getOwnPropertySymbols;var h=Object.prototype.hasOwnProperty,l=Object.prototype.propertyIsEnumerable;var r=(e,t,s)=>t in e?T(e,t,{enumerable:!0,configurable:!0,writable:!0,value:s}):e[t]=s,i=(e,t)=>{for(var s in t||(t={}))h.call(t,s)&&r(e,s,t[s]);if(a)for(var s of a(t))l.call(t,s)&&r(e,s,t[s]);return e};import{c1 as g,aA as p,D as u,S as y}from"./index.js";import{u as A}from"./chartEditStore-e8b17db2.js";var n=(e=>(e.SINGLE="single",e.DOUBLE="double",e))(n||{}),c=(e=>(e.THUMBNAIL="thumbnail",e.TEXT="text",e))(c||{}),S=(e=>(e.LAYERS="layers",e.CHARTS="charts",e.DETAILS="details",e.Chart_TYPE="chartType",e.LAYER_TYPE="layerType",e.PERCENTAGE="percentage",e.RE_POSITION_CANVAS="rePositionCanvas",e))(S||{});const C=A(),{GO_CHART_LAYOUT_STORE:o}=y,L=g(o),d=p({id:"useChartLayoutStore",state:()=>i({layers:!0,charts:!0,details:!1,chartType:n.SINGLE,layerType:c.THUMBNAIL,percentage:0,rePositionCanvas:!1},L),getters:{getLayers(){return this.layers},getCharts(){return this.charts},getDetails(){return this.details},getChartType(){return this.chartType},getLayerType(){return this.layerType},getPercentage(){return this.percentage},getRePositionCanvas(){return this.rePositionCanvas}},actions:{setItem(e,t){this.$patch(s=>{s[e]=t}),u(o,this.$state),this.rePositionCanvas=!0,setTimeout(()=>{C.computedScale()},500)},setItemUnHandle(e,t){this.$patch(s=>{s[e]=t})}}});export{S as C,c as L,n as a,d as u};
var T=Object.defineProperty;var a=Object.getOwnPropertySymbols;var h=Object.prototype.hasOwnProperty,l=Object.prototype.propertyIsEnumerable;var r=(e,t,s)=>t in e?T(e,t,{enumerable:!0,configurable:!0,writable:!0,value:s}):e[t]=s,i=(e,t)=>{for(var s in t||(t={}))h.call(t,s)&&r(e,s,t[s]);if(a)for(var s of a(t))l.call(t,s)&&r(e,s,t[s]);return e};import{c1 as g,aA as p,D as u,S as y}from"./index.js";import{u as A}from"./chartEditStore-18a9cd2a.js";var n=(e=>(e.SINGLE="single",e.DOUBLE="double",e))(n||{}),c=(e=>(e.THUMBNAIL="thumbnail",e.TEXT="text",e))(c||{}),S=(e=>(e.LAYERS="layers",e.CHARTS="charts",e.DETAILS="details",e.Chart_TYPE="chartType",e.LAYER_TYPE="layerType",e.PERCENTAGE="percentage",e.RE_POSITION_CANVAS="rePositionCanvas",e))(S||{});const C=A(),{GO_CHART_LAYOUT_STORE:o}=y,L=g(o),d=p({id:"useChartLayoutStore",state:()=>i({layers:!0,charts:!0,details:!1,chartType:n.SINGLE,layerType:c.THUMBNAIL,percentage:0,rePositionCanvas:!1},L),getters:{getLayers(){return this.layers},getCharts(){return this.charts},getDetails(){return this.details},getChartType(){return this.chartType},getLayerType(){return this.layerType},getPercentage(){return this.percentage},getRePositionCanvas(){return this.rePositionCanvas}},actions:{setItem(e,t){this.$patch(s=>{s[e]=t}),u(o,this.$state),this.rePositionCanvas=!0,setTimeout(()=>{C.computedScale()},500)},setItemUnHandle(e,t){this.$patch(s=>{s[e]=t})}}});export{S as C,c as L,n as a,d as u};
@@ -1 +1 @@
var f=Object.defineProperty,l=Object.defineProperties;var m=Object.getOwnPropertyDescriptors;var o=Object.getOwnPropertySymbols;var u=Object.prototype.hasOwnProperty,d=Object.prototype.propertyIsEnumerable;var p=(e,t,i)=>t in e?f(e,t,{enumerable:!0,configurable:!0,writable:!0,value:i}):e[t]=i,r=(e,t)=>{for(var i in t||(t={}))u.call(t,i)&&p(e,i,t[i]);if(o)for(var i of o(t))d.call(t,i)&&p(e,i,t[i]);return e},s=(e,t)=>l(e,m(t));import{ax as h,al as a}from"./index.js";import{e as c}from"./chartEditStore-e8b17db2.js";import{c as n}from"./index-2b081abf.js";import"./plugin-20889218.js";import"./icon-1e77a86f.js";import"./chartLayoutStore-aa494572.js";import"./tables_list-16bd57ab.js";/* empty css */import"./SettingItemBox-4bb8b904.js";import"./CollapseItem-d1c7c015.js";import"./useTargetData.hook-48477efe.js";const g={dataset:10*60,useEndDate:!1,endDate:new Date().getTime(),style:"\u65F6\u5206\u79D2",showDay:!1,flipperBgColor:"#16293E",flipperTextColor:"#4A9EF8FF",flipperWidth:30,flipperHeight:50,flipperRadius:5,flipperGap:10,flipperType:"down",flipperSpeed:450};class A extends c{constructor(){super(...arguments),this.key=n.key,this.attr=s(r({},h),{w:500,h:100,zIndex:-1}),this.chartConfig=a(n),this.option=a(g)}}export{A as default,g as option};
var f=Object.defineProperty,l=Object.defineProperties;var m=Object.getOwnPropertyDescriptors;var o=Object.getOwnPropertySymbols;var u=Object.prototype.hasOwnProperty,d=Object.prototype.propertyIsEnumerable;var p=(e,t,i)=>t in e?f(e,t,{enumerable:!0,configurable:!0,writable:!0,value:i}):e[t]=i,r=(e,t)=>{for(var i in t||(t={}))u.call(t,i)&&p(e,i,t[i]);if(o)for(var i of o(t))d.call(t,i)&&p(e,i,t[i]);return e},s=(e,t)=>l(e,m(t));import{ax as h,al as a}from"./index.js";import{e as c}from"./chartEditStore-18a9cd2a.js";import{c as n}from"./index-4ac03131.js";import"./plugin-0871c0c4.js";import"./icon-25a9ceb8.js";import"./chartLayoutStore-4e5e7e9d.js";import"./tables_list-16bd57ab.js";/* empty css */import"./SettingItemBox-1d5230ce.js";import"./CollapseItem-7bbde778.js";import"./useTargetData.hook-c3393be6.js";const g={dataset:10*60,useEndDate:!1,endDate:new Date().getTime(),style:"\u65F6\u5206\u79D2",showDay:!1,flipperBgColor:"#16293E",flipperTextColor:"#4A9EF8FF",flipperWidth:30,flipperHeight:50,flipperRadius:5,flipperGap:10,flipperType:"down",flipperSpeed:450};class A extends c{constructor(){super(...arguments),this.key=n.key,this.attr=s(r({},h),{w:500,h:100,zIndex:-1}),this.chartConfig=a(n),this.option=a(g)}}export{A as default,g as option};
@@ -1 +1 @@
import{al as o}from"./index.js";import{e as t}from"./chartEditStore-e8b17db2.js";import{N as r}from"./index-2b081abf.js";import"./plugin-20889218.js";import"./icon-1e77a86f.js";import"./chartLayoutStore-aa494572.js";import"./tables_list-16bd57ab.js";/* empty css */import"./SettingItemBox-4bb8b904.js";import"./CollapseItem-d1c7c015.js";import"./useTargetData.hook-48477efe.js";const e={dataset:1e5,from:0,dur:3,precision:0,showSeparator:!0,numberSize:34,numberColor:"#4a9ef8",prefixText:"\uFFE5",prefixColor:"#4a9ef8",suffixText:"\u5143",suffixColor:"#4a9ef8"};class g extends t{constructor(){super(...arguments),this.key=r.key,this.chartConfig=o(r),this.option=o(e)}}export{g as default,e as option};
import{al as o}from"./index.js";import{e as t}from"./chartEditStore-18a9cd2a.js";import{N as r}from"./index-4ac03131.js";import"./plugin-0871c0c4.js";import"./icon-25a9ceb8.js";import"./chartLayoutStore-4e5e7e9d.js";import"./tables_list-16bd57ab.js";/* empty css */import"./SettingItemBox-1d5230ce.js";import"./CollapseItem-7bbde778.js";import"./useTargetData.hook-c3393be6.js";const e={dataset:1e5,from:0,dur:3,precision:0,showSeparator:!0,numberSize:34,numberColor:"#4a9ef8",prefixText:"\uFFE5",prefixColor:"#4a9ef8",suffixText:"\u5143",suffixColor:"#4a9ef8"};class g extends t{constructor(){super(...arguments),this.key=r.key,this.chartConfig=o(r),this.option=o(e)}}export{g as default,e as option};
@@ -1 +1 @@
import{al as o}from"./index.js";import{e as t}from"./chartEditStore-e8b17db2.js";import{C as r}from"./index-2b081abf.js";import"./plugin-20889218.js";import"./icon-1e77a86f.js";import"./chartLayoutStore-aa494572.js";import"./tables_list-16bd57ab.js";/* empty css */import"./SettingItemBox-4bb8b904.js";import"./CollapseItem-d1c7c015.js";import"./useTargetData.hook-48477efe.js";const i={border:6,color:"#ffffff",bgColor:"#84a5e9",borderColor:"#ffffff"};class b extends t{constructor(){super(...arguments),this.key=r.key,this.chartConfig=o(r),this.option=o(i)}}export{b as default,i as option};
import{al as o}from"./index.js";import{e as t}from"./chartEditStore-18a9cd2a.js";import{C as r}from"./index-4ac03131.js";import"./plugin-0871c0c4.js";import"./icon-25a9ceb8.js";import"./chartLayoutStore-4e5e7e9d.js";import"./tables_list-16bd57ab.js";/* empty css */import"./SettingItemBox-1d5230ce.js";import"./CollapseItem-7bbde778.js";import"./useTargetData.hook-c3393be6.js";const i={border:6,color:"#ffffff",bgColor:"#84a5e9",borderColor:"#ffffff"};class b extends t{constructor(){super(...arguments),this.key=r.key,this.chartConfig=o(r),this.option=o(i)}}export{b as default,i as option};

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