From 145463f1d80396ee29d7063a808e0a48223b5697 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E6=80=A1=E6=A0=8B?= Date: Mon, 25 Mar 2024 10:38:05 +0800 Subject: [PATCH] * Code for task #113950. --- framework/control.class.php | 2 +- lib/zin/wg/detailbody/v1.php | 10 +- lib/zin/wg/detailside/v1.php | 10 +- module/build/ui/view.html.php | 1 + module/caselib/ui/view.html.php | 4 +- module/execution/ui/view.html.php | 154 +---- module/product/ui/view.html.php | 4 +- module/productplan/ui/view.html.php | 1 + module/project/ui/view.html.php | 906 ++++++++++++---------------- module/release/ui/view.html.php | 1 + module/testsuite/ui/view.html.php | 1 + module/testtask/ui/view.html.php | 55 +- 12 files changed, 431 insertions(+), 718 deletions(-) diff --git a/framework/control.class.php b/framework/control.class.php index 943d43649c..6e99e59104 100644 --- a/framework/control.class.php +++ b/framework/control.class.php @@ -487,7 +487,7 @@ class control extends baseControl if($type == 'html') { parse_str($extras, $result); - $fields = $this->flow->buildExtendHtmlValue($object, zget($result, 'position', 'info')); + $fields = $this->flow->buildExtendHtmlValue($object, zget($result, 'position', 'info')); } else { diff --git a/lib/zin/wg/detailbody/v1.php b/lib/zin/wg/detailbody/v1.php index 55a23b9493..f5caef08da 100644 --- a/lib/zin/wg/detailbody/v1.php +++ b/lib/zin/wg/detailbody/v1.php @@ -29,8 +29,10 @@ class detailBody extends wg { global $app; - $data = data($app->getModuleName()); - $fields = $app->control->appendExtendForm('info', $data); + $app->control->loadModel('flow'); + $isForm = $this->prop('isForm'); + $object = data($app->getModuleName()); + $fields = $app->control->appendExtendForm('info', $object); $extraMain = array(); foreach($fields as $field) { @@ -47,7 +49,7 @@ class detailBody extends wg ) : null, set::title($field->name), set::required($field->required), - formGroup + !$isForm ? div($app->control->flow->getFieldValue($field, $object)) : formGroup ( set::id($field->field), set::name($field->field), @@ -58,7 +60,7 @@ class detailBody extends wg ) ); } - return sectionList($extraMain); + return empty($extraMain) ? null : sectionList($extraMain); } protected function build() diff --git a/lib/zin/wg/detailside/v1.php b/lib/zin/wg/detailside/v1.php index 877715290e..6b6e5d96eb 100644 --- a/lib/zin/wg/detailside/v1.php +++ b/lib/zin/wg/detailside/v1.php @@ -12,15 +12,17 @@ class detailSide extends wg .detail-side .tabs:not(:first-child) {border-top: 1px solid #E6EAF1;} .detail-side .tabs {padding-top: 12px; padding-bottom: 20px;} .detail-side > .table-data {width: 100%;} - CSS; +CSS; } protected function buildExtraSide() { global $app, $lang; - $data = data($app->getModuleName()); - $fields = $app->control->appendExtendForm('basic', $data); + $app->control->loadModel('flow'); + $isForm = $this->prop('isForm'); + $object = data($app->getModuleName()); + $fields = $app->control->appendExtendForm('basic', $object); $extraSide = array(); foreach($fields as $field) { @@ -35,7 +37,7 @@ class detailSide extends wg set::showDelete(true) ) : null, set::name($field->name), - formGroup + !$isForm ? div($app->control->flow->getFieldValue($field, $object)) : formGroup ( set::id($field->field), set::name($field->field), diff --git a/module/build/ui/view.html.php b/module/build/ui/view.html.php index 4542955e48..ecf677cbdc 100644 --- a/module/build/ui/view.html.php +++ b/module/build/ui/view.html.php @@ -277,6 +277,7 @@ detailBody html($build->desc) ) ), + html($this->printExtendFields($build, 'html', 'position=all', false)), $build->files ? h::hr(set::className('mt-6')) : null, section ( diff --git a/module/caselib/ui/view.html.php b/module/caselib/ui/view.html.php index 5c465e8019..3c400b21db 100644 --- a/module/caselib/ui/view.html.php +++ b/module/caselib/ui/view.html.php @@ -11,6 +11,8 @@ declare(strict_types=1); namespace zin; $isInModal = isAjaxRequest('modal'); + +data('caselib', $lib); detailHeader ( $isInModal ? to::prefix('') : '', @@ -34,8 +36,8 @@ detailBody set::content($lib->desc), set::useHtml(true) ), - history(set::objectID($lib->id)) ), + history(set::objectID($lib->id)), floatToolbar ( !$isInModal ? set::prefix diff --git a/module/execution/ui/view.html.php b/module/execution/ui/view.html.php index afd71f3281..adc4d28dec 100644 --- a/module/execution/ui/view.html.php +++ b/module/execution/ui/view.html.php @@ -546,14 +546,7 @@ div ( h::tr ( - h::td - ( - div - ( - setClass('flex flex-wrap member-list pt-2'), - $membersDom - ) - ) + h::td(div(setClass('flex flex-wrap member-list pt-2'), $membersDom)) ) ) ), @@ -566,14 +559,7 @@ div ( h::tr ( - h::th - ( - div - ( - setClass('flex items-center justify-between'), - span($lang->execution->DurationStats) - ) - ) + h::th(div(setClass('flex items-center justify-between'), span($lang->execution->DurationStats))) ) ), h::tbody @@ -588,58 +574,26 @@ div div ( setClass('w-1/4'), - span - ( - setClass('text-gray'), - $lang->execution->begin - ), - span - ( - setClass('ml-2'), - $execution->begin - ) + span(setClass('text-gray'), $lang->execution->begin), + span(setClass('ml-2'), $execution->begin) ), div ( setClass('w-1/4'), - span - ( - setClass('text-gray'), - $lang->execution->end - ), - span - ( - setClass('ml-2'), - $execution->end - ) + span(setClass('text-gray'), $lang->execution->end), + span(setClass('ml-2'), $execution->end) ), div ( setClass('w-1/4'), - span - ( - setClass('text-gray'), - $lang->execution->realBeganAB - ), - span - ( - setClass('ml-2'), - helper::isZeroDate($execution->realBegan) ? '' : $execution->realBegan - ) + span(setClass('text-gray'), $lang->execution->realBeganAB), + span(setClass('ml-2'), helper::isZeroDate($execution->realBegan) ? '' : $execution->realBegan) ), div ( setClass('w-1/4'), - span - ( - setClass('text-gray'), - $lang->execution->realEndAB - ), - span - ( - setClass('ml-2'), - helper::isZeroDate($execution->realEnd) ? '' : $execution->realEnd - ) + span(setClass('text-gray'), $lang->execution->realEndAB), + span(setClass('ml-2'), helper::isZeroDate($execution->realEnd) ? '' : $execution->realEnd) ) ) ) @@ -653,14 +607,7 @@ div ( h::tr ( - h::th - ( - div - ( - setClass('flex items-center justify-between'), - span($lang->execution->lblStats) - ) - ) + h::th(div(setClass('flex items-center justify-between'), span($lang->execution->lblStats))) ) ), h::tbody @@ -675,72 +622,32 @@ div div ( setClass('w-1/3'), - span - ( - setClass('text-gray'), - $lang->execution->estimateHours - ), - span - ( - setClass('ml-2'), - $execution->totalEstimate . $lang->execution->workHourUnit - ) + span(setClass('text-gray'), $lang->execution->estimateHours), + span(setClass('ml-2'), $execution->totalEstimate . $lang->execution->workHourUnit) ), div ( setClass('w-1/3'), - span - ( - setClass('text-gray'), - $lang->execution->consumedHours - ), - span - ( - setClass('ml-2'), - $execution->totalConsumed . $lang->execution->workHourUnit - ) + span(setClass('text-gray'), $lang->execution->consumedHours), + span(setClass('ml-2'), $execution->totalConsumed . $lang->execution->workHourUnit) ), div ( setClass('w-1/3'), - span - ( - setClass('text-gray'), - $lang->execution->leftHours - ), - span - ( - setClass('ml-2'), - $execution->totalLeft . $lang->execution->workHourUnit - ) + span(setClass('text-gray'), $lang->execution->leftHours), + span(setClass('ml-2'), $execution->totalLeft . $lang->execution->workHourUnit) ), div ( setClass('w-1/3 mt-4'), - span - ( - setClass('text-gray'), - $lang->execution->totalDays - ), - span - ( - setClass('ml-2'), - $execution->days - ) + span(setClass('text-gray'), $lang->execution->totalDays), + span(setClass('ml-2'), $execution->days) ), div ( setClass('w-1/3 mt-4'), - span - ( - setClass('text-gray'), - $lang->execution->totalHours - ), - span - ( - setClass('ml-2'), - $execution->totalHours . $lang->execution->workHourUnit - ) + span(setClass('text-gray'), $lang->execution->totalHours), + span(setClass('ml-2'), $execution->totalHours . $lang->execution->workHourUnit) ) ) ) @@ -777,17 +684,11 @@ div ( h::tr ( - h::td - ( - div - ( - setClass('flex flex-wrap pt-2'), - $docLibDom - ) - ) + h::td(div(setClass('flex flex-wrap pt-2'), $docLibDom)) ) ) - ) : null + ) : null, + html($this->printExtendFields($execution, 'html', 'position=info', false)) ) ), div @@ -797,11 +698,7 @@ div ( to::heading ( - div - ( - set('class', 'panel-title'), - $lang->execution->latestDynamic - ) + div(set('class', 'panel-title'), $lang->execution->latestDynamic) ), to::headingActions ( @@ -816,6 +713,7 @@ div set::shadow(false), dynamic() ), + html($this->printExtendFields($execution, 'html', 'position=basic', false)), div ( setClass('mt-4'), diff --git a/module/product/ui/view.html.php b/module/product/ui/view.html.php index a016413685..b217ad4bc3 100644 --- a/module/product/ui/view.html.php +++ b/module/product/ui/view.html.php @@ -263,7 +263,8 @@ div span(setClass('ml-2'), $product->executions) ) ) - ) + ), + html($this->printExtendFields($product, 'html', "position=info", false)) ) ), cell @@ -288,6 +289,7 @@ div set::shadow(false), dynamic() ), + html($this->printExtendFields($product, 'html', "position=basic", false)), div ( setClass('mt-4'), diff --git a/module/productplan/ui/view.html.php b/module/productplan/ui/view.html.php index 9c49281b1c..b70413bc00 100644 --- a/module/productplan/ui/view.html.php +++ b/module/productplan/ui/view.html.php @@ -294,6 +294,7 @@ detailBody item(set::name($lang->productplan->status), $lang->productplan->statusList[$plan->status]), item(set::name($lang->productplan->desc), empty($plan->desc) ? $lang->noData : html(($plan->desc))) ), + html($this->printExtendFields($plan, 'html', 'position=all', false)), h::hr(setClass('mt-4')), history(set::objectID($plan->id), set::commentBtn(false)) ) diff --git a/module/project/ui/view.html.php b/module/project/ui/view.html.php index d3189f7324..b9b445a0d5 100644 --- a/module/project/ui/view.html.php +++ b/module/project/ui/view.html.php @@ -19,15 +19,12 @@ if($project->grade > 1) { foreach($programList as $programID => $name) { + $programList[$programID] = "{$name}"; if(common::hasPriv('program', 'product')) { $programLink = $this->createLink('program', 'product', "programID={$programID}"); $programList[$programID] = "{$name}"; } - else - { - $programList[$programID] = "{$name}"; - } } $programDom = div @@ -64,29 +61,16 @@ if($project->hasProduct) $branches[] = div( setClass('flex clip w-full items-center'), icon('product mr-2'), - a - ( + a( setClass('flex'), set::title($product->name . $branchName), hasPriv('product', 'browse') ? set::href(createLink('product', 'browse', "productID={$productID}&branch={$branchID}")) : null, - span - ( - setClass('flex-1'), - setStyle('width', '0'), - $product->name . $branchName - ) + span(setClass('flex-1'), setStyle('width', '0'), $product->name . $branchName) ) ); } - $productDom = h::td - ( - div - ( - setClass('flex flex-wrap'), - $branches - ) - ); + $productDom = h::td(div(setClass('flex flex-wrap'), $branches)); $plans = array(); $planDom = null; @@ -108,8 +92,7 @@ if($project->hasProduct) ( setClass($class), icon('productplan mr-2 '), - a - ( + a( set::title($planGroup[$productID][$planID]), hasPriv('productplan', 'view') ? set::href(createLink('productplan', 'view', "planID={$planID}")) : null, span($planGroup[$productID][$planID]) @@ -117,14 +100,7 @@ if($project->hasProduct) ); } } - $planDom[] = h::td - ( - div - ( - setClass('flex flex-wrap'), - $plans - ) - ); + $planDom[] = h::td(div(setClass('flex flex-wrap'), $plans)); $relatedProducts[] = h::tr(setClass('border-r'), $productDom, $planDom); } } @@ -136,27 +112,13 @@ if(!empty($project->PM)) if($user) { $membersDom[] = div - ( - setClass('w-1/8 center-y'), - avatar - ( - setClass('primary-outline'), - set::text($user->realname), - set::src($user->avatar) - ), - span - ( - setClass('my-2'), - $user->realname - ), - span - ( - setClass('text-gray'), - $lang->project->PM - ) - ); + ( + setClass('w-1/8 center-y'), + avatar(setClass('primary-outline'), set::text($user->realname), set::src($user->avatar)), + span(setClass('my-2'), $user->realname), + span(setClass('text-gray'), $lang->project->PM) + ); } - unset($teamMembers[$project->PM]); } @@ -169,24 +131,12 @@ foreach($teamMembers as $teamMember) $user = isset($userList[$teamMember->account]) ? $userList[$teamMember->account] : null; if(!$user) continue; $membersDom[] = div - ( - setClass('w-1/8 center-y'), - avatar - ( - set::text($user->realname), - set::src($user->avatar) - ), - span - ( - setClass('my-2'), - $user->realname - ), - span - ( - setClass('text-gray'), - $lang->project->member - ) - ); + ( + setClass('w-1/8 center-y'), + avatar(set::text($user->realname), set::src($user->avatar)), + span(setClass('my-2'), $user->realname), + span(setClass('text-gray'), $lang->project->member) + ); $memberCount ++; } @@ -207,505 +157,389 @@ if(common::hasPriv('project', 'manageMembers')) ); } -div +row ( - setClass('main'), - div + cell ( - setClass('flex-auto canvas flex p-4 basic'), + setClass('main w-2/3'), div ( - setClass('text-center w-1/3 flex flex-col justify-center items-center progressBox'), + setClass('flex-auto canvas flex p-4 basic'), div ( - set('class', 'chart pie-chart'), - echarts + setClass('text-center w-1/3 flex flex-col justify-center items-center progressBox'), + div ( - set::color(array('#2B80FF', '#E3E4E9')), - set::series + set('class', 'chart pie-chart'), + echarts ( + set::color(array('#2B80FF', '#E3E4E9')), + set::series(array( array ( - array - ( - 'type' => 'pie', - 'radius' => array('80%', '90%'), - 'itemStyle' => array('borderRadius' => '40'), - 'label' => array('show' => false), - 'data' => array($progress, 100 - $progress) - ) - ) - ) - )->size(120, 120), - div - ( - set::className('pie-chart-title text-center'), - div(span(set::className('text-2xl font-bold'), $progress . '%')), + 'type' => 'pie', + 'radius' => array('80%', '90%'), + 'itemStyle' => array('borderRadius' => '40'), + 'label' => array('show' => false), + 'data' => array($progress, 100 - $progress) + ))) + )->size(120, 120), div ( - span - ( - setClass('text-sm text-gray'), - $lang->allProgress, - btn - ( - set::size('sm'), - set::icon('help'), - setClass('ghost form-label-hint text-gray-300 ml-2'), - toggle::tooltip(array('title' => $lang->execution->progressTip, 'className' => 'text-gray border border-gray-300', 'type' => 'white', 'placement' => 'right')) - ) - ) - ) - ) - ), - div - ( - setClass('border w-3/4 flex justify-center items-center pl-4 py-2 statistics'), - div - ( - setClass('w-1/3 storyCount'), - div - ( - setClass('text-md font-bold'), - $statData->storyCount - ), - span - ( - setClass('text-gray'), - $lang->story->common - ) - ), - div - ( - setClass('w-1/3 taskCount'), - div - ( - setClass('text-md font-bold'), - $statData->taskCount - ), - span - ( - setClass('text-gray'), - $lang->task->common - ) - ), - div - ( - setClass('w-1/3 bugCount'), - div - ( - setClass('text-md font-bold'), - $statData->bugCount - ), - span - ( - setClass('text-gray'), - $lang->bug->common - ) - ) - ) - ), - div - ( - setClass('flex-none w-2/3'), - div - ( - setClass('flex items-center'), - label - ( - setClass('label rounded-full ring-gray-400 gray-300-pale'), - $project->id - ), - span - ( - setClass('text-md font-bold ml-2 clip'), - set::title($project->name), - $project->name - ), - !empty($config->setCode) && !empty($project->code) ? label - ( - setClass('label gray-400-pale ring-gray-400 ml-2 flex-none'), - $project->code - ) : null, - label - ( - setClass('label warning-pale ring-warning rounded-full ml-2 flex-none projectType'), - $lang->project->projectTypeList[$project->hasProduct] - ), - $project->deleted ? label - ( - setClass('danger-outline text-danger flex-none ml-2'), - $lang->project->deleted - ) : null, - isset($project->delay) ? label - ( - setClass("ml-2 flex-none danger-pale"), - $lang->execution->delayed - ) : label - ( - setClass("ml-2 flex-none bg-white status status-{$project->status}"), - $status - ), - span - ( - setClass('ml-2 text-gray flex-none acl'), - $lang->project->shortAclList[$project->acl], - btn - ( - set::size('sm'), - set::icon('help'), - setClass('ghost form-label-hint text-gray-300 ml-2'), - toggle::tooltip(array('title' => $lang->project->subAclList[$project->acl], 'className' => 'text-gray border border-gray-300', 'type' => 'white', 'placement' => 'right')) - ) - ) - ), - div - ( - setClass('flex mt-4'), - div - ( - setClass('clip programBox'), - $programDom - ) - ), - div - ( - set::className('detail-content mt-4'), - html($project->desc) - ) - ) - ), - div - ( - setClass('flex flex-auto p-4 mt-4 canvas'), - div - ( - setClass('w-full'), - /* Linked product and plan. */ - $project->hasProduct ? h::table - ( - setClass('table condensed bordered productsBox'), - h::thead - ( - h::tr - ( - h::th - ( - setClass('w-1/3'), - div - ( - setClass('flex items-center justify-between'), - span - ( - setClass('leading-8 flex'), - img(set('src', 'static/svg/product.svg'), setClass('mr-2')), - $lang->project->manageProducts - ), - common::hasPriv('project', 'manageproducts') ? btn - ( - setClass('ghost text-gray'), - set::url(createLink('project', 'manageproducts', "projectID={$project->id}")), - icon('link', setClass('text-primary')), - span($lang->more, setClass('font-normal')) - ) : null - ) - ), - h::th + set::className('pie-chart-title text-center'), + div(span(set::className('text-2xl font-bold'), $progress . '%')), + div ( span ( - setClass('flex'), - img(set('src', 'static/svg/productplan.svg'), setClass('mr-2')), - $lang->execution->linkPlan - ) - ) - ) - ), - h::tbody($relatedProducts) - ) : null, - /* Project team. */ - h::table - ( - setClass('table condensed bordered teams ' . ($project->hasProduct ? 'mt-4' : '')), - h::thead - ( - h::tr - ( - h::th - ( - div - ( - setClass('flex items-center justify-between'), - span($lang->projectCommon . $lang->project->team), - hasPriv('project', 'team') ? btn + setClass('text-sm text-gray'), + $lang->allProgress, + btn ( - setClass('ghost text-gray'), - set::trailingIcon('caret-right pb-0.5'), - set::url(createLink('project', 'team', "projectID={$project->id}")), - span($lang->more, setClass('font-normal')) - ) : null - ) - ) - ) - ), - h::tbody - ( - h::tr - ( - h::td - ( - div - ( - setClass('flex flex-wrap member-list pt-2'), - $membersDom - ) - ) - ) - ) - ), - /* Estimate statistics. */ - h::table - ( - setClass('table condensed bordered mt-4 duration'), - h::thead - ( - h::tr - ( - h::th - ( - div - ( - setClass('flex items-center justify-between'), - span($lang->execution->DurationStats) - ) - ) - ) - ), - h::tbody - ( - h::tr - ( - h::td - ( - div - ( - setClass('flex flex-wrap pt-2 mx-4'), - div - ( - setClass('w-1/4'), - span - ( - setClass('text-gray'), - $lang->project->begin - ), - span - ( - setClass('ml-2'), - $project->begin - ) - ), - div - ( - setClass('w-1/4'), - span - ( - setClass('text-gray'), - $lang->project->end - ), - span - ( - setClass('ml-2'), - $project->end = $project->end == LONG_TIME ? $this->lang->project->longTime : $project->end - ) - ), - div - ( - setClass('w-1/4'), - span - ( - setClass('text-gray'), - $lang->project->realBeganAB - ), - span - ( - setClass('ml-2'), - helper::isZeroDate($project->realBegan) ? '' : $project->realBegan - ) - ), - div - ( - setClass('w-1/4'), - span - ( - setClass('text-gray'), - $lang->project->realEndAB - ), - span - ( - setClass('ml-2'), - helper::isZeroDate($project->realEnd) ? '' : $project->realEnd - ) + set::size('sm'), + set::icon('help'), + setClass('ghost form-label-hint text-gray-300 ml-2'), + toggle::tooltip(array('title' => $lang->execution->progressTip, 'className' => 'text-gray border border-gray-300', 'type' => 'white', 'placement' => 'right')) ) ) ) ) + ), + div + ( + setClass('border w-3/4 flex justify-center items-center pl-4 py-2 statistics'), + div + ( + setClass('w-1/3 storyCount'), + div(setClass('text-md font-bold'), $statData->storyCount), + span(setClass('text-gray'), $lang->story->common) + ), + div + ( + setClass('w-1/3 taskCount'), + div(setClass('text-md font-bold'), $statData->taskCount), + span(setClass('text-gray'), $lang->task->common) + ), + div + ( + setClass('w-1/3 bugCount'), + div(setClass('text-md font-bold'), $statData->bugCount), + span(setClass('text-gray'), $lang->bug->common) + ) ) ), - h::table - ( - setClass('table condensed bordered mt-4 estimate'), - h::thead - ( - h::tr - ( - h::th - ( - div - ( - setClass('flex items-center justify-between'), - span($lang->execution->lblStats) - ) - ) - ) - ), - h::tbody - ( - h::tr - ( - h::td - ( - div - ( - setClass('flex flex-wrap pt-2 mx-4'), - div - ( - setClass('w-1/3'), - span - ( - setClass('text-gray'), - $lang->execution->estimateHours - ), - span - ( - setClass('ml-2'), - (float)$workhour->totalEstimate . 'h' - ) - ), - div - ( - setClass('w-1/3'), - span - ( - setClass('text-gray'), - $lang->execution->consumedHours - ), - span - ( - setClass('ml-2'), - (float)$workhour->totalConsumed . 'h' - ) - ), - div - ( - setClass('w-1/3'), - span - ( - setClass('text-gray'), - $lang->execution->leftHours - ), - span - ( - setClass('ml-2'), - (float)$workhour->totalLeft . 'h' - ) - ), - div - ( - setClass('w-1/3 mt-4'), - span - ( - setClass('text-gray'), - $lang->execution->totalDays - ), - span - ( - setClass('ml-2'), - $project->days - ) - ), - div - ( - setClass('w-1/3 mt-4'), - span - ( - setClass('text-gray'), - $lang->execution->totalHours - ), - span - ( - setClass('ml-2'), - (float)$workhour->totalLeft . 'h' - ) - ), - div - ( - setClass('w-1/3 mt-4'), - span - ( - setClass('text-gray'), - $lang->project->budget - ), - span - ( - setClass('ml-2'), - $project->budget ? zget($lang->project->currencySymbol, $project->budgetUnit) . $project->budget : $lang->project->future - ) - ) - ) - ) - ) - ) - ) - ) - ) -); - -div -( - setClass('side ml-4'), - panel - ( - setID('dynamicBlock'), - to::heading - ( div ( - set('class', 'panel-title text-md font-bold'), - $lang->execution->latestDynamic + setClass('flex-none w-2/3'), + div + ( + setClass('flex items-center'), + label + ( + setClass('label rounded-full ring-gray-400 gray-300-pale'), + $project->id + ), + span + ( + setClass('text-md font-bold ml-2 clip'), + set::title($project->name), + $project->name + ), + !empty($config->setCode) && !empty($project->code) ? label + ( + setClass('label gray-400-pale ring-gray-400 ml-2 flex-none'), + $project->code + ) : null, + label + ( + setClass('label warning-pale ring-warning rounded-full ml-2 flex-none projectType'), + $lang->project->projectTypeList[$project->hasProduct] + ), + $project->deleted ? label + ( + setClass('danger-outline text-danger flex-none ml-2'), + $lang->project->deleted + ) : null, + isset($project->delay) ? label + ( + setClass("ml-2 flex-none danger-pale"), + $lang->execution->delayed + ) : label + ( + setClass("ml-2 flex-none bg-white status status-{$project->status}"), + $status + ), + span + ( + setClass('ml-2 text-gray flex-none acl'), + $lang->project->shortAclList[$project->acl], + btn + ( + set::size('sm'), + set::icon('help'), + setClass('ghost form-label-hint text-gray-300 ml-2'), + toggle::tooltip(array('title' => $lang->project->subAclList[$project->acl], 'className' => 'text-gray border border-gray-300', 'type' => 'white', 'placement' => 'right')) + ) + ) + ), + div(setClass('flex mt-4'), div(setClass('clip programBox'), $programDom)), + div(set::className('detail-content mt-4'), html($project->desc)) ) ), - to::headingActions + div ( - ($project->model != 'kanban' and common::hasPriv('project', 'dynamic')) ? btn + setClass('flex flex-auto p-4 mt-4 canvas'), + div ( - setClass('ghost text-gray'), - set::url(createLink('project', 'dynamic', "projectID={$projectID}&type=all")), - $lang->more - ) : null - ), - set::bodyClass('pt-0 h-80 overflow-y-auto'), - set::shadow(false), - dynamic() + setClass('w-full'), + /* Linked product and plan. */ + $project->hasProduct ? h::table + ( + setClass('table condensed bordered productsBox'), + h::thead + ( + h::tr + ( + h::th + ( + setClass('w-1/3'), + div + ( + setClass('flex items-center justify-between'), + span + ( + setClass('leading-8 flex'), + img(set('src', 'static/svg/product.svg'), setClass('mr-2')), + $lang->project->manageProducts + ), + common::hasPriv('project', 'manageproducts') ? btn + ( + setClass('ghost text-gray'), + set::url(createLink('project', 'manageproducts', "projectID={$project->id}")), + icon('link', setClass('text-primary')), + span($lang->more, setClass('font-normal')) + ) : null + ) + ), + h::th + ( + span + ( + setClass('flex'), + img(set('src', 'static/svg/productplan.svg'), setClass('mr-2')), + $lang->execution->linkPlan + ) + ) + ) + ), + h::tbody($relatedProducts) + ) : null, + /* Project team. */ + h::table + ( + setClass('table condensed bordered teams ' . ($project->hasProduct ? 'mt-4' : '')), + h::thead + ( + h::tr + ( + h::th + ( + div + ( + setClass('flex items-center justify-between'), + span($lang->projectCommon . $lang->project->team), + hasPriv('project', 'team') ? btn + ( + setClass('ghost text-gray'), + set::trailingIcon('caret-right pb-0.5'), + set::url(createLink('project', 'team', "projectID={$project->id}")), + span($lang->more, setClass('font-normal')) + ) : null + ) + ) + ) + ), + h::tbody + ( + h::tr + ( + h::td(div(setClass('flex flex-wrap member-list pt-2'), $membersDom)) + ) + ) + ), + /* Estimate statistics. */ + h::table + ( + setClass('table condensed bordered mt-4 duration'), + h::thead + ( + h::tr + ( + h::th + ( + div(setClass('flex items-center justify-between'), span($lang->execution->DurationStats)) + ) + ) + ), + h::tbody + ( + h::tr + ( + h::td + ( + div + ( + setClass('flex flex-wrap pt-2 mx-4'), + div + ( + setClass('w-1/4'), + span(setClass('text-gray'), $lang->project->begin), + span(setClass('ml-2'), $project->begin) + ), + div + ( + setClass('w-1/4'), + span(setClass('text-gray'), $lang->project->end), + span + ( + setClass('ml-2'), + $project->end = $project->end == LONG_TIME ? $this->lang->project->longTime : $project->end + ) + ), + div + ( + setClass('w-1/4'), + span(setClass('text-gray'), $lang->project->realBeganAB), + span + ( + setClass('ml-2'), + helper::isZeroDate($project->realBegan) ? '' : $project->realBegan + ) + ), + div + ( + setClass('w-1/4'), + span(setClass('text-gray'), $lang->project->realEndAB), + span + ( + setClass('ml-2'), + helper::isZeroDate($project->realEnd) ? '' : $project->realEnd + ) + ) + ) + ) + ) + ) + ), + h::table + ( + setClass('table condensed bordered mt-4 estimate'), + h::thead + ( + h::tr + ( + h::th + ( + div(setClass('flex items-center justify-between'), span($lang->execution->lblStats)) + ) + ) + ), + h::tbody + ( + h::tr + ( + h::td + ( + div + ( + setClass('flex flex-wrap pt-2 mx-4'), + div + ( + setClass('w-1/3'), + span(setClass('text-gray'), $lang->execution->estimateHours), + span(setClass('ml-2'), (float)$workhour->totalEstimate . 'h') + ), + div + ( + setClass('w-1/3'), + span(setClass('text-gray'), $lang->execution->consumedHours), + span(setClass('ml-2'), (float)$workhour->totalConsumed . 'h') + ), + div + ( + setClass('w-1/3'), + span(setClass('text-gray'), $lang->execution->leftHours), + span(setClass('ml-2'), (float)$workhour->totalLeft . 'h') + ), + div + ( + setClass('w-1/3 mt-4'), + span(setClass('text-gray'), $lang->execution->totalDays), + span(setClass('ml-2'), $project->days) + ), + div + ( + setClass('w-1/3 mt-4'), + span(setClass('text-gray'), $lang->execution->totalHours), + span(setClass('ml-2'), (float)$workhour->totalLeft . 'h') + ), + div + ( + setClass('w-1/3 mt-4'), + span(setClass('text-gray'), $lang->project->budget), + span + ( + setClass('ml-2'), + $project->budget ? zget($lang->project->currencySymbol, $project->budgetUnit) . $project->budget : $lang->project->future + ) + ) + ) + ) + ) + ) + ), + html($this->printExtendFields($project, 'html', 'position=info', false)) + ) + ) ), - div + cell ( - setID('historyBlock'), - setClass('mt-4'), - history + setClass('side ml-4'), + panel ( - set::objectID($project->id), - set::commentUrl(createLink('action', 'comment', array('objectType' => 'project', 'objectID' => $project->id))), - set::bodyClass('maxh-80 overflow-y-auto') + setID('dynamicBlock'), + to::heading + ( + div + ( + set('class', 'panel-title text-md font-bold'), + $lang->execution->latestDynamic + ) + ), + to::headingActions + ( + ($project->model != 'kanban' and common::hasPriv('project', 'dynamic')) ? btn + ( + setClass('ghost text-gray'), + set::url(createLink('project', 'dynamic', "projectID={$projectID}&type=all")), + $lang->more + ) : null + ), + set::bodyClass('pt-0 h-80 overflow-y-auto'), + set::shadow(false), + dynamic() + ), + html($this->printExtendFields($project, 'html', 'position=basic', false)), + div + ( + setID('historyBlock'), + setClass('mt-4'), + history + ( + set::objectID($project->id), + set::commentUrl(createLink('action', 'comment', array('objectType' => 'project', 'objectID' => $project->id))), + set::bodyClass('maxh-80 overflow-y-auto') + ) ) ) ); diff --git a/module/release/ui/view.html.php b/module/release/ui/view.html.php index 82b0c980a3..a315f70f74 100644 --- a/module/release/ui/view.html.php +++ b/module/release/ui/view.html.php @@ -309,6 +309,7 @@ detailBody ) ) ), + html($this->printExtendFields($release, 'html', 'position=all', false)), fileList(set::files($release->files)), h::hr(set::className('mt-6')), history(set::objectID($release->id)) diff --git a/module/testsuite/ui/view.html.php b/module/testsuite/ui/view.html.php index 4379a9afd5..f85e2bbf11 100644 --- a/module/testsuite/ui/view.html.php +++ b/module/testsuite/ui/view.html.php @@ -10,6 +10,7 @@ declare(strict_types=1); */ namespace zin; +data('testsuite', $suite); detailHeader ( to::title diff --git a/module/testtask/ui/view.html.php b/module/testtask/ui/view.html.php index 5f641ff3ca..04cf2983e2 100644 --- a/module/testtask/ui/view.html.php +++ b/module/testtask/ui/view.html.php @@ -12,6 +12,7 @@ namespace zin; $isInModal = isAjaxRequest('modal'); +data('testtask', $task); detailHeader ( to::title @@ -85,61 +86,29 @@ detailBody set::name($lang->testtask->build), span ( - $isInModal ? $buildName :a + $isInModal ? $buildName : a ( set::href(createLink('build', 'view', "buildID=$task->build")), $buildName ) ) ), - item - ( - set::name($lang->testtask->type), - $taskType - ), - item - ( - set::name($lang->testtask->owner), - zget($users, $task->owner) - ), - item - ( - set::name($lang->testtask->mailto), - $mailto - ), - item - ( - set::name($lang->testtask->pri), - priLabel($task->pri, set::text($lang->testtask->priList)) - ), - item - ( - set::name($lang->testtask->begin), - $task->begin - ), - item - ( - set::name($lang->testtask->end), - $task->end - ), - item - ( - set::name($lang->testtask->realFinishedDate), - !helper::isZeroDate($task->realFinishedDate) ? $task->realFinishedDate : '' - ), - item - ( - set::name($lang->testtask->status), - $this->processStatus('testtask', $task) - ), + item(set::name($lang->testtask->type), $taskType), + item(set::name($lang->testtask->owner), zget($users, $task->owner)), + item(set::name($lang->testtask->mailto), $mailto), + item(set::name($lang->testtask->pri), priLabel($task->pri, set::text($lang->testtask->priList))), + item(set::name($lang->testtask->begin), $task->begin), + item(set::name($lang->testtask->end), $task->end), + item(set::name($lang->testtask->realFinishedDate), !helper::isZeroDate($task->realFinishedDate) ? $task->realFinishedDate : ''), + item(set::name($lang->testtask->status), $this->processStatus('testtask', $task)), item ( set::name($lang->testtask->testreport), - !empty($task->testreport) ? a + empty($task->testreport) ? null : a ( set('href', createLink('testreport', 'view', "reportID=$task->testreport")), zget($testreport, 'title', '') - ) : null + ) ) ) )