From c8ea2893558484bf934ae110bf6b403d34dadceb Mon Sep 17 00:00:00 2001 From: wangyuting Date: Wed, 12 Jul 2023 14:29:47 +0800 Subject: [PATCH] * Finish execution progress on executionstatistic block. --- .../block/css/executionstatisticblock.ui.css | 7 +- module/block/js/executionstatisticblock.ui.js | 34 ++ module/block/lang/de.php | 6 + module/block/lang/en.php | 6 + module/block/lang/fr.php | 6 + module/block/lang/zh-cn.php | 10 +- .../block/ui/executionstatisticblock.html.php | 311 ++++++++++++++++-- .../block/ui/productstatisticblock.html.php | 1 + module/block/ui/qastatisticblock.html.php | 1 + 9 files changed, 343 insertions(+), 39 deletions(-) create mode 100644 module/block/js/executionstatisticblock.ui.js diff --git a/module/block/css/executionstatisticblock.ui.css b/module/block/css/executionstatisticblock.ui.css index a4fc982e60..621f211b0c 100644 --- a/module/block/css/executionstatisticblock.ui.css +++ b/module/block/css/executionstatisticblock.ui.css @@ -1,6 +1,5 @@ -.executionstatistic-block {background: #FCFDFE; height: 256px;} +.executionstatistic-block {background: #FCFDFE;} .executionstatistic-block .panel-body {padding: 0;} -.executionstatistic-block.block-sm {height: auto;} .executionstatistic-block .tab-content {width: 100%;} .executionstatistic-block .tab-pane {padding: 0;} @@ -15,3 +14,7 @@ .executionstatistic-block.block-sm .nav-tabs .nav-item.nav-prev > a {padding: 0;} .executionstatistic-block.block-sm .nav-tabs .nav-item.nav-next {display: flex} .executionstatistic-block.block-sm .nav-tabs .nav-item.nav-next > a {padding: 0;} + +.executionstatistic-block .chart > div {margin: auto;} +.executionstatistic-block .pie-chart {position: relative;} +.executionstatistic-block .pie-chart .pie-chart-title {position: absolute; top: 50%; left: 50%; margin-top: -25px; margin-left: -30px} diff --git a/module/block/js/executionstatisticblock.ui.js b/module/block/js/executionstatisticblock.ui.js new file mode 100644 index 0000000000..3c22566963 --- /dev/null +++ b/module/block/js/executionstatisticblock.ui.js @@ -0,0 +1,34 @@ +$(function() +{ + $('.executionstatistic-block.block-sm .nav.nav-tabs').find('.nav-item.nav-switch').removeClass('active'); + $('.executionstatistic-block.block-sm .nav.nav-tabs').find('.nav-item.nav-switch').each(function() + { + if($(this).find('a[data-toggle=tab]').hasClass('active')) $(this).addClass('active'); + }) +}); + +function switchNav(event) +{ + var isPrev = $(event.target).closest('.nav-item').hasClass('nav-prev'); + var $navTabs = $(event.target).closest('.nav-tabs'); + + var $switch = isPrev ? $navTabs.find('.nav-switch > a.active').parent().prev() : $navTabs.find('.nav-switch > a.active').parent().next(); + if($switch.length) $switch.find('a[data-toggle=tab]').trigger('click'); +} + +$('.executionstatistic-block.block-sm .nav.nav-tabs').on('show', function(event, info) +{ + $(event.target).find('.nav-item.nav-switch').removeClass('active'); + $(event.target).find('.nav-item.nav-switch').each(function() + { + if($(this).find('a[data-toggle=tab]').hasClass('active')) $(this).addClass('active'); + }) +}); + +$('.executionstatistic-block .nav.nav-tabs').on('show', function(event, info) +{ + $('#' + info[1] + ' .chart').each(function() + { + $(this).find('div').data('zui.ECharts').chart.resize(); + }); +}); diff --git a/module/block/lang/de.php b/module/block/lang/de.php index 6ece63b0ca..f96b24a775 100644 --- a/module/block/lang/de.php +++ b/module/block/lang/de.php @@ -587,6 +587,12 @@ $lang->block->qastatistic->closedYesterday = 'Closed Yesterday'; $lang->block->qastatistic->closedToday = 'Closed Today'; $lang->block->qastatistic->latestTesttask = 'Latest Testtask'; +$lang->block->executionstatistic = new stdclass(); +$lang->block->executionstatistic->progress = 'Progress'; +$lang->block->executionstatistic->totalEstimate = 'Estimate'; +$lang->block->executionstatistic->totalConsumed = 'Consumed'; +$lang->block->executionstatistic->totalLeft = 'Left'; + $lang->block->executionoverview = new stdclass(); $lang->block->executionoverview->totalExecution = 'Total'; $lang->block->executionoverview->thisYear = 'This Year'; diff --git a/module/block/lang/en.php b/module/block/lang/en.php index fb40f5bb69..a32e4e1a69 100644 --- a/module/block/lang/en.php +++ b/module/block/lang/en.php @@ -587,6 +587,12 @@ $lang->block->qastatistic->closedYesterday = 'Closed Yesterday'; $lang->block->qastatistic->closedToday = 'Closed Today'; $lang->block->qastatistic->latestTesttask = 'Latest Testtask'; +$lang->block->executionstatistic = new stdclass(); +$lang->block->executionstatistic->progress = 'Progress'; +$lang->block->executionstatistic->totalEstimate = 'Estimate'; +$lang->block->executionstatistic->totalConsumed = 'Consumed'; +$lang->block->executionstatistic->totalLeft = 'Left'; + $lang->block->executionoverview = new stdclass(); $lang->block->executionoverview->totalExecution = 'Total'; $lang->block->executionoverview->thisYear = 'This Year'; diff --git a/module/block/lang/fr.php b/module/block/lang/fr.php index 931c986f69..f1e8972934 100644 --- a/module/block/lang/fr.php +++ b/module/block/lang/fr.php @@ -587,6 +587,12 @@ $lang->block->qastatistic->closedYesterday = 'Closed Yesterday'; $lang->block->qastatistic->closedToday = 'Closed Today'; $lang->block->qastatistic->latestTesttask = 'Latest Testtask'; +$lang->block->executionstatistic = new stdclass(); +$lang->block->executionstatistic->progress = 'Progress'; +$lang->block->executionstatistic->totalEstimate = 'Estimate'; +$lang->block->executionstatistic->totalConsumed = 'Consumed'; +$lang->block->executionstatistic->totalLeft = 'Left'; + $lang->block->executionoverview = new stdclass(); $lang->block->executionoverview->totalExecution = 'Total'; $lang->block->executionoverview->thisYear = 'This Year'; diff --git a/module/block/lang/zh-cn.php b/module/block/lang/zh-cn.php index 20362ef87d..0d3abb5a91 100644 --- a/module/block/lang/zh-cn.php +++ b/module/block/lang/zh-cn.php @@ -601,6 +601,13 @@ $lang->block->qastatistic->closedYesterday = '昨日关闭'; $lang->block->qastatistic->closedToday = '今日关闭'; $lang->block->qastatistic->latestTesttask = '近期测试单'; +$lang->block->executionstatistic = new stdclass(); +$lang->block->executionstatistic->allProject = '全部项目'; +$lang->block->executionstatistic->progress = '执行进度'; +$lang->block->executionstatistic->totalEstimate = '预计工时'; +$lang->block->executionstatistic->totalConsumed = '消耗工时'; +$lang->block->executionstatistic->totalLeft = '剩余工时'; + $lang->block->executionoverview = new stdclass(); $lang->block->executionoverview->totalExecution = "{$lang->executionCommon}总量"; $lang->block->executionoverview->thisYear = '今年完成'; @@ -653,9 +660,6 @@ $lang->block->releasestatistic = new stdclass(); $lang->block->releasestatistic->monthly = '月度发布次数趋势图'; $lang->block->releasestatistic->annual = "年度发布榜(%s年)"; -$lang->block->executionstatistic = new stdclass(); -$lang->block->executionstatistic->allProject = '全部项目'; - $lang->block->moduleList['product'] = $lang->productCommon; $lang->block->moduleList['project'] = $lang->projectCommon; $lang->block->moduleList['execution'] = $lang->execution->common; diff --git a/module/block/ui/executionstatisticblock.html.php b/module/block/ui/executionstatisticblock.html.php index 0ef5526906..751ae20f8b 100644 --- a/module/block/ui/executionstatisticblock.html.php +++ b/module/block/ui/executionstatisticblock.html.php @@ -19,26 +19,40 @@ $blockID = $block->module . '-' . $block->code . '-' . $block->id; * * @param array $executions * @param string $blockNavCode + * @param bool $longBlock * @access public * @return array */ -$getExecutionTabs = function($executions, $blockNavCode): array +$getExecutionTabs = function(array $executions, string $blockNavCode, bool $longBlock): array { $navTabs = array(); $selected = key($executions); + $navTabs[] = li + ( + set('class', 'nav-item overflow-hidden nav-prev rounded-full bg-white shadow-md h-6 w-6'), + a(icon(set('size', '24'), 'angle-left')) + ); foreach($executions as $execution) { $navTabs[] = li ( - set('class', 'nav-item'), + set('class', 'nav-item nav-switch w-full'), a ( - set('class', 'ellipsis title ' . ($execution->id == $selected ? 'active' : '')), - set('data-toggle', 'tab'), - set('href', "#tab3{$blockNavCode}Content{$execution->id}"), + set('class', 'ellipsis text-dark title ' . ($longBlock && $execution->id == $selected ? ' active' : '')), + $longBlock ? set('data-toggle', 'tab') : null, + set('data-name', "tab3{$blockNavCode}Content{$execution->id}"), + set('href', $longBlock ? "#tab3{$blockNavCode}Content{$execution->id}" : helper::createLink('execution', 'task', "executionID={$execution->id}")), $execution->name ), + !$longBlock ? a + ( + set('class', 'hidden' . ($execution->id == $selected ? ' active' : '')), + set('data-toggle', 'tab'), + set('data-name', "tab3{$blockNavCode}Content{$execution->id}"), + set('href', "#tab3{$blockNavCode}Content{$execution->id}"), + ) : null, a ( set('class', 'link flex-1 text-right hidden'), @@ -46,11 +60,17 @@ $getExecutionTabs = function($executions, $blockNavCode): array icon ( set('class', 'rotate-90 text-primary'), - 'export' + setStyle(array('--tw-rotate' => '270deg')), + 'import' ) ) ); } + $navTabs[] = li + ( + set('class', 'nav-item overflow-hidden nav-next rounded-full bg-white shadow-md h-6 w-6'), + a(icon(set('size', '24'), 'angle-right')) + ); return $navTabs; }; @@ -60,10 +80,11 @@ $getExecutionTabs = function($executions, $blockNavCode): array * * @param object $executions * @param string $blockNavID + * @param bool $longBlock * @access public * @return array */ -$getExecutionInfo = function($executions, $blockNavID): array +$getExecutionInfo = function(array $executions, string $blockNavID, bool $longBlock): array { global $lang; @@ -71,11 +92,230 @@ $getExecutionInfo = function($executions, $blockNavID): array $tabItems = array(); foreach($executions as $execution) { + $execution->addYesterday = rand(0, 100); + $execution->addToday = rand(0, 100); + $execution->resolvedYesterday = rand(0, 100); + $execution->resolvedToday = rand(0, 100); + $execution->closedYesterday = rand(0, 100); + $execution->closedToday = rand(0, 100); + $execution->progress = rand(0, 100); + $execution->totalEstimate = rand(0, 100); + $execution->totalConsumed = rand(0, 100); + $execution->totalLeft = rand(0, 100); + + $waitTesttasks = array(); + if(!empty($execution->waitTesttasks)) + { + foreach($execution->waitTesttasks as $waitTesttask) + { + $waitTesttasks[] = div(set('class', 'py-1'), common::hasPriv('testtask', 'cases') ? a(set('href', createLink('testtask', 'cases', "taskID={$waitTesttask->id}")), $waitTesttask->name) : span($waitTesttask->name)); + if(count($waitTesttasks) >= 2) break; + } + } + + $doingTesttasks = array(); + if(!empty($execution->doingTesttasks)) + { + foreach($execution->doingTesttasks as $doingTesttask) + { + $doingTesttasks[] = div(set('class', 'py-1'), common::hasPriv('testtask', 'cases') ? a(set('href', createLink('testtask', 'cases', "taskID={$doingTesttask->id}")), $doingTesttask->name) : span($doingTesttask->name)); + if(count($doingTesttasks) >= 2) break; + } + } + + $progressMax = max($execution->addYesterday, $execution->addToday, $execution->resolvedYesterday, $execution->resolvedToday, $execution->closedYesterday, $execution->closedToday); + $progressBlcok = array(); + foreach(array(array('addYesterday', 'addToday'), array('resolvedYesterday', 'resolvedToday'), array('closedYesterday', 'closedToday')) as $group) + { + $progress = array(); + $progressLabel = array(); + foreach($group as $key => $field) + { + $progressLabel[] = div(set('class', 'py-1 ' . ($key === 0 ? '' : 'text-gray')), span($lang->block->qastatistic->{$field}), span(set('class', 'ml-1'), $execution->{$field})); + $progress[] = div + ( + set('class', $key === 0 ? 'pt-2' : 'pt-5'), + div + ( + set('class', 'progress h-2'), + div + ( + set('class', 'progress-bar'), + set('role', 'progressbar'), + setStyle(array('width' => ($execution->{$field} / $progressMax * 100) . '%', 'background' => $key === 0 ? 'var(--color-secondary-200)' : 'var(--color-primary-300)')), + ) + ) + ); + } + $progressBlcok[] = div + ( + set('class', 'flex py-1 pr-4 ' . ($waitTesttasks || $doingTesttasks ? 'border-r' : '')), + cell($progressLabel), + cell + ( + set('class', 'flex-1 px-3'), + $progress + ) + ); + } + $tabItems[] = div ( - set('class', 'tab-pane' . ($execution->id == $selected ? ' active' : '')), + set('class', 'tab-pane h-full' . ($execution->id == $selected ? ' active' : '')), set('id', "tab3{$blockNavID}Content{$execution->id}"), - div() + div + ( + set('class', 'flex h-full ' . ($longBlock ? '' : 'col')), + cell + ( + set('class', 'flex-1'), + $longBlock ? set('width', '70%') : null, + div + ( + set('class', 'flex h-full ' . ($longBlock ? '' : 'col')), + cell + ( + $longBlock ? set('width', '40%') : null, + set('class', $longBlock ? 'p-4' : 'px-4'), + div + ( + set('class', 'chart pie-chart ' . ($longBlock ? 'py-6' : 'py-1')), + echarts + ( + set::color(array('#2B80FF', '#E3E4E9')), + set::series + ( + array + ( + array + ( + 'type' => 'pie', + 'radius' => array('80%', '90%'), + 'itemStyle' => array('borderRadius' => '40'), + 'label' => array('show' => false), + 'data' => array($execution->progress, 100 - $execution->progress) + ) + ) + ) + )->size('100%', 120), + div + ( + set::class('pie-chart-title text-center'), + div(span(set::class('text-2xl font-bold'), $execution->progress . '%')), + div(span(set::class('text-sm text-gray'), $lang->block->executionstatistic->progress, icon('help', set('data-toggle', 'tooltip'), set('id', 'storyTip'), set('class', 'text-light')))) + ) + ), + div + ( + set('class', 'flex h-full story-num w-44'), + cell + ( + set('class', 'flex-1 text-center'), + div + ( + span(!empty($execution->totalEstimate) ? $execution->totalEstimate : 0, 'h') + ), + div + ( + span + ( + set('class', 'text-sm text-gray'), + $lang->block->executionstatistic->totalEstimate + ) + ) + ), + cell + ( + set('class', 'flex-1 text-center'), + div + ( + span(!empty($execution->totalConsumed) ? $execution->totalConsumed : 0, 'h') + ), + div + ( + span + ( + set('class', 'text-sm text-gray'), + $lang->block->executionstatistic->totalConsumed + ) + ) + ), + cell + ( + set('class', 'flex-1 text-center'), + div + ( + span(!empty($execution->totalLeft) ? $execution->totalLeft : 0, 'h') + ), + div + ( + span + ( + set('class', 'text-sm text-gray'), + $lang->block->executionstatistic->totalLeft + ) + ) + ) + ) + ), + cell + ( + $longBlock ? set('width', '60%') : null, + set('class', 'py-4 ' . (!$longBlock ? 'px-4 flex' : '')), + cell + ( + set('class', 'flex-1'), + div + ( + $longBlock ? set('class', 'pb-2') : null, + $lang->block->qastatistic->bugStatistics + ), + $progressBlcok + ), + !$longBlock && ($doingTesttasks || $waitTesttasks) ? cell + ( + set('width', '50%'), + set('class', 'px-4'), + div(span($lang->block->qastatistic->latestTesttask)), + $doingTesttasks ? div + ( + set('class', 'py-2'), + div(set('class', 'text-sm pb-2'), $lang->testtask->statusList['doing']), + $doingTesttasks + ) : null, + $waitTesttasks ? div + ( + set('class', 'py-2'), + div(set('class', 'text-sm pb-2'), $lang->testtask->statusList['wait']), + $waitTesttasks + ) : null + ) : null + ) + ) + ), + $longBlock && ($doingTesttasks || $waitTesttasks) ? cell + ( + set('width', '30%'), + set('class', 'py-2 px-6'), + div + ( + set('class', 'py-2'), + span($lang->block->qastatistic->latestTesttask) + ), + $doingTesttasks ? div + ( + set('class', 'py-2'), + div(set('class', 'text-sm pb-2'), $lang->testtask->statusList['doing']), + $doingTesttasks + ) : null, + $waitTesttasks ? div + ( + set('class', 'py-2'), + div(set('class', 'text-sm pb-2'), $lang->testtask->statusList['wait']), + $waitTesttasks + ) : null + ) : null + ) ); } return $tabItems; @@ -83,59 +323,62 @@ $getExecutionInfo = function($executions, $blockNavID): array $url = createLink('block', 'printBlock', "blockID={$block->id}"); $projectItems = array(); -$projectItems[] = array('text' => $lang->block->executionstatistic->allProject, 'data-on' => 'click', 'data-call' => "loadPage('{$url}', '#{$blockID}')"); +$projectItems[] = array('text' => $lang->block->executionstatistic->allProject, 'data-on' => 'click', 'data-call' => "loadPage('{$url}', '#executionstatistic-block-{$block->id}')"); foreach($projects as $projectID => $projectName) { $url = createLink('block', 'printBlock', "blockID={$block->id}¶ms=" . helper::safe64Encode("project={$projectID}")); - $projectItems[] = array('text' => $projectName, 'data-on' => 'click', 'data-call' => "loadPage('{$url}', '#{$blockID}')"); + $projectItems[] = array('text' => $projectName, 'data-on' => 'click', 'data-call' => "loadPage('{$url}', '#executionstatistic-block-{$block->id}')"); } $blockNavCode = 'nav-' . uniqid(); panel ( - setID($blockID), + set('id', "executionstatistic-block-{$block->id}"), + on::click('.nav-prev,.nav-next', 'switchNav'), set('class', 'executionstatistic-block ' . ($longBlock ? 'block-long' : 'block-sm')), set('headingClass', 'border-b'), - to::heading + set::title($block->title), + to::headingActions ( - div + dropdown ( - set('class', 'panel-title'), - span($block->title), - - dropdown + a ( - a - ( - setClass('text-gray ml-4'), - isset($projects[$currentProjectID]) ? $projects[$currentProjectID] : $lang->block->executionstatistic->allProject, - span(setClass('caret align-middle ml-1')) - ), - set::placement('bottom-end'), - set::menu(array('style' => array('minWidth' => 70, 'width' => 70))), - set::items($projectItems) - ) + setClass('text-gray ml-4'), + isset($projects[$currentProjectID]) ? $projects[$currentProjectID] : $lang->block->executionstatistic->allProject, + span(setClass('caret align-middle ml-1')) + ), + set::placement('bottom-end'), + set::menu(array('style' => array('minWidth' => 70, 'width' => 70))), + set::items($projectItems) + ), + a + ( + set('class', 'text-gray'), + set('href', createLink('execution', 'all', 'status=' . $block->params->type)), + $lang->more, + icon('caret-right') ) ), div ( - set('class', 'flex h-full overflow-hidden'), + set('class', "flex h-full overflow-hidden " . ($longBlock ? '' : 'col')), cell ( - set('width', '22%'), - set('class', 'bg-secondary-pale overflow-y-auto overflow-x-hidden'), + $longBlock ? set('width', '22%') : null, + set('class', $longBlock ? 'bg-secondary-pale overflow-y-auto overflow-x-hidden' : ''), ul ( - set('class', 'nav nav-tabs nav-stacked'), - $getExecutionTabs($executions, $blockNavCode) + set('class', 'nav nav-tabs ' . ($longBlock ? 'nav-stacked' : 'pt-4 px-4')), + $getExecutionTabs($executions, $blockNavCode, $longBlock) ), ), cell ( set('class', 'tab-content'), set('width', '78%'), - $getExecutionInfo($executions, $blockNavCode) + $getExecutionInfo($executions, $blockNavCode, $longBlock) ) ) ); diff --git a/module/block/ui/productstatisticblock.html.php b/module/block/ui/productstatisticblock.html.php index d8888a77c9..4978c691f9 100644 --- a/module/block/ui/productstatisticblock.html.php +++ b/module/block/ui/productstatisticblock.html.php @@ -384,6 +384,7 @@ $getProductInfo = function(array $products, string $blockNavID, bool $longBlock) $blockNavCode = 'nav-' . uniqid(); panel ( + set('id', "productstatistic-block-{$block->id}"), on::click('.nav-prev,.nav-next', 'switchNav'), set('class', 'productstatistic-block ' . ($longBlock ? 'block-long' : 'block-sm')), set('headingClass', 'border-b'), diff --git a/module/block/ui/qastatisticblock.html.php b/module/block/ui/qastatisticblock.html.php index 4728c8e81e..78f0e3b759 100644 --- a/module/block/ui/qastatisticblock.html.php +++ b/module/block/ui/qastatisticblock.html.php @@ -322,6 +322,7 @@ $getProductInfo = function(array $products, string $blockNavID, bool $longBlock) $blockNavCode = 'nav-' . uniqid(); panel ( + set('id', "qastatistic-block-{$block->id}"), on::click('.nav-prev,.nav-next', 'switchNav'), set('class', 'qastatistic-block ' . ($longBlock ? 'block-long' : 'block-sm')), set('headingClass', 'border-b'),