From e12832e9e6adcf1b5cc274c9a03286f788a0723a Mon Sep 17 00:00:00 2001 From: tianshujie Date: Thu, 29 Jun 2023 10:04:23 +0800 Subject: [PATCH] * Refactor edit execution page. --- module/execution/css/edit.ui.css | 4 + module/execution/js/common.ui.js | 19 + module/execution/js/create.ui.js | 19 - module/execution/js/edit.ui.js | 4 + module/execution/ui/create.html.php | 8 +- module/execution/ui/edit.html.php | 617 ++++++++++++++++++++++++++++ 6 files changed, 649 insertions(+), 22 deletions(-) create mode 100644 module/execution/css/edit.ui.css create mode 100644 module/execution/js/edit.ui.js create mode 100644 module/execution/ui/edit.html.php diff --git a/module/execution/css/edit.ui.css b/module/execution/css/edit.ui.css new file mode 100644 index 0000000000..92b372b28f --- /dev/null +++ b/module/execution/css/edit.ui.css @@ -0,0 +1,4 @@ +.editPanel {max-width: 1200px !important;} +.items-center {align-items: center !important;} +#lifeTimeTips {padding-left: 1rem; align-items: center;} +.productsBox .line-btn {width: 48px; margin-right: 32px;} diff --git a/module/execution/js/common.ui.js b/module/execution/js/common.ui.js index 64fa327d13..152ef46113 100644 --- a/module/execution/js/common.ui.js +++ b/module/execution/js/common.ui.js @@ -286,3 +286,22 @@ function setWhite() const acl = $("[name^='acl']:checked").val(); acl != 'open' ? $('#whitelistBox').removeClass('hidden') : $('#whitelistBox').addClass('hidden'); } + +/** + * Show lifetime tips. + * + * @access public + * @return void + */ +function showLifeTimeTips() +{ + const lifetime = $('#lifetime').val(); + if(lifetime == 'ops') + { + $('#lifeTimeTips').removeClass('hidden'); + } + else + { + $('#lifeTimeTips').addClass('hidden'); + } +} diff --git a/module/execution/js/create.ui.js b/module/execution/js/create.ui.js index 36edad1fd7..5fb0bbbd1c 100644 --- a/module/execution/js/create.ui.js +++ b/module/execution/js/create.ui.js @@ -74,25 +74,6 @@ function setType() loadPage($.createLink('execution', 'create', 'projectID=' + projectID + '&executionID=0©ExecutionID=&planID=0&confirm=no&productID=0&extra=type=' + type)); } -/** - * Show lifetime tips. - * - * @access public - * @return void - */ -function showLifeTimeTips() -{ - const lifetime = $('#lifetime').val(); - if(lifetime == 'ops') - { - $('#lifeTimeTips').removeClass('hidden'); - } - else - { - $('#lifeTimeTips').addClass('hidden'); - } -} - /** * Load team members. * diff --git a/module/execution/js/edit.ui.js b/module/execution/js/edit.ui.js new file mode 100644 index 0000000000..c215dc54c5 --- /dev/null +++ b/module/execution/js/edit.ui.js @@ -0,0 +1,4 @@ +$(function() +{ + if($('#typeHover').length) new zui.Tooltip('#typeHover', {title: typeTip, trigger: 'hover', placement: 'right', type: 'white', 'className': 'text-gray border border-light'}); +}) diff --git a/module/execution/ui/create.html.php b/module/execution/ui/create.html.php index fc2112dcca..bc5745029c 100644 --- a/module/execution/ui/create.html.php +++ b/module/execution/ui/create.html.php @@ -53,7 +53,7 @@ if(!empty($project->model) && $project->model == 'agileplus') } $typeBox = null; -if((empty($project) || $project->model != 'kanban') and $type != 'kanban') +if((empty($project) || $project->model != 'kanban') && $type != 'kanban') { $typeBox = formRow( formGroup @@ -80,7 +80,7 @@ if((empty($project) || $project->model != 'kanban') and $type != 'kanban') } $productsBox = null; -if(isset($project->hasProduct) and !empty($project->hasProduct) and $products) +if(isset($project->hasProduct) && !empty($project->hasProduct) && $products) { $i = 0; foreach($products as $product) @@ -143,6 +143,7 @@ if(isset($project->hasProduct) and !empty($project->hasProduct) and $products) set::items($branches), set::value($branchIdList), set::disabled($isStage && $project->stageBy == 'project'), + set::multiple(true), on::change("loadPlans('#products{$i}', this)") ) ), @@ -200,6 +201,7 @@ elseif(!empty($project) && empty($project->hasProduct) && !in_array($project->mo ( set::name("plans[{$planProductID}][]"), set::items(isset($productPlan) ? $productPlan : array()), + set::multiple(true), formHidden('products[]', $planProductID), formHidden('branch[0][0]', 0), ) @@ -236,7 +238,7 @@ else ( set::id('branch0'), set::name('branch[0][]'), - set::control('select'), + set::multiple(true), on::change("loadPlans('#products0', this)") ) ), diff --git a/module/execution/ui/edit.html.php b/module/execution/ui/edit.html.php new file mode 100644 index 0000000000..9625c60d77 --- /dev/null +++ b/module/execution/ui/edit.html.php @@ -0,0 +1,617 @@ + + * @package execution + * @link https://www.zentao.net + */ +namespace zin; + +jsVar('weekend', $config->execution->weekend); +jsVar('errorSameProducts', $lang->execution->errorSameProducts); +jsVar('errorSameBranches', $lang->execution->errorSameBranches); +jsVar('unmodifiableProducts',$unmodifiableProducts); +jsVar('unmodifiableBranches', $unmodifiableBranches); +jsVar('multiBranchProducts', $multiBranchProducts); +jsVar('confirmSync', $lang->execution->confirmSync); +jsVar('unLinkProductTip', $lang->project->unLinkProductTip); +jsVar('typeTip', $lang->execution->typeTip); +jsVar('projectID', $execution->project); +jsVar('allProducts', $allProducts); +jsVar('branchGroups', $branchGroups); + +$projectBox = null; +if(isset($project)) +{ + if($project->model == 'scrum') + { + $projectBox = formGroup + ( + set::width('1/2'), + set::name('project'), + set::label($lang->execution->projectName), + set::items($allProjects), + set::value($execution->project), + set::required(true), + on::change('changeProject'), + ); + } + elseif($project->model == 'kanban') + { + $projectBox = formHidden('project', $execution->project); + } + elseif($project->model == 'agileplus') + { + $projectBox = formGroup + ( + set::class('items-center'), + set::label($lang->execution->method), + zget($lang->execution->typeList, $execution->type) + ); + } + elseif($app->tab == 'project' && $project->model == 'waterfallplus') + { + $projectBox = formGroup + ( + set::width('1/2'), + set::name('parent'), + set::label($lang->programplan->parent), + set::items($parentStageList), + set::value($execution->parent), + ); + } +} + +$typeBox = null; +if($project->model == 'waterfall' || $project->model == 'waterfallplus') +{ + $typeBox = formRow + ( + formGroup + ( + set::width($enableOptionalAttr ? '1/2' : '1/8'), + set::label($lang->stage->type), + set::class('items-center'), + $enableOptionalAttr ? select + ( + set::name('attribute'), + set::items($lang->stage->typeList), + set::value($execution->attribute), + ) : span(zget($lang->stage->typeList, $execution->attribute)), + ), + formGroup + ( + div + ( + setClass('pl-2 flex self-center'), + setStyle(['color' => 'var(--form-label-color)']), + icon + ( + 'help', + set('data-toggle', 'tooltip'), + set('id', 'typeHover'), + ) + ) + ) + ); +} +elseif($execution->type != 'kanban') +{ + $typeBox = formRow + ( + formGroup + ( + set::width('1/2'), + set::label($lang->execution->type), + select + ( + set::id('lifetime'), + set::name('lifetime'), + set::items($lang->execution->lifeTimeList), + set::value($execution->lifetime), + set::required(true), + on::change('showLifeTimeTips') + ) + ), + formGroup + ( + set::width('1/2'), + set::id('lifeTimeTips'), + set::class('text-gray'), + set::class($execution->lifetime != 'ops' ? 'hidden' : ''), + span($lang->execution->typeDesc), + ), + ); +} + +$productsBox = null; +if($project->model != 'waterfall' && $project->model != 'waterfallplus') +{ + if(!empty($project) && !empty($project->hasProduct) && $linkedProducts) + { + $i = 0; + foreach($linkedProducts as $product) + { + $hasBranch = $product->type != 'normal' && isset($branchGroups[$product->id]); + $branches = isset($branchGroups[$product->id]) ? $branchGroups[$product->id] : array(); + $plans = isset($productPlans[$product->id]) ? $productPlans[$product->id] : array(); + $productsBox[] = formRow + ( + set::class('productsBox'), + formGroup + ( + set::width($hasBranch ? '1/4' : '1/2'), + setClass('linkProduct'), + $i == 0 ? set::label($lang->project->manageProducts) : set::label(''), + inputGroup + ( + div + ( + setClass('grow'), + select + ( + set::id("products{$i}"), + set::name("products[$i]"), + set::value($product->id), + set::items($allProducts), + set::last($product->id), + set::disabled($execution->type == 'stage' && $project->stageBy == 'project'), + set::required(true), + on::change('loadBranches'), + $execution->type == 'stage' && $project->stageBy == 'project' ? formHidden("products[$i]", $product->id) : null, + ) + ), + ) + ), + formGroup + ( + set::width('1/4'), + setClass('ml-px'), + $hasBranch ? null : setClass('hidden'), + inputGroup + ( + $lang->product->branchName['branch'], + select + ( + set::id("branch{$i}"), + set::name("branch[$i][]"), + set::items($branches), + set::value(implode(',', $product->branches)), + set::multiple(true), + on::change("loadPlans('#products{$i}', this)") + ) + ), + ), + formGroup + ( + set::width('1/2'), + set::label($lang->project->associatePlan), + set::class('planBox'), + inputGroup + ( + set::id("plan{$i}"), + select + ( + set::name("plans[$product->id][]"), + set::items($plans), + set::value($product->plans), + set::multiple(true) + ) + ), + $isStage && $project->stageBy == 'project' ? null : div + ( + setClass('pl-2 flex self-center line-btn'), + btn + ( + setClass('btn btn-link addLine'), + on::click('addNewLine'), + icon('plus') + ), + btn + ( + setClass('btn btn-link removeLine'), + setClass($i == 0 ? 'hidden' : ''), + icon('trash'), + on::click('removeLine'), + ), + ) + ), + ); + + $i ++; + } + } + elseif(!empty($project) && empty($project->hasProduct)) + { + $planProductID = current(array_keys($linkedProducts)); + $productsBox[] = formRow( + formGroup + ( + set::width('1/2'), + set::label($lang->execution->linkPlan), + set('id', 'plansBox'), + set::class('planBox'), + select + ( + set::name("plans[{$planProductID}][]"), + set::items(isset($productPlans[$planProductID]) ? $productPlans[$planProductID] : array()), + set::multiple(true), + formHidden('products[]', $planProductID), + formHidden('branch[0][0]', 0), + ) + ), + ); + } + else + { + $productsBox [] = formRow + ( + set::class('productsBox'), + formGroup + ( + set::width('1/2'), + setClass('linkProduct'), + set::label($lang->project->manageProducts), + select + ( + set::id('products0'), + set::name('products[0]'), + set::items($allProducts), + set::required(true), + on::change('loadBranches') + ) + ), + formGroup + ( + set::width('1/4'), + setClass('hidden ml-px'), + inputGroup + ( + $lang->product->branchName['branch'], + select + ( + set::id('branch0'), + set::name('branch[0][]'), + set::control('select'), + set::multiple(true), + on::change("loadPlans('#products0', this)") + ) + ), + ), + formGroup + ( + set::width('1/2'), + set::label($lang->project->associatePlan), + set::class('planBox'), + inputGroup + ( + set::id("plan0"), + select + ( + set::name('plans[0][]'), + set::items(array()), + set::multiple(true) + ) + ), + $isStage && $project->stageBy == 'product' ? null : div + ( + setClass('pl-2 flex self-center line-btn'), + btn + ( + setClass('btn btn-link addLine'), + on::click('addNewLine'), + icon('plus') + ), + btn + ( + setClass('btn btn-link removeLine'), + setClass('hidden'), + icon('trash'), + on::click('removeLine'), + ), + ), + ), + ); + } +} +else +{ + if(!empty($project) && !empty($project->hasProduct)) + { + $hasBranch = $product->type != 'normal' and isset($branchGroups[$product->id]); + $branches = isset($branchGroups[$product->id]) ? $branchGroups[$product->id] : array(); + $plans = isset($productPlans[$product->id]) ? $productPlans[$product->id] : array(); + $productsBox[] = formRow + ( + set::class('productsBox'), + formGroup + ( + set::width($hasBranch ? '1/4' : '1/2'), + setClass('linkProduct'), + $i == 0 ? set::label($lang->project->manageProducts) : set::label(''), + inputGroup + ( + div + ( + setClass('grow'), + select + ( + set::id("products{$i}"), + set::name("products[$i]"), + set::value($product->id), + set::items($allProducts), + set::last($product->id), + set::disabled($project->model == 'waterfall' || $project->model == 'waterfallplus'), + set::required(true), + on::change('loadBranches'), + $project->model == 'waterfall' || $project->model == 'waterfallplus' ? formHidden("products[$i]", $product->id) : null, + ) + ), + ) + ), + formGroup + ( + set::width('1/4'), + setClass('ml-px'), + $hasBranch ? null : setClass('hidden'), + inputGroup + ( + $lang->product->branchName['branch'], + select + ( + set::id("branch{$i}"), + set::name("branch[$i][]"), + set::items($branches), + set::value(isset($product->branches) ? implode(',', $product->branches) : ''), + set::disabled($project->model == 'waterfall' || $project->model == 'waterfallplus'), + set::multiple(true), + on::change("loadPlans('#products{$i}', this)") + ) + ), + ), + formGroup + ( + set::width('1/2'), + set::label($lang->project->associatePlan), + set::class('planBox'), + inputGroup + ( + set::id("plan{$i}"), + select + ( + set::name("plans[$product->id][]"), + set::items($plans), + set::value(isset($product->plans) ? $product->plans : ''), + set::multiple(true) + ) + ), + ), + ); + + $i ++; + } + $productsBox[] = formHidden('products[]', key($linkedProducts)); + $productsBox[] = formHidden('branch', json_encode(array_values($linkedBranches))); +} + +formPanel +( + set::class('editPanel'), + modalHeader(set::title($lang->execution->edit)), + $projectBox, + formGroup + ( + set::width('1/2'), + set::name('name'), + set::label($lang->execution->name), + set::value($execution->name), + ), + isset($config->setCode) && $config->setCode == 1 ? formGroup + ( + set::width('1/2'), + set::name('code'), + set::label($lang->execution->code), + set::value($execution->code), + ) : null, + formRow + ( + formGroup + ( + set::width('1/2'), + set::label($lang->execution->dateRange), + set::required(true), + inputGroup + ( + input + ( + set::name('begin'), + set::type('date'), + set('id', 'begin'), + set::value($execution->begin), + set::placeholder($lang->execution->begin), + set::required(true), + on::change('computeWorkDays') + ), + $lang->project->to, + input + ( + set::name('end'), + set::type('date'), + set('id', 'end'), + set::value(($execution->end), + set::placeholder($lang->execution->end), + set::required(true), + on::change('computeWorkDays') + ), + ) + ), + ), + formGroup + ( + radioList + ( + set::name('delta'), + set::inline(true), + set::items($lang->execution->endList), + set::value((strtotime($project->end) - strtotime($project->begin)) / 3600 / 24 + 1), + on::change('computeEndDate'), + ) + ), + ), + formGroup + ( + set::label($lang->execution->days), + set::width('1/2'), + inputGroup + ( + setClass('has-suffix'), + input + ( + set::name('days'), + set::value($execution->days), + ), + div + ( + setClass('input-control-suffix z-50'), + $lang->execution->day + ) + ) + ), + $typeBox, + $execution->type == 'stage' && isset($config->setPercent) && $config->setPercent == 1 ? formGroup + ( + set::width('1/2'), + set::name('percent'), + set::label($lang->stage->percent), + set::value($execution->percent), + set::required(true), + ) : null, + formGroup + ( + set::width('1/2'), + set::label($lang->execution->status), + set::name('status'), + set::items($lang->execution->statusList), + set::value($execution->status), + ), + $productsBox, + formRow + ( + setClass('border-b border-b-1'), + div + ( + setClass('bg-lighter font-black px-3 py-1'), + $lang->execution->teamSetting + ), + ), + formGroup + ( + set::width('1/2'), + set::name('team'), + set::label($lang->execution->teamname), + set::value($execution->team), + ), + formRow + ( + formGroup + ( + set::width('1/4'), + set::label($lang->execution->PM), + select + ( + set::name('PM'), + set::items($pmUsers), + set::value($execution->PM), + set::required(true), + ) + ), + formGroup + ( + set::width('1/4'), + set::label($lang->execution->PO), + select + ( + set::name('PO'), + set::items($poUsers), + set::value($execution->PO), + set::required(true), + ) + ), + formGroup + ( + set::width('1/4'), + set::label($lang->execution->QD), + select + ( + set::name('QD'), + set::items($qdUsers), + set::value($execution->QD), + set::required(true), + ) + ), + formGroup + ( + set::width('1/4'), + set::label($lang->execution->RD), + select + ( + set::name('RD'), + set::items($rdUsers), + set::value($execution->RD), + set::required(true), + ) + ), + ), + formGroup + ( + set::label($lang->execution->team), + select + ( + set::name('teamMembers[]'), + set::items($users), + set::value(array_keys($teamMembers)), + set::multiple(true), + ) + ), + h::hr(), + formGroup + ( + set::name('desc'), + set::label($lang->execution->desc), + set::value(htmlSpecialString($execution->desc)), + set::control('editor'), + ), + formRow + ( + set::id('aclList'), + formGroup + ( + set::width('1/2'), + set::name('acl'), + set::label($lang->execution->acl), + set::control('radioList'), + set::items($lang->execution->aclList), + set::value($execution->acl), + set::disabled($execution->grade == 2), + on::change('setWhite(this.value)'), + ) + ), + formGroup + ( + set::label($lang->whitelist), + set::id('whitelistBox'), + set::class($execution->acl == 'open' ? 'hidden' : ''), + select + ( + set::name('whitelist[]'), + set::items($users), + set::multiple(true), + ) + ), +); + +/* ====== Render page ====== */ +render();