* Adjust code.

This commit is contained in:
zenggang
2023-08-28 01:55:48 +00:00
parent 8d26480b51
commit 975be8529a
16 changed files with 541 additions and 4 deletions

View File

@@ -88,6 +88,8 @@ CREATE TABLE `zt_artifactrepo` (
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
ALTER TABLE `zt_build` ADD `artifactRepoID` MEDIUMINT(8) UNSIGNED NOT NULL AFTER `bugs`;
ALTER TABLE `zt_host` ADD COLUMN `product` varchar(255) NOT NULL DEFAULT '' AFTER `hostType`,ADD COLUMN `testType` varchar(10) NOT NULL DEFAULT '' AFTER `product`;
UPDATE `zt_host` SET `testType`='kvm',`type`='normal' WHERE `type`='zahost';
UPDATE `zt_host` SET `testType`='node',`type`='normal',`hostType`='physical' WHERE `type`='node' AND `parent`=0;

View File

@@ -353,6 +353,7 @@ CREATE TABLE IF NOT EXISTS `zt_build` (
`date` date NULL,
`stories` text NULL,
`bugs` text NULL,
`artifactRepoID` mediumint(8) unsigned NOT NULL,
`builder` char(30) NOT NULL default '',
`desc` mediumtext NULL,
`createdBy` varchar(30) NOT NULL DEFAULT '',

View File

@@ -66,7 +66,7 @@ class artifactrepo extends control
if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
$this->loadModel('action')->create('artifactRepo', $repoID, 'created');
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => inlink('browse')));
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'load' => inlink('browse')));
}
$nexusList = $this->loadModel('pipeline')->getPairs('nexus');

View File

@@ -138,8 +138,6 @@ class artifactrepoModel extends model
->leftJoin(TABLE_PIPELINE)->alias('t2')->on('t1.serverID = t2.id')
->where('products')->like("%,{$productID},%")
->andWhere('t1.deleted')->eq(0)
->orderBy($orderBy)
->page($pager)
->fetchAll('id');
foreach($artifactRepos as $repo)
{

View File

@@ -111,6 +111,17 @@ class build extends control
foreach($productGroups as $product) $products[$product->id] = $product->name;
if(!$this->view->hidden && $products)
{
$this->loadModel('artifactrepo');
$productArtifactRepos = array();
foreach($products as $ID => $productName)
{
$productArtifactRepos[$ID] = $this->artifactrepo->getReposByProduct($ID);
}
$this->view->productArtifactRepos = $productArtifactRepos;
}
$this->view->title = $this->lang->build->create;
$this->view->position[] = $this->lang->build->create;

View File

@@ -0,0 +1,250 @@
$().ready(function()
{
new zui.Tooltip('#tooltipHover', {title: autoRelationTip, trigger: 'hover', placement: 'right', type: 'white', 'className': 'text-gray border border-light'});
$(document).on('click', '#lastBuildBtn', function()
{
$('#name').val($(this).text());
});
$(document).off('change', '#product, #branch').on('change', '#product, #branch', function()
{
let projectID = $('input[name=project]').val();
let productID = $('input[name=product]').val();
$.get($.createLink('build', 'ajaxGetProjectBuilds', 'projectID=' + projectID + '&productID=' + productID + '&letName=builds&build=&branch=all&index=&needCreate=&type=noempty,notrunk,separate,singled&extra=multiple'), function(data)
{
if(data)
{
data = JSON.parse(data);
const $buildsPicker = $('select[name^=builds]').zui('picker');
$buildsPicker.render({items: data, multiple: true});
$('#builds').attr('data-placeholder', multipleSelect);
}
});
if(productID)
{
$.get($.createLink('product', 'ajaxGetProductById', 'produtID=' + productID), function(data)
{
$('#branch').prev('.form-label').html(data.branchName);
}, 'json');
}
});
$(document).on('change', 'input[name=isIntegrated]', function()
{
let projectID = $('input[name=project]').val();
let executionID = $('input[name=execution]').val();
if($(this).val() == 'no')
{
$('#execution').closest('.form-row').removeClass('hidden');
$('#builds').closest('.form-row').addClass('hidden');
loadProducts(executionID);
}
else
{
$('#execution').closest('.form-row').addClass('hidden');
$('#builds').closest('.form-row').removeClass('hidden');
loadProducts(projectID);
let productID = $('input[name=product]').val();
$.get($.createLink('build', 'ajaxGetProjectBuilds', 'projectID=' + projectID + '&productID=' + productID + '&letName=builds&build=&branch=all&index=&needCreate=&type=noempty,notrunk,separate,singled&extra=multiple'), function(data)
{
if(data)
{
data = JSON.parse(data);
const $buildsPicker = $('select[name^=builds]').zui('picker');
$buildsPicker.render({items: data, multiple: true});
$('#builds').attr('data-placeholder', multipleSelect);
}
});
}
});
loadBranches();
});
/**
* Load products.
*
* @param int $executionID
* @access public
* @return void
*/
function loadProducts(executionID)
{
executionID = parseInt(executionID);
if(!executionID) executionID = $('input[name=execution]').val();
$.get($.createLink('product', 'ajaxGetProducts', 'executionID=' + executionID), function(data)
{
if(data)
{
data = JSON.parse(data);
const $product = $('input[name=product]');
const $productPicker = $product.zui('picker');
const productID = data[0].value;
$productPicker.render({items: data});
$productPicker.$.setValue(productID);
$('#builds').attr('data-placeholder', multipleSelect);
loadBranches(productID);
}
});
loadLastBuild();
}
/**
* Load last build
*
* @access public
* @return void
*/
function loadLastBuild()
{
let isIntegrated = $('input[name=isIntegrated]:checked').val();
let projectID = $('input[name=project]').val();
let executionID = $('input[name=execution]').val();
if(isIntegrated == 'yes') executionID = 0;
$.get($.createLink('build', 'ajaxGetLastBuild', 'projectID=' + projectID + '&executionID=' + executionID), function(data)
{
$('#lastBuildBox').html(data);
});
}
/**
* 产品改变时更新制品库显示。
* When change product load artifactrepo.
*
* @param event $event
* @access public
* @return viod
*/
function loadArtifactrepo(event)
{
const productID = $(event.target).val();
var data = Object.values(productArtifactRepos[productID]);
if(data.length > 0)
{
$('.artifactrepo').removeClass('hidden');
}
else
{
$('.artifactrepo').addClass('hidden');
$('#filePath').val('');
var datePicker = $('#date').datePicker().zui();
datePicker.$.setValue(today);
}
onShowArtifactRepo();
}
/**
* 版本库显示改变事件。
* Artifact repo show change event.
*
* @access public
* @return viod
*/
function onShowArtifactRepo()
{
var isArtifactRepo = $('input[name=isArtifactRepo]:checked').val();
if(isArtifactRepo == 'yes')
{
var productID = $('[name=product]').val();
var data = Object.values(productArtifactRepos[productID]);
if(data.length > 0)
{
$('.artifactrepo-id').removeClass('hidden');
var items = [];
for(i in productArtifactRepos[productID])
{
items.push({'text': productArtifactRepos[productID][i].name, 'value': productArtifactRepos[productID][i].id});
}
$artifactRepo = $('#artifactRepoID').zui('picker');
$artifactRepo.render({items: items});
$artifactRepo.$.clear();
}
else
{
$('.artifactrepo-id').addClass('hidden');
}
}
else
{
$('.artifactrepo-id').addClass('hidden');
}
}
/**
* 版本库改变事件。
* Artifact repo change event.
*
* @access public
* @return viod
*/
function onChangeArtifactRepo(event)
{
const repoID = $(event.target).val();
const datePicker = $('#date').datePicker().zui();
var productID = $('[name=product]').val();
var data = Object.values(productArtifactRepos[productID]);
if(data.length == 0 || !repoID)
{
$('#filePath').val('');
datePicker.$.setValue(today);
return;
}
for(i in productArtifactRepos[productID])
{
if(productArtifactRepos[productID][i].id == repoID)
{
$('#filePath').val(productArtifactRepos[productID][i].url);
datePicker.$.setValue(productArtifactRepos[productID][i].createdDate.substr(0, 10));
}
}
}
/**
* Load branches
*
* @param int $productID
* @access public
* @return void
*/
window.loadBranches = function(productID)
{
productID = parseInt(productID);
if(!productID) productID = $('input[name=product]').val();
if($('input[name=isIntegrated]:checked').val() == 'yes')
{
$('#branch').closest('.form-row').addClass('hidden');
return false;
}
let oldBranch = 0;
if(typeof(productGroups[productID]) != "undefined")
{
oldBranch = productGroups[productID]['branches'];
}
$.get($.createLink('branch', 'ajaxGetBranches', 'productID=' + productID + '&oldBranch=0&param=active&projectID=' + $('input[name=execution]').val() + '&withMainBranch=true&isSiblings=no&fieldID=0&multiple=multiple'), function(data)
{
if(data)
{
data = JSON.parse(data);
const $branchPicker = $('input[name^=branch]').zui('picker');
$branchPicker.render({items: data});
$('#branch').closest('.form-row').removeClass('hidden');
}
else
{
$('#branch').closest('.form-row').addClass('hidden');
}
});
}

View File

@@ -20,6 +20,7 @@ $lang->build->view = "Build Details";
$lang->build->batchUnlink = 'Batch Unlink';
$lang->build->batchUnlinkStory = "Batch {$lang->SRCommon} Unlink";
$lang->build->batchUnlinkBug = 'Batch Bug Unlink';
$lang->build->linkArtifactRepo = 'Link Artifact Repo';
$lang->build->confirmDelete = "Möchten Sie dieses Build löschen?";
$lang->build->confirmUnlinkStory = "Möchten Sie diese {$lang->SRCommon} löschen?";
@@ -40,6 +41,7 @@ $lang->build->singled = 'Singled';
$lang->build->builds = 'Included Builds';
$lang->build->released = 'Released';
$lang->build->name = 'Name';
$lang->build->nameAB = 'Name';
$lang->build->date = 'Datum';
$lang->build->builder = 'Builder';
$lang->build->url = 'URL';

View File

@@ -20,6 +20,7 @@ $lang->build->view = "Build Detail";
$lang->build->batchUnlink = 'Batch Unlink';
$lang->build->batchUnlinkStory = "Batch Unlink {$lang->SRCommon}";
$lang->build->batchUnlinkBug = 'Batch Unlink Bugs';
$lang->build->linkArtifactRepo = 'Link Artifact Repo';
$lang->build->confirmDelete = "Do you want to delete this build?";
$lang->build->confirmUnlinkStory = "Do you want to unlink this {$lang->SRCommon}?";
@@ -40,6 +41,7 @@ $lang->build->singled = 'Singled';
$lang->build->builds = 'Included Builds';
$lang->build->released = 'Released';
$lang->build->name = 'Name';
$lang->build->nameAB = 'Name';
$lang->build->date = 'Date';
$lang->build->builder = 'Builder';
$lang->build->url = 'URL';

View File

@@ -20,6 +20,7 @@ $lang->build->view = "Détail Build";
$lang->build->batchUnlink = 'Retirer par Lot';
$lang->build->batchUnlinkStory = "Retirer {$lang->SRCommon} par Lot";
$lang->build->batchUnlinkBug = 'Retirer Bugs par Lot';
$lang->build->linkArtifactRepo = 'Link Artifact Repo';
$lang->build->confirmDelete = "Voulez-vous supprimer ce build ?";
$lang->build->confirmUnlinkStory = "Voulez-vous retirer cette {$lang->SRCommon} du Build ?";
@@ -40,6 +41,7 @@ $lang->build->singled = 'Singled';
$lang->build->builds = 'Included Builds';
$lang->build->released = 'Released';
$lang->build->name = 'Nom';
$lang->build->nameAB = 'Name';
$lang->build->date = 'Date';
$lang->build->builder = 'Builder';
$lang->build->url = 'URL';

View File

@@ -20,6 +20,7 @@ $lang->build->view = "版本详情";
$lang->build->batchUnlink = '批量移除';
$lang->build->batchUnlinkStory = "批量移除{$lang->SRCommon}";
$lang->build->batchUnlinkBug = '批量移除Bug';
$lang->build->linkArtifactRepo = '关联制品库';
$lang->build->confirmDelete = "您确认删除该版本吗?";
$lang->build->confirmUnlinkStory = "您确认移除该{$lang->SRCommon}吗?";
@@ -40,6 +41,7 @@ $lang->build->singled = '单一版本';
$lang->build->builds = '包含版本';
$lang->build->released = '发布';
$lang->build->name = '名称编号';
$lang->build->nameAB = '名称';
$lang->build->date = '打包日期';
$lang->build->builder = '构建者';
$lang->build->url = '地址';

View File

@@ -424,7 +424,7 @@ class buildModel extends model
->stripTags($this->config->build->editor->create['id'], $this->config->allowedTags)
->join('builds', ',')
->join('branch', ',')
->remove('resolvedBy,allchecker,files,labels,isIntegrated,uid')
->remove('resolvedBy,allchecker,files,labels,isIntegrated,uid,isArtifactRepo')
->get();
if($this->post->isIntegrated == 'yes')

View File

@@ -0,0 +1,263 @@
<?php
declare(strict_types=1);
/**
* The create view file of build module of ZenTaoPMS.
* @copyright Copyright 2009-2023 禅道软件(青岛)有限公司(ZenTao Software (Qingdao) Co., Ltd. www.zentao.net)
* @license ZPL(https://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
* @author Shujie Tian<tianshujie@easycorp.ltd>
* @package build
* @link https://www.zentao.net
*/
namespace zin;
/* zin: Set variables to define picker options for form. */
jsVar('multipleSelect', $lang->build->placeholder->multipleSelect);
jsVar('autoRelationTip', $lang->build->notice->autoRelation);
jsVar('projectID', $projectID);
jsVar('executionID', $executionID);
jsVar('productGroups', $productGroups);
jsVar('productArtifactRepos', !empty($productArtifactRepos) ? $productArtifactRepos : '');
jsVar('today', helper::today());
$integratedRow = '';
if($app->tab == 'project' && !empty($multipleProject))
{
$integratedRow = formRow(
formGroup
(
set::width('1/2'),
set::label($lang->build->integrated),
radioList
(
set::name('isIntegrated'),
set::items($lang->build->isIntegrated),
set::value('no'),
set::inline(true)
),
),
);
}
$executionRow = '';
if(!empty($multipleProject))
{
$executionRow = formRow(
formGroup
(
set::width('1/2'),
set::name('execution'),
set::label($lang->executionCommon),
set::value($executionID),
set::items($executions),
set::required(true),
on::change('loadProducts')
),
);
}
$productRow = '';
if(!$hidden)
{
$productBox = '';
if(!empty($products) || !$executionID)
{
$productBox = formGroup(
set::width('1/2'),
set::id('productBox'),
set::name('product'),
set::label($lang->build->product),
set::value(empty($product) ? '' : $product->id),
set::items($products),
set::required(true),
on::change('loadBranches'),
on::change('loadArtifactrepo'),
);
$artifactRepoRow[] = formRow
(
setClass('artifactrepo ' . ((empty($product) || empty($productArtifactRepos[$product->id])) ? 'hidden' : '')),
formGroup
(
set::width('1/2'),
set::label($lang->build->linkArtifactRepo),
radioList
(
set::name('isArtifactRepo'),
set::items($lang->build->isIntegrated),
set::value('no'),
set::inline(true),
on::click('onShowArtifactRepo')
),
),
);
$artifactRepoRow[] = formRow
(
setClass('artifactrepo-id hidden'),
formGroup
(
set::width('1/2'),
set::label($lang->artifactrepo->repoName),
set::name('artifactRepoID'),
set::items(array()),
on::change('onChangeArtifactRepo'),
),
);
}
else
{
$productBox = formGroup(
set::width('1/2'),
set::id('productBox'),
set::label($lang->build->product),
setClass('items-center'),
html(sprintf($lang->build->noProduct, helper::createLink('execution', 'manageproducts', "executionID={$executionID}", '', true), $app->tab)),
);
}
$productRow = formRow(
$productBox,
);
}
if(empty($product)) $product = new stdclass();
$productType = zget($product, 'type', 'normal');
$productBranches = zget($product, 'branches', array());
formPanel
(
set::title($lang->build->create),
$integratedRow,
$executionRow,
$productRow,
formRow
(
setClass(!empty($product) && $product->type != 'normal' ? '' : 'hidden'),
formGroup
(
set::width('1/2'),
set::name('branch[]'),
set::label($lang->product->branchName['branch']),
set::value(key($productBranches)),
set::items($branches),
)
),
!empty($artifactRepoRow) ? $artifactRepoRow : null,
formRow
(
setClass('hidden'),
formGroup
(
set::width('1/2'),
set::label($lang->build->builds),
picker
(
set::id('builds'),
set::name('builds[]'),
set::items(array()),
set::multiple(true),
)
),
formGroup
(
set::width('1/2'),
setClass('pl-4 items-center'),
icon(
'help',
set('data-toggle', 'tooltip'),
set('id', 'tooltipHover'),
),
),
),
formRow
(
formGroup
(
set::width('1/2'),
set::name('name'),
set::label($lang->build->nameAB),
),
$lastBuild ? formGroup
(
set::width('1/2'),
setClass('items-center'),
div
(
set::id('lastBuildBox'),
setClass('text-gray'),
div
(
setClass('help-block'),
html('&nbsp;' . $lang->build->last . ': <a class="code label light rounded-full" id="lastBuildBtn">' . $lastBuild->name . '</a>'),
),
)
) : '',
),
formRow
(
formGroup
(
set::width('1/2'),
set::name('builder'),
set::label($lang->build->builder),
set::value($app->user->account),
set::items($users),
),
),
formRow
(
formGroup
(
set::width('1/2'),
set::name('date'),
set::label($lang->build->date),
set::control('date'),
set::value(helper::today()),
),
),
formRow
(
formGroup
(
set::name('scmPath'),
set::label($lang->build->scmPath),
set::placeholder($lang->build->placeholder->scmPath),
),
),
formRow
(
formGroup
(
set::name('filePath'),
set::label($lang->build->filePath),
set::placeholder($lang->build->placeholder->filePath),
),
),
formRow
(
formGroup
(
set::label($lang->build->files),
upload()
),
),
formRow
(
formGroup
(
set::label($lang->build->desc),
editor
(
set::name('desc'),
set::rows('10'),
)
),
formGroup
(
setClass('hidden'),
set::name('project'),
set::value($projectID),
)
)
);
/* ====== Render page ====== */
render();

View File

@@ -125,6 +125,7 @@ $lang->lineNumber = 'Zeile Nr.';
$lang->tutorialConfirm = 'Sie benutzen die Anleitung. Möchten Sie diese jetzt verlassen';
$lang->levelExceeded = 'The level has exceeded the display range. For more information, please go to the web page or view it through search.';
$lang->noticeOkFile = 'Aus Sicherheitsgrü nden muss Ihr Adminkonto bestätigt werden. \n Bitte melden Sie sich an und erstellen Sie die Datei %s File.\n Hinweis:\n 1. Die Datei ist leer.\n 2. Wenn die Datei bereits existiert, löschen Sie sie und erstellen Sie eine neue Datei.';
$lang->noticeDrag = 'Click to add or drag to upload, no more than %s';
$lang->serviceAgreement = "Service Agreement";
$lang->privacyPolicy = "Privacy Policy";

View File

@@ -125,6 +125,7 @@ $lang->lineNumber = 'Line No.';
$lang->tutorialConfirm = 'You are using ZenTao tutorial. Do you want to quit right now';
$lang->levelExceeded = 'The level has exceeded the display range. For more information, please go to the web page or view it through search.';
$lang->noticeOkFile = 'For security reasons, your Admin account has to be confirmed. \n Please login ZenTao server and create %s File.\n Note:\n 1. File is blank.\n 2. If the file existed, delete it and then create a new one.';
$lang->noticeDrag = 'Click to add or drag to upload, no more than %s';
$lang->serviceAgreement = "Service Agreement";
$lang->privacyPolicy = "Privacy Policy";

View File

@@ -125,6 +125,7 @@ $lang->lineNumber = 'Ligne No.';
$lang->tutorialConfirm = 'Vous utilisez le didacticiel ZenTao. Voulez-vous quitter maintenant ';
$lang->levelExceeded = 'The level has exceeded the display range. For more information, please go to the web page or view it through search.';
$lang->noticeOkFile = 'Pour des raisons de s?curit?, votre compte administrateur doit ?tre confirm?. \n Please login ZenTao server and create %s File.\n Note:\n 1. File is blank.\n 2. If the file existed, delete it and then create a new one.';
$lang->noticeDrag = 'Click to add or drag to upload, no more than %s';
$lang->serviceAgreement = "Service Agreement";
$lang->privacyPolicy = "Privacy Policy";

View File

@@ -125,6 +125,7 @@ $lang->lineNumber = '行号';
$lang->tutorialConfirm = '检测到你尚未退出新手教程模式,是否现在退出?';
$lang->levelExceeded = '层级已超过显示范围,更多信息请前往网页端查看或者是通过搜索方式查看。';
$lang->noticeOkFile = '为了安全起见,系统需要确认您的管理员身份。\n 请登录禅道所在的服务器,创建%s文件。\n 注意:\n 1. 文件内容为空。\n 2. 如果之前文件存在,删除之后重新创建。';
$lang->noticeDrag = '可点击添加或拖拽上传, 不超过 %s';
$lang->serviceAgreement = "服务协议";
$lang->privacyPolicy = "隐私政策";