* Code for task #77800.

This commit is contained in:
Yagami
2022-12-01 13:52:46 +08:00
parent e08a99744e
commit 7a843ece37
13 changed files with 169 additions and 180 deletions
+4 -8
View File
@@ -722,9 +722,8 @@ class project extends control
$withProgram = $this->config->systemMode == 'ALM' ? true : false;
$linkedBranches = array();
$linkedBranchList = array();
$productPlans = array(0 => '');
$productPlans = array();
$branches = $this->project->getBranchesByProject($projectID);
$linkedProductIdList = empty($branches) ? '' : array_keys($branches);
$allProducts = $this->program->getProductPairs($project->parent, 'all', 'noclosed', '', 0, $withProgram);
@@ -743,11 +742,10 @@ class project extends control
if(!isset($allProducts[$productID])) $allProducts[$productID] = $linkedProduct->name;
foreach($branches[$productID] as $branchID => $branch)
{
$linkedBranchList[$branchID] = $branchID;
$linkedBranches[$productID][$branchID] = $branchID;
$linkedBranchList[$branchID] = $branchID;
if($branch != BRANCH_MAIN) $productPlans[$productID][$branchID] = isset($plans[$productID][BRANCH_MAIN]) ? $plans[$productID][BRANCH_MAIN] : array();
$productPlans[$productID][$branchID] += isset($plans[$productID][$branchID]) ? $plans[$productID][$branchID] : array();
if($branch != BRANCH_MAIN) $productPlans[$productID] = isset($plans[$productID][BRANCH_MAIN]) ? $plans[$productID][BRANCH_MAIN] : array();
$productPlans[$productID] += isset($plans[$productID][$branchID]) ? $plans[$productID][$branchID] : array();
if(!empty($projectStories[$productID][$branchID]) or !empty($projectBranches[$productID][$branchID]))
{
@@ -773,7 +771,6 @@ class project extends control
$this->view->multiBranchProducts = $this->loadModel('product')->getMultiBranchPairs();
$this->view->productPlans = array_filter($productPlans);
$this->view->linkedProducts = $linkedProducts;
$this->view->linkedBranches = $linkedBranches;
$this->view->branches = $branches;
$this->view->executions = $this->execution->getPairs($projectID);
$this->view->unmodifiableProducts = $unmodifiableProducts;
@@ -1286,7 +1283,6 @@ class project extends control
$this->view->branchOption = $branchOption;
$this->view->branchTagOption = $branchTagOption;
$this->view->executions = $executions;
$this->view->plans = $this->loadModel('productplan')->getPairs($productID ? $productID : array_keys($products));
$this->view->stories = $storyList;
$this->view->tasks = $taskList;
$this->view->projectPairs = $this->project->getPairsByProgram();
-1
View File
@@ -5,5 +5,4 @@
#dateRange, .futureBox {vertical-align: top !important; padding-top: 13px !important;}
#endList {vertical-align: top; padding-top: 13px;}
#linkPlan {padding-top: 25px !important;}
#productsBox .row .col-sm-4.required::after {right: -5px;}
#projectType {padding-top: 7px !important;}
-128
View File
@@ -138,134 +138,6 @@ function computeEndDate(delta)
$('#days').trigger('mousedown');
}
/**
* Load branches.
*
* @param object product
* @access public
* @return void
*/
function loadBranches(product)
{
/* When selecting a product, delete a plan that is empty by default. */
$("#planDefault").remove();
var chosenProducts = [];
$("#productsBox select[name^='products']").each(function()
{
var $product = $(product);
var productID = $(this).val();
if(productID > 0 && chosenProducts.indexOf(productID) == -1) chosenProducts.push(productID);
if($product.val() != 0 && $product.val() == $(this).val() && $product.attr('id') != $(this).attr('id') && !multiBranchProducts[$product.val()])
{
bootbox.alert(errorSameProducts);
$product.val(0);
$product.trigger("chosen:updated");
return false;
}
});
chosenProducts.length > 1 ? $('.division').removeClass('hide') : $('.division').addClass('hide');
if($('#productsBox .input-group:last select:first').val() != 0)
{
var length = $('#productsBox .row .input-group').size();
$('#productsBox .row').append('<div class="col-sm-4">' + $('#productsBox .col-sm-4:last').html() + '</div>');
if($('#productsBox .input-group:last select').size() >= 2) $('#productsBox .input-group:last select:last').remove();
$('#productsBox .input-group:last .chosen-container').remove();
$('#productsBox .input-group:last select:first').attr('name', 'products[' + length + ']').attr('id', 'products' + length);
$('#productsBox .input-group:last .chosen').chosen();
adjustProductBoxMargin();
}
var $inputgroup = $(product).closest('.input-group');
if($inputgroup.find('select').size() >= 2) $inputgroup.removeClass('has-branch').find('select:last').remove();
if($inputgroup.find('.chosen-container').size() >= 2) $inputgroup.find('.chosen-container:last').remove();
var index = $inputgroup.find('select:first').attr('id').replace('products' , '');
var oldBranch = $(product).attr('data-branch') !== undefined ? $(product).attr('data-branch') : 0;
$.get(createLink('branch', 'ajaxGetBranches', "productID=" + $(product).val() + "&oldBranch=" + oldBranch + "&param=active"), function(data)
{
if(data)
{
$inputgroup.addClass('has-branch').append(data);
$inputgroup.find('select:last').attr('name', 'branch[' + index + ']').attr('id', 'branch' + index).attr('onchange', "loadPlans('#products" + index + "', this.value)").chosen();
$inputgroup.find('select:last').each(disableSelectedBranch);
disableSelectedProduct();
}
var branchID = $('#branch' + index).val();
loadPlans(product, branchID);
});
if(!multiBranchProducts[$(product).val()]) disableSelectedProduct();
$("input[name='products[" + index + "]']").remove();
$("input[name='branch[" + index + "]']").remove();
}
function loadPlans(product, branchID)
{
if($('#plansBox').size() == 0) return false;
var productID = $(product).val();
var branchID = typeof(branchID) == 'undefined' ? 0 : branchID;
var planID = $(product).attr('data-plan') !== undefined ? $(product).attr('data-plan') : 0;
var index = $(product).attr('id').replace('products', '');
$("input[name='products[" + index + "]']").remove();
$("input[name='branch[" + index + "]']").remove();
$.get(createLink('product', 'ajaxGetPlans', "productID=" + productID + '&branch=0,' + branchID + '&planID=' + planID + '&fieldID&needCreate=&expired=unexpired,noclosed&param=skipParent,multiple'), function(data)
{
if(data)
{
if($("div#plan" + index).size() == 0) $("#plansBox .row").append('<div class="col-sm-4" id="plan' + index + '"></div>');
$("div#plan" + index).html(data).find('select').attr('name', 'plans[' + productID + ']' + '[' + branchID + '][]').attr('id', 'plans' + productID).chosen();
adjustPlanBoxMargin();
}
});
}
/**
* Adjust the layout of product selection.
*
* @access public
* @return void
*/
function adjustProductBoxMargin()
{
var productRows = Math.ceil($('#productsBox > .row > .col-sm-4').length / 3);
if(productRows > 1)
{
for(i = 1; i <= productRows - 1; i++)
{
$('#productsBox .col-sm-4:lt(' + (i * 3) + ')').css('margin-bottom', '10px');
}
}
}
/**
* Adjust the layout of the plan selection.
*
* @access public
* @return void
*/
function adjustPlanBoxMargin()
{
var planRows = Math.ceil($('#plansBox > .row > .col-sm-4').length / 3);
if(planRows > 1)
{
for(j = 1; j <= planRows - 1; j++)
{
$('#plansBox .col-sm-4:lt(' + (j * 3) + ')').css('margin-bottom', '10px');
}
}
}
/**
* Initialization operation.
*
+2 -2
View File
@@ -370,7 +370,7 @@ function loadBranches(product)
function loadPlans(product, branch)
{
var productID = $(product).val();
var branchID = $(branch).val() == null ? 0 : $(branch).val();
var branchID = $(branch).val() == null ? 0 : '0,' + $(branch).val();
var planID = $(product).attr('data-plan') !== undefined ? $(product).attr('data-plan') : 0;
var index = $(product).attr('id').replace('products', '');
@@ -380,7 +380,7 @@ function loadPlans(product, branch)
{
$("div#plan" + index).find("select[name^='plans']").replaceWith(data);
$("div#plan" + index).find('.chosen-container').remove();
$("div#plan" + index).find('select').attr('name', 'plans[' + productID + '][' + branchID + '][]').attr('id', 'plans' + productID).chosen();
$("div#plan" + index).find('select').attr('name', 'plans[' + productID + ']' + '[]').attr('id', 'plans' + productID).chosen();
}
});
}
+124 -3
View File
@@ -32,9 +32,6 @@ $(function()
});
});
adjustProductBoxMargin();
adjustPlanBoxMargin();
$(document).on('change', '[name*=products]', function()
{
var current = $(this).val();
@@ -173,3 +170,127 @@ function setAclList(programID)
$('.aclBox').html($('#projectAcl').html());
}
}
/**
* Load branches.
*
* @param int $product
* @access public
* @return void
*/
function loadBranches(product)
{
/* When selecting a product, delete a plan that is empty by default. */
$("#planDefault").remove();
var chosenProducts = [];
$(".productsBox select[name^='products']").each(function()
{
var $product = $(product);
var productID = $(this).val();
if(productID > 0 && chosenProducts.indexOf(productID) == -1) chosenProducts.push(productID);
if($product.val() != 0 && $product.val() == $(this).val() && $product.attr('id') != $(this).attr('id') && !multiBranchProducts[$product.val()])
{
bootbox.alert(errorSameProducts);
$product.val(0);
$product.trigger("chosen:updated");
return false;
}
});
(chosenProducts.length > 1 && model == 'waterfall') ? $('.division').removeClass('hide') : $('.division').addClass('hide');
var $tableRow = $(product).closest('.table-row');
var index = $tableRow.find('select:first').attr('id').replace('products' , '');
var oldBranch = $(product).attr('data-branch') !== undefined ? $(product).attr('data-branch') : 0;
if(!multiBranchProducts[$(product).val()])
{
$tableRow.find('.table-col:last select').val('').trigger('chosen:updated');
$tableRow.find('.table-col:last').addClass('hidden');
}
$.get(createLink('branch', 'ajaxGetBranches', "productID=" + $(product).val() + "&oldBranch=" + oldBranch + "&param=active"), function(data)
{
if(data)
{
$tableRow.find("select[name^='branch']").replaceWith(data);
$tableRow.find('.table-col:last .chosen-container').remove();
$tableRow.find('.table-col:last').removeClass('hidden');
$tableRow.find("select[name^='branch']").attr('multiple', '').attr('name', 'branch[' + index + '][]').attr('id', 'branch' + index).attr('onchange', "loadPlans('#products" + index + "', this)").chosen();
disableSelectedProduct();
}
var branch = $('#branch' + index);
loadPlans(product, branch);
});
}
/**
* Load plans.
*
* @param obj $product
* @param obj $branchID
* @access public
* @return void
*/
function loadPlans(product, branch)
{
var productID = $(product).val();
var branchID = $(branch).val() == null ? 0 : '0,' + $(branch).val();
var planID = $(product).attr('data-plan') !== undefined ? $(product).attr('data-plan') : 0;
var index = $(product).attr('id').replace('products', '');
$.get(createLink('product', 'ajaxGetPlans', "productID=" + productID + '&branch=' + branchID + '&planID=' + planID + '&fieldID&needCreate=&expired=unexpired,noclosed&param=skipParent,multiple'), function(data)
{
if(data)
{
$("div#plan" + index).find("select[name^='plans']").replaceWith(data);
$("div#plan" + index).find('.chosen-container').remove();
$("div#plan" + index).find('select').attr('name', 'plans[' + productID + ']' + '[]').attr('id', 'plans' + productID).chosen();
}
});
}
/**
* Add new line for link product.
*
* @param obj $obj
* @access public
* @return void
*/
function addNewLine(obj)
{
var newLine = $(obj).closest('tr').clone();
var index = 0;
$(".productsBox select[name^='products']").each(function()
{
var id = $(this).attr('id').replace('products' , '');
id = parseInt(id);
id ++;
index = id > index ? id : index;
})
newLine.addClass('newLine');
newLine.find('th').html('');
newLine.find('.removeLine').css('visibility', 'visible');
newLine.find('.chosen-container').remove();
newLine.find('.productsBox .table-col:last').addClass('hidden');
newLine.find("select[name^='products']").attr('name', 'products[' + index + ']').attr('id', 'products' + index).val('').chosen();
newLine.find("select[name^='plans']").attr('name', 'plans[' + index + '][' + 0 + '][]').chosen();
newLine.find("div[id^='plan']").attr('id', 'plan' + index);
$(obj).closest('tr').after(newLine);
var product = newLine.find("select[name^='products']");
var branch = newLine.find("select[name^='branch']");
loadPlans(product, branch);
disableSelectedProduct();
}
function removeLine(obj)
{
$(obj).closest('tr').remove();
}
+1
View File
@@ -42,6 +42,7 @@ $lang->project->addWhitelist = 'Project Add Whitelist';
$lang->project->unbindWhitelist = 'Project Remove Whitelist';
$lang->project->manageProducts = 'Manage Products';
$lang->project->manageOtherProducts = 'Manage Other Products';
$lang->project->manageProductPlan = 'Manage Products And Plans';
$lang->project->copyTitle = 'Please select an project to copy';
$lang->project->errorSameProducts = 'Project cannot be associated with multiple identical products.';
$lang->project->errorSameBranches = 'Project cannot be associated with multiple identical branches.';
+1
View File
@@ -42,6 +42,7 @@ $lang->project->addWhitelist = 'Project Add Whitelist';
$lang->project->unbindWhitelist = 'Project Remove Whitelist';
$lang->project->manageProducts = 'Manage Products';
$lang->project->manageOtherProducts = 'Manage Other Products';
$lang->project->manageProductPlan = 'Manage Products And Plans';
$lang->project->copyTitle = 'Please select an project to copy';
$lang->project->errorSameProducts = 'Project cannot be associated with multiple identical products.';
$lang->project->errorSameBranches = 'Project cannot be associated with multiple identical branches.';
+1
View File
@@ -42,6 +42,7 @@ $lang->project->addWhitelist = 'Project Add Whitelist';
$lang->project->unbindWhitelist = 'Project Remove Whitelist';
$lang->project->manageProducts = 'Manage Products';
$lang->project->manageOtherProducts = 'Manage Other Products';
$lang->project->manageProductPlan = 'Manage Products And Plans';
$lang->project->copyTitle = 'Please select an project to copy';
$lang->project->errorSameProducts = 'Project cannot be associated with multiple identical products.';
$lang->project->errorSameBranches = 'Project cannot be associated with multiple identical branches.';
+1
View File
@@ -42,6 +42,7 @@ $lang->project->addWhitelist = 'Project Add Whitelist';
$lang->project->unbindWhitelist = 'Project Remove Whitelist';
$lang->project->manageProducts = 'Manage Products';
$lang->project->manageOtherProducts = 'Manage Other Products';
$lang->project->manageProductPlan = 'Manage Products And Plans';
$lang->project->copyTitle = 'Please select an project to copy';
$lang->project->errorSameProducts = 'Project cannot be associated with multiple identical products.';
$lang->project->errorSameBranches = 'Project cannot be associated with multiple identical branches.';
+1
View File
@@ -42,6 +42,7 @@ $lang->project->addWhitelist = '项目添加白名单';
$lang->project->unbindWhitelist = '项目删除白名单';
$lang->project->manageProducts = '关联产品';
$lang->project->manageOtherProducts = '关联其他产品';
$lang->project->manageProductPlan = '关联产品和计划';
$lang->project->copyTitle = '请选择要复制的项目';
$lang->project->errorSameProducts = '项目不能关联多个相同的产品。';
$lang->project->errorSameBranches = '项目不能关联多个相同的分支。';
+1 -1
View File
@@ -2420,7 +2420,7 @@ class projectModel extends model
$data->project = $projectID;
$data->product = $productID;
$data->branch = $branchID;
$data->plan = isset($plans[$productID][$branchID]) ? implode(',', $plans[$productID][$branchID]) : $oldPlan;
$data->plan = isset($plans[$productID]) ? implode(',', $plans[$productID]) : $oldPlan;
$data->plan = trim($data->plan, ',');
$data->plan = empty($data->plan) ? 0 : ",$data->plan,";
+3 -3
View File
@@ -139,7 +139,7 @@
</td><td></td><td></td>
</tr>
<tr>
<th id='productTitle'>关联产品和计划</th>
<th id='productTitle'><?php echo $lang->project->manageProductPlan;?></th>
<td class='text-left productsBox' colspan='3'>
<div class='row'>
<div class="col-sm-6">
@@ -154,8 +154,8 @@
<div><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->project->productTip;?>"></icon></div>
</span>
<?php endif;?>
</div>
</div>
</div>
<div class='table-col hidden'>
<div class='input-group required'>
<span class='input-group-addon fix-border'><?php echo $lang->product->branchName['branch'];?></span>
@@ -167,7 +167,7 @@
<div class="col-sm-6">
<div class='input-group' id='plan0'>
<span class='input-group-addon'><?php echo $lang->product->plan;?></span>
<?php echo html::select("plans[][][]", '', '', "class='form-control chosen' multiple");?>
<?php echo html::select("plans[][]", '', '', "class='form-control chosen' multiple");?>
<div class='input-group-btn'>
<a href='javascript:;' onclick='addNewLine(this)' class='btn btn-link addLine'><i class='icon-plus'></i></a>
<a href='javascript:;' onclick='removeLine(this)' class='btn btn-link removeLine' style='visibility: hidden'><i class='icon-close'></i></a>
+30 -34
View File
@@ -146,49 +146,45 @@
<td></td>
</tr>
<?php if($project->hasProduct and $this->config->vision != 'lite'):?>
<?php $i = 0;?>
<?php foreach($linkedProducts as $product):?>
<tr>
<th><?php echo $lang->project->manageProducts;?></th>
<td class='text-left' id='productsBox' colspan="3">
<th><?php if($i == 0) echo $lang->project->manageProductPlan;?></th>
<td class='text-left productsBox' colspan="3">
<div class='row'>
<?php $i = 0;?>
<?php foreach($linkedProducts as $product):?>
<?php $hasBranch = $product->type != 'normal' and isset($branchGroups[$product->id]);?>
<?php foreach($linkedBranches[$product->id] as $branchID => $branch):?>
<div class='col-sm-4' style="padding-right: 6px;">
<div class="input-group<?php if($hasBranch) echo ' has-branch';?>">
<?php echo html::select("products[$i]", $allProducts, $product->id, "class='form-control chosen' onchange='loadBranches(this)' data-last='" . $product->id . "' data-type='" . $product->type . "' data-lastBranch='" . $branchID . "'");?>
<span class='input-group-addon fix-border'></span>
<?php if($hasBranch) echo html::select("branch[$i]", $branchGroups[$product->id], $branchID, "class='form-control chosen' onchange=\"loadPlans('#products{$i}', this.value)\" data-last='" . $branchID . "'");?>
<div class="col-sm-6">
<div class='table-row'>
<div class='table-col'>
<?php $hasBranch = $product->type != 'normal' and isset($branchGroups[$product->id]);?>
<div class='input-group <?php if($hasBranch) echo ' has-branch';?>'>
<span class='input-group-addon'><?php echo $lang->product->common;?></span>
<?php echo html::select("products[$i]", $allProducts, $product->id, "class='form-control chosen' onchange='loadBranches(this)' data-last='" . $product->id . "' data-type='" . $product->type . "'");?>
</div>
</div>
<div class='table-col <?php if(!$hasBranch) echo 'hidden';?>'>
<div class='input-group required'>
<span class='input-group-addon fix-border'><?php echo $lang->product->branchName['branch'];?></span>
<?php $branchIdList = join(',', $product->branches);?>
<?php echo html::select("branch[$i][]", isset($branchGroups[$product->id]) ? $branchGroups[$product->id] : array(), $branchIdList, "class='form-control chosen' multiple onchange=\"loadPlans('#products{$i}', this)\"");?>
</div>
</div>
</div>
</div>
<?php $i++;?>
<?php endforeach;?>
<?php endforeach;?>
<div class='col-sm-4 <?php if($projectID) echo 'required';?>' style="padding-right: 6px;">
<div class='input-group'>
<?php echo html::select("products[$i]", $allProducts, '', "class='form-control chosen' onchange='loadBranches(this)'");?>
<span class='input-group-addon fix-border'></span>
<div class="col-sm-6">
<div class='input-group' <?php echo "id='plan$i'";?>>
<span class='input-group-addon'><?php echo $lang->product->plan;?></span>
<?php echo html::select("plans[$product->id][]", isset($productPlans[$product->id]) ? $productPlans[$product->id] : array(), $product->plans, "class='form-control chosen' multiple");?>
<div class='input-group-btn'>
<a href='javascript:;' onclick='addNewLine(this)' class='btn btn-link addLine'><i class='icon-plus'></i></a>
<a href='javascript:;' onclick='removeLine(this)' class='btn btn-link removeLine' <?php if($i == 0) echo "style='visibility: hidden'";?>><i class='icon-close'></i></a>
</div>
</div>
</div>
</div>
</td>
</tr>
<tr>
<th id='linkPlan'><?php echo $lang->execution->linkPlan;?></th>
<td id="plansBox" colspan="3">
<div class='row'>
<?php $i = 0;?>
<?php foreach($linkedProducts as $product):?>
<?php foreach($linkedBranches[$product->id] as $branchID => $branch):?>
<?php $plans = isset($productPlans[$product->id][$branchID]) ? $productPlans[$product->id][$branchID] : array();?>
<div class="col-sm-4" id="plan<?php echo $i;?>" style="padding-right: 6px;"><?php echo html::select("plans[{$product->id}][{$branchID}][]", $plans, $branches[$product->id][$branchID]->plan, "class='form-control chosen' multiple");?></div>
<?php $i++;?>
<?php endforeach;?>
<?php endforeach;?>
<div class="col-sm-4" id="planDefault" style="padding-right: 6px;"><?php echo html::select("plans[0][0][]", array(), 0, "class='form-control chosen' multiple");?></div>
</div>
</td>
</tr>
<?php $i ++;?>
<?php endforeach;?>
<?php endif;?>
<?php if($project->model == 'waterfall'):?>
<?php $class = (!$project->division and count($linkedProducts) < 2) ? 'hide' : '';?>