* Add productsBox to project::create.

This commit is contained in:
liumengyi
2024-01-19 10:55:08 +08:00
parent 39af044fb7
commit 35cacc18d1
8 changed files with 263 additions and 258 deletions
-3
View File
@@ -1,9 +1,6 @@
.items-center {align-items: center !important;}
#ignore {text-decoration: underline; cursor: pointer; color: #ef7b0f;}
.productBox .input-group-addon {background: #fff}
.productBox .form-group.no-label {padding-left: 1px}
#project-model {font-weight: 500; font-size: 14px;}
.items-center {align-items: center !important}
-1
View File
@@ -9,7 +9,6 @@
#copyProjects .btn.primary-outline {background-color: var(--color-primary-50);}
#copyProjects .btn.primary-outline:after {position: absolute; content: '\e92f'; font-family: ZentaoIcon; font-size: 20px; right: 10px;}
#copyProjects .btn.primary-outline span {color: rgba(var(--color-fore-rgb),var(--tw-text-opacity));}
.productBox .line-btn {width: 48px; margin-right: 32px;}
.productBox div[id^=plan] {flex: 1 1;}
#mainContent .input-group.required {position: relative;}
#mainContent .input-group.required:after {content: '*'; color: rgba(var(--color-danger-500-rgb),var(--tw-text-opacity)); position: absolute; top: 0.5rem; right: 0.125rem;}
+176 -176
View File
@@ -77,8 +77,8 @@ function computeDaysDelta(date1, date2)
*/
function computeWorkDays()
{
const begin = $('#begin').zui('datePicker').$.value;
const end = $('#end').zui('datePicker').$.value;
const begin = $('[name=begin]').val();
const end = $('[name=end]').val();
if(end == LONG_TIME)
{
@@ -299,177 +299,177 @@ function ignoreTip(tip)
}
/**
* Add new line for link product.
*
* @param obj e
* @access public
* @return void
*/
window.addNewLine = function(e)
{
const obj = e.target
const newLine = $(obj).closest('.form-row').clone();
let index = 0;
let options = zui.Picker.query("[name^='products']").options;
/* 将已有产品下拉的最大name属性的值加1赋值给新行. */
$("[name^='products']").each(function()
{
let id = $(this).attr('name').replace(/[^\d]/g, '');
id = parseInt(id);
id ++;
index = id > index ? id : index;
})
/* 处理新一行控件的显示/隐藏,宽度/是否居中等样式问题. */
newLine.addClass('newLine');
newLine.find('.form-label').html('');
newLine.find('.removeLine').removeClass('disabled');
newLine.find('[name="newProduct"]').closest('div.items-center').remove();
newLine.find('.form-group').eq(0).addClass('w-1/2').removeClass('w-1/4');
newLine.find('.form-group').eq(1).addClass('hidden');
newLine.find("div[id^='plan']").attr('id', 'plan' + index);
$(obj).closest('.form-row').after(newLine);
/* 重新初始化新一行的下拉控件. */
newLine.find('.form-group').eq(0).find('.picker-box').empty();
newLine.find('.form-group').eq(0).find('.picker-box').append(`<div id=products${index}></div>`);
newLine.find('div[id^=plan] .picker-box').empty();
newLine.find('div[id^=plan] .picker-box').append(`<div id=plans${index}></div>`);
options.name = `products[${index}]`;
options.defaultValue = '';
new zui.Picker(`#products${index}`, options);
new zui.Picker(`#plans${index}`, {
items:[],
multiple: true,
name: `plans[${index}]`,
});
}
/**
* Remove line for link product.
*
* @param obj e
* @access public
* @return void
*/
window.removeLine = function(e)
{
const obj = e.target;
/* Dsiabled btn can't remove line. */
if($(obj).closest('.btn').hasClass('disabled')) return false;
$(obj).closest('.form-row').remove();
let chosenProducts = 0;
$("[name^='products']").each(function()
{
if($(this).val() > 0) chosenProducts ++;
});
(chosenProducts.length > 1 && (model == 'waterfall' || model == 'waterfallplus')) ? $('.stageBy').removeClass('hidden') : $('.stageBy').addClass('hidden');
}
/**
* Load branches.
*
* @param int $product
* @access public
* @return void
*/
window.loadBranches = function(product)
{
/* When selecting a product, delete a plan that is empty by default. */
$("#planDefault").remove();
let chosenProducts = [];
let $product = $(product);
$("[name^='products']").each(function()
{
let 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'))
{
zui.Modal.alert(errorSameProducts);
$(`#${product.id}`).zui('picker').$.setValue(0);
return false;
}
});
(chosenProducts.length > 1 && (model == 'waterfall' || model == 'waterfallplus')) ? $('.stageBy').removeClass('hidden') : $('.stageBy').addClass('hidden');
let $formRow = $(product).closest('.form-row');
let index = $formRow.find("[name^='products']").first().attr('name').match(/\d+/)[0];
let oldBranch = $(product).attr('data-branch') !== undefined ? $(product).attr('data-branch') : 0;
if(!multiBranchProducts[$(product).val()])
{
$formRow.find('.form-group').last().find('select').val('');
$formRow.find('.form-group').eq(0).addClass('w-1/2').removeClass('w-1/4');
$formRow.find('.form-group').eq(1).addClass('hidden').find('select').val('');
$formRow.find('.form-group').eq(0).find('.newProductBox').removeClass('hidden');
}
$.getJSON($.createLink('branch', 'ajaxGetBranches', "productID=" + $(product).val() + "&oldBranch=" + oldBranch + "&param=active"), function(data)
{
if(data.length > 0)
{
$formRow.find('.form-group').eq(1).find('.picker-box').empty();
$formRow.find('.form-group').eq(1).find('.picker-box').append(`<div id='branch${index}'></div>`);
$formRow.find('.form-group').eq(0).addClass('w-1/4').removeClass('w-1/2');
$formRow.find('.form-group').eq(1).removeClass('hidden');
$formRow.find('.form-group').eq(0).find('.newProductBox').addClass('hidden');
new zui.Picker(`#branch${index}`, {
items: data,
multiple: true,
name: `branch[${index}]`,
});
}
let branch = $('#branch' + index);
loadPlans(product, branch);
});
}
/**
* Load plans.
*
* @param obj $product
* @param obj $branchID
* @access public
* @return void
*/
window.loadPlans = function(product, branch)
{
let productID = $(product).val();
let branchID = $(branch).val() == null ? 0 : '0,' + $(branch).val();
let planID = $(product).attr('data-plan') !== undefined ? $(product).attr('data-plan') : 0;
let index = $(product).attr('name').match(/\d+/)[0];
$.get($.createLink('product', 'ajaxGetPlans', "productID=" + productID + '&branch=' + branchID + '&planID=' + planID + '&fieldID&needCreate=&expired=unexpired,noclosed&param=skipParent,multiple'), function(data)
{
if(data)
{
data = JSON.parse(data);
$("div#plan" + index).find('.picker-box').empty();
$("div#plan" + index).find('.picker-box').append(`<div id='plans${productID}'></div>`);
new zui.Picker(`#plans${productID}`, {
items: data,
multiple: true,
name: `plans[${productID}]`,
});
}
});
}
// * Add new line for link product.
// *
// * @param obj e
// * @access public
// * @return void
// */
// window.addNewLine = function(e)
// {
// const obj = e.target
// const newLine = $(obj).closest('.form-row').clone();
//
// let index = 0;
// let options = zui.Picker.query("[name^='products']").options;
//
// /* 将已有产品下拉的最大name属性的值加1赋值给新行. */
// $("[name^='products']").each(function()
// {
// let id = $(this).attr('name').replace(/[^\d]/g, '');
//
// id = parseInt(id);
// id ++;
//
// index = id > index ? id : index;
// })
//
// /* 处理新一行控件的显示/隐藏,宽度/是否居中等样式问题. */
// newLine.addClass('newLine');
// newLine.find('.form-label').html('');
// newLine.find('.removeLine').removeClass('disabled');
// newLine.find('[name="newProduct"]').closest('div.items-center').remove();
// newLine.find('.form-group').eq(0).addClass('w-1/2').removeClass('w-1/4');
// newLine.find('.form-group').eq(1).addClass('hidden');
// newLine.find("div[id^='plan']").attr('id', 'plan' + index);
//
// $(obj).closest('.form-row').after(newLine);
//
// /* 重新初始化新一行的下拉控件. */
// newLine.find('.form-group').eq(0).find('.picker-box').empty();
// newLine.find('.form-group').eq(0).find('.picker-box').append(`<div id=products${index}></div>`);
//
// newLine.find('div[id^=plan] .picker-box').empty();
// newLine.find('div[id^=plan] .picker-box').append(`<div id=plans${index}></div>`);
//
// options.name = `products[${index}]`;
// options.defaultValue = '';
// new zui.Picker(`#products${index}`, options);
//
// new zui.Picker(`#plans${index}`, {
// items:[],
// multiple: true,
// name: `plans[${index}]`,
// });
// }
//
// /**
// * Remove line for link product.
// *
// * @param obj e
// * @access public
// * @return void
// */
// window.removeLine = function(e)
// {
// const obj = e.target;
//
// /* Dsiabled btn can't remove line. */
// if($(obj).closest('.btn').hasClass('disabled')) return false;
//
// $(obj).closest('.form-row').remove();
//
// let chosenProducts = 0;
// $("[name^='products']").each(function()
// {
// if($(this).val() > 0) chosenProducts ++;
// });
//
// (chosenProducts.length > 1 && (model == 'waterfall' || model == 'waterfallplus')) ? $('.stageBy').removeClass('hidden') : $('.stageBy').addClass('hidden');
// }
//
// /**
// * Load branches.
// *
// * @param int $product
// * @access public
// * @return void
// */
// window.loadBranches = function(product)
// {
// /* When selecting a product, delete a plan that is empty by default. */
// $("#planDefault").remove();
//
// let chosenProducts = [];
// let $product = $(product);
// $("[name^='products']").each(function()
// {
// let 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'))
// {
// zui.Modal.alert(errorSameProducts);
// $(`#${product.id}`).zui('picker').$.setValue(0);
// return false;
// }
// });
//
// (chosenProducts.length > 1 && (model == 'waterfall' || model == 'waterfallplus')) ? $('.stageBy').removeClass('hidden') : $('.stageBy').addClass('hidden');
//
// let $formRow = $(product).closest('.form-row');
// let index = $formRow.find("[name^='products']").first().attr('name').match(/\d+/)[0];
// let oldBranch = $(product).attr('data-branch') !== undefined ? $(product).attr('data-branch') : 0;
//
// if(!multiBranchProducts[$(product).val()])
// {
// $formRow.find('.form-group').last().find('select').val('');
// $formRow.find('.form-group').eq(0).addClass('w-1/2').removeClass('w-1/4');
// $formRow.find('.form-group').eq(1).addClass('hidden').find('select').val('');
// $formRow.find('.form-group').eq(0).find('.newProductBox').removeClass('hidden');
// }
//
// $.getJSON($.createLink('branch', 'ajaxGetBranches', "productID=" + $(product).val() + "&oldBranch=" + oldBranch + "&param=active"), function(data)
// {
// if(data.length > 0)
// {
// $formRow.find('.form-group').eq(1).find('.picker-box').empty();
// $formRow.find('.form-group').eq(1).find('.picker-box').append(`<div id='branch${index}'></div>`);
//
// $formRow.find('.form-group').eq(0).addClass('w-1/4').removeClass('w-1/2');
// $formRow.find('.form-group').eq(1).removeClass('hidden');
// $formRow.find('.form-group').eq(0).find('.newProductBox').addClass('hidden');
//
// new zui.Picker(`#branch${index}`, {
// items: data,
// multiple: true,
// name: `branch[${index}]`,
// });
// }
//
// let branch = $('#branch' + index);
// loadPlans(product, branch);
// });
// }
//
// /**
// * Load plans.
// *
// * @param obj $product
// * @param obj $branchID
// * @access public
// * @return void
// */
// window.loadPlans = function(product, branch)
// {
// let productID = $(product).val();
// let branchID = $(branch).val() == null ? 0 : '0,' + $(branch).val();
// let planID = $(product).attr('data-plan') !== undefined ? $(product).attr('data-plan') : 0;
// let index = $(product).attr('name').match(/\d+/)[0];
//
// $.get($.createLink('product', 'ajaxGetPlans', "productID=" + productID + '&branch=' + branchID + '&planID=' + planID + '&fieldID&needCreate=&expired=unexpired,noclosed&param=skipParent,multiple'), function(data)
// {
// if(data)
// {
// data = JSON.parse(data);
//
// $("div#plan" + index).find('.picker-box').empty();
// $("div#plan" + index).find('.picker-box').append(`<div id='plans${productID}'></div>`);
//
// new zui.Picker(`#plans${productID}`, {
// items: data,
// multiple: true,
// name: `plans[${productID}]`,
// });
// }
// });
// }
+61 -61
View File
@@ -31,67 +31,67 @@ function removeAllTips()
$('.text-warning').remove();
}
window.addProduct = function(e)
{
if($(e.target).prop('checked'))
{
$('.productBox').addClass('hidden');
$('#addProductBox').removeClass('hidden');
$("[name^='newProduct']").prop('checked', true);
}
else
{
$('.productBox').removeClass('hidden');
$('#addProductBox').addClass('hidden');
$("[name^='newProduct']").prop('checked', false);
}
}
window.productChange = function(target)
{
loadBranches(target);
let $this = $(target);
let current = $this.val();
let last = $this.attr('last');
let lastBranch = $this.attr('data-lastBranch');
let $newProduct = $this.closest('.productBox').find('[name=newProduct]').closest('.checkbox-primary').parent();
if($newProduct.length > 0) $newProduct.toggleClass('hidden', current > 0);
$this.attr('data-last', current);
let $branch = $this.closest('.has-branch').find("[name^='branch']");
if($branch.length)
{
let branchID = $branch.val();
$this.attr('data-lastBranch', branchID);
}
else
{
$this.removeAttr('data-lastBranch');
}
let chosenProducts = 0;
$(".productBox [name^='products']").each(function()
{
if($(this).val() > 0) chosenProducts ++;
});
if(chosenProducts > 1) $('.stageBy').removeClass('hidden');
if(chosenProducts <= 1) $('.stageBy').addClass('hidden');
}
window.branchChange = function(e)
{
let current = $(e.target).val();
let last = $(e.target).attr('data-last');
$(e.target).attr('data-last', current);
let $product = $(e.target).closest('.form-row').find("[name^='products']");
$product.attr('data-lastBranch', current);
loadPlans($product, $(e.target));
}
// window.addProduct = function(e)
// {
// if($(e.target).prop('checked'))
// {
// $('.productBox').addClass('hidden');
// $('#addProductBox').removeClass('hidden');
// $("[name^='newProduct']").prop('checked', true);
// }
// else
// {
// $('.productBox').removeClass('hidden');
// $('#addProductBox').addClass('hidden');
// $("[name^='newProduct']").prop('checked', false);
// }
// }
//
// window.productChange = function(target)
// {
// loadBranches(target);
//
// let $this = $(target);
// let current = $this.val();
// let last = $this.attr('last');
// let lastBranch = $this.attr('data-lastBranch');
// let $newProduct = $this.closest('.productBox').find('[name=newProduct]').closest('.checkbox-primary').parent();
//
// if($newProduct.length > 0) $newProduct.toggleClass('hidden', current > 0);
// $this.attr('data-last', current);
//
// let $branch = $this.closest('.has-branch').find("[name^='branch']");
// if($branch.length)
// {
// let branchID = $branch.val();
// $this.attr('data-lastBranch', branchID);
// }
// else
// {
// $this.removeAttr('data-lastBranch');
// }
//
// let chosenProducts = 0;
// $(".productBox [name^='products']").each(function()
// {
// if($(this).val() > 0) chosenProducts ++;
// });
//
// if(chosenProducts > 1) $('.stageBy').removeClass('hidden');
// if(chosenProducts <= 1) $('.stageBy').addClass('hidden');
// }
//
// window.branchChange = function(e)
// {
// let current = $(e.target).val();
// let last = $(e.target).attr('data-last');
// $(e.target).attr('data-last', current);
//
// let $product = $(e.target).closest('.form-row').find("[name^='products']");
// $product.attr('data-lastBranch', current);
//
// loadPlans($product, $(e.target));
// }
$(document).on('click', '#copyProjects button', function()
{
+13 -13
View File
@@ -54,19 +54,19 @@ $fields->field('begin')
$fields->field('days')->label($lang->project->days . $lang->project->daysUnit)->control('input');
$fields->field('products[]')
->wrapBefore()
->control('picker')
->setClass('className', 'productBox')
->checkbox(array('text' => $lang->project->newProduct, 'name' => 'newProduct', 'checked' => false))
->items(data('allProducts'))
->label($lang->project->manageProducts);
$fields->field('plans[]')
->control('picker')
->setClass('className', 'productBox')
->items(array())
->label($lang->project->managePlans);
$fields->field('productsBox')
->width('full')
->control(array
(
'control' => 'productsBox',
'productItems' => data('allProducts'),
'branchGroups' => data('branchGroups'),
'planGroups' => data('productPlans'),
'linkedProducts' => data('linkedProducts'),
'linkedBranches' => data('linkedBranches'),
'project' => data('copyProject'),
'isStage' => data('isStage')
));
if($model == 'waterfall' || $model == 'waterfallplus')
{
-4
View File
@@ -35,10 +35,6 @@ if($hasCode)
$fields->field('days')->control('input', array('className' => $copyProject ? 'has-warning' : ''));
$fields->field('products[]')->hidden($copyProject ? !data('copyProject.hasProduct') : false);
$fields->field('plans[]')->hidden($copyProject ? !data('copyProject.hasProduct') : false);
if($model == 'waterfall' || $model == 'waterfallplus')
{
$fields->field('stageBy')->className('hidden');
+2
View File
@@ -19,6 +19,8 @@ jsVar('currencySymbol', $lang->project->currencySymbol);
jsVar('parentBudget', $lang->project->parentBudget);
jsVar('budgetUnitLabel', $lang->project->tenThousandYuan);
jsVar('budgetUnitValue', $config->project->budget->tenThousand);
jsVar('+projectID', $copyProjectID);
jsVar('LONG_TIME', LONG_TIME);
$modelMenuItems = array();
foreach($lang->project->modelList as $key => $text)
+11
View File
@@ -274,6 +274,12 @@ class projectZen extends project
$allProducts = $this->program->getProductPairs($programID, 'all', 'noclosed', '', $shadow, $withProgram);
$parentProgram = $this->loadModel('program')->getByID($programID);
if($copyProjectID)
{
$copyProjectBranches = $this->project->getBranchesByProject($copyProjectID);
$linkedProducts = $this->product->getProducts($copyProjectID, 'all', '', true, $copyProjectBranches, false);
}
$this->view->title = $this->lang->project->create;
$this->view->gobackLink = (isset($output['from']) && $output['from'] == 'global') ? $this->createLink('project', 'browse') : '';
$this->view->model = $model;
@@ -292,6 +298,11 @@ class projectZen extends project
$this->view->URSRPairs = $this->loadModel('custom')->getURSRPairs();
$this->view->availableBudget = $parentProgram ? $this->program->getBudgetLeft($parentProgram) : 0;
$this->view->budgetUnitList = $this->project->getBudgetUnitList();
$this->view->branchGroups = $this->loadModel('execution')->getBranchByProduct(array_keys($allProducts));
$this->view->productPlans = $this->loadModel('productplan')->getGroupByProduct(array_keys($allProducts), 'skipparent|unexpired');
$this->view->linkedProducts = isset($linkedProducts) ? $linkedProducts : array();
$this->view->linkedBranches = $this->project->getBranchesByProject($copyProjectID);
$this->view->isStage = in_array($model, array('waterfall', 'waterfallplus', 'ipd'));
$this->display();
}