From f842e17c67bf162aec5ed2f0b473b5b0a07139e4 Mon Sep 17 00:00:00 2001 From: wangyuting Date: Thu, 27 Jul 2023 11:02:42 +0800 Subject: [PATCH] * Finish testtask unitcases and unitgroup zin page. --- module/testcase/control.php | 2 +- module/testcase/js/groupcase.ui.js | 1 - module/testtask/config/table.php | 31 ++++++++ module/testtask/control.php | 54 ++++++------- module/testtask/css/unitcases.ui.css | 2 + module/testtask/js/groupcase.ui.js | 1 - module/testtask/js/unitcases.ui.js | 107 ++++++++++++++++++++++++++ module/testtask/ui/unitcases.html.php | 43 +++++++++++ 8 files changed, 209 insertions(+), 32 deletions(-) create mode 100644 module/testtask/css/unitcases.ui.css create mode 100644 module/testtask/js/unitcases.ui.js create mode 100644 module/testtask/ui/unitcases.html.php diff --git a/module/testcase/control.php b/module/testcase/control.php index 07001472d5..6c87a48497 100644 --- a/module/testcase/control.php +++ b/module/testcase/control.php @@ -325,7 +325,7 @@ class testcase extends control if($groupBy == 'story') $groupCases[$case->story][] = $case; } - $story = ''; + $story = null; foreach($cases as $index => $case) { if($case->storyDeleted) diff --git a/module/testcase/js/groupcase.ui.js b/module/testcase/js/groupcase.ui.js index 11c9ad0a03..8ffc9cb13c 100644 --- a/module/testcase/js/groupcase.ui.js +++ b/module/testcase/js/groupcase.ui.js @@ -65,7 +65,6 @@ window.deformation = function(event) if($(event.target).closest('a').find('span').hasClass('is-collapsed')) { - console.log(initialOptions.data); $.each(options.data, function(index) { if(!options.data[index]) return; diff --git a/module/testtask/config/table.php b/module/testtask/config/table.php index 9a57647a71..cf036cb240 100644 --- a/module/testtask/config/table.php +++ b/module/testtask/config/table.php @@ -139,3 +139,34 @@ $config->testtask->browseUnits->dtable->fieldList['actions']['type'] = 'acti $config->testtask->browseUnits->dtable->fieldList['actions']['sortType'] = false; $config->testtask->browseUnits->dtable->fieldList['actions']['list'] = $config->testtask->actionList; $config->testtask->browseUnits->dtable->fieldList['actions']['menu'] = array('unitCases', 'edit', 'delete'); + +$config->testtask->unitgroup = new stdclass(); +$config->testtask->unitgroup->dtable = new stdclass(); +$config->testtask->unitgroup->dtable->fieldList['suite']['title'] = $lang->testcase->suite; +$config->testtask->unitgroup->dtable->fieldList['suite']['width'] = 'auto'; +$config->testtask->unitgroup->dtable->fieldList['suite']['type'] = 'title'; +$config->testtask->unitgroup->dtable->fieldList['suite']['fixed'] = false; +$config->testtask->unitgroup->dtable->fieldList['suite']['sortType'] = true; +$config->testtask->unitgroup->dtable->fieldList['suite']['group'] = 'story'; + +$config->testtask->unitgroup->dtable->fieldList['id'] = $config->testcase->dtable->fieldList['id']; +$config->testtask->unitgroup->dtable->fieldList['id']['type'] = 'id'; +$config->testtask->unitgroup->dtable->fieldList['id']['fixed'] = false; + +$config->testtask->unitgroup->dtable->fieldList['title'] = $config->testcase->dtable->fieldList['title']; +$config->testtask->unitgroup->dtable->fieldList['title']['width'] = 'auto'; +$config->testtask->unitgroup->dtable->fieldList['title']['nestedToggle'] = false; +$config->testtask->unitgroup->dtable->fieldList['title']['fixed'] = false; + +$config->testtask->unitgroup->dtable->fieldList['pri'] = $config->testcase->dtable->fieldList['pri']; +$config->testtask->unitgroup->dtable->fieldList['status'] = $config->testcase->dtable->fieldList['status']; +$config->testtask->unitgroup->dtable->fieldList['lastRunResult'] = $config->testcase->dtable->fieldList['lastRunResult']; +$config->testtask->unitgroup->dtable->fieldList['type'] = $config->testcase->dtable->fieldList['type']; +$config->testtask->unitgroup->dtable->fieldList['bugs'] = $config->testcase->dtable->fieldList['bugs']; +$config->testtask->unitgroup->dtable->fieldList['results'] = $config->testcase->dtable->fieldList['results']; +$config->testtask->unitgroup->dtable->fieldList['stepNumber'] = $config->testcase->dtable->fieldList['stepNumber']; +$config->testtask->unitgroup->dtable->fieldList['lastRunner'] = $config->testcase->dtable->fieldList['lastRunner']; +$config->testtask->unitgroup->dtable->fieldList['lastRunDate'] = $config->testcase->dtable->fieldList['lastRunDate']; +$config->testtask->unitgroup->dtable->fieldList['actions'] = $config->testcase->dtable->fieldList['actions']; +$config->testtask->unitgroup->dtable->fieldList['actions']['fixed'] = false; +$config->testtask->unitgroup->dtable->fieldList['actions']['menu'] = array('runResult'); diff --git a/module/testtask/control.php b/module/testtask/control.php index 5555a13c3e..dbd3be9991 100644 --- a/module/testtask/control.php +++ b/module/testtask/control.php @@ -409,7 +409,6 @@ class testtask extends control $cases = array(); $runs = $this->loadModel('testcase')->appendData($runs, 'testrun'); - foreach($runs as $run) $cases[$run->case] = $run; $results = $this->dao->select('*')->from(TABLE_TESTRESULT)->where('`case`')->in(array_keys($cases))->andWhere('run')->in(array_keys($runs))->fetchAll('run'); foreach($results as $result) @@ -419,38 +418,35 @@ class testtask extends control $runs[$result->run]->duration = $result->duration; } - $groupCases = $this->dao->select('*')->from(TABLE_SUITECASE)->where('`case`')->in(array_keys($cases))->orderBy('case')->fetchGroup('suite', 'case'); - $summary = array(); - if(empty($groupCases)) $groupCases[] = $cases; - foreach($groupCases as $suiteID => $groupCase) + $suitecases = $this->dao->select('*')->from(TABLE_SUITECASE)->where('`case`')->in(array_keys($cases))->orderBy('`case`')->fetchAll('case'); + + $groupCases = array(); + foreach($runs as $run) { - $caseCount = 0; - $failCount = 0; - $duration = 0; - foreach($groupCase as $caseID => $suitecase) - { - $case = $cases[$caseID]; - $groupCases[$suiteID][$caseID] = $case; - $duration += $case->duration; - $caseCount ++; - if($case->caseResult == 'fail') $failCount ++; - } - $summary[$suiteID] = sprintf($this->lang->testtask->summary, $caseCount, $failCount, $duration); + $run->suite = !empty($suitecases[$run->case]) ? $suitecases[$run->case]->suite : ''; + $groupCases[$run->suite][] = $run; } - $suites = $this->loadModel('testsuite')->getUnitSuites($productID); + $suite = null; + foreach($runs as $run) + { + $run->rowspan = 0; + if($suite !== $run->suite) + { + $suite = $run->suite; + if(!empty($groupCases[$run->suite])) $run->rowspan = count($groupCases[$run->suite]); + } + } /* Assign. */ - $this->view->title = $this->products[$productID] . $this->lang->colon . $this->lang->testcase->common; - + $this->view->title = $this->products[$productID] . $this->lang->colon . $this->lang->testcase->common; $this->view->productID = $productID; $this->view->task = $task; $this->view->product = $this->product->getById($productID); $this->view->productName = $this->products[$productID]; $this->view->users = $this->loadModel('user')->getPairs('noletter'); - $this->view->groupCases = $groupCases; - $this->view->suites = $suites; - $this->view->summary = $summary; + $this->view->runs = $runs; + $this->view->suites = $this->loadModel('testsuite')->getUnitSuites($productID); $this->view->taskID = $taskID; $this->display(); @@ -736,14 +732,14 @@ class testtask extends control } } - $story = ''; - foreach($runs as $index => $case) + $story = null; + foreach($runs as $run) { - $case->rowspan = 0; - if($story !== $case->story) + $run->rowspan = 0; + if($story !== $run->story) { - $story = $case->story; - if(!empty($groupCases[$case->story])) $case->rowspan = count($groupCases[$case->story]); + $story = $run->story; + if(!empty($groupCases[$run->story])) $run->rowspan = count($groupCases[$run->story]); } } diff --git a/module/testtask/css/unitcases.ui.css b/module/testtask/css/unitcases.ui.css new file mode 100644 index 0000000000..ab88b822a1 --- /dev/null +++ b/module/testtask/css/unitcases.ui.css @@ -0,0 +1,2 @@ +.toggle-icon.is-collapsed:before,.toggle-icon.is-expanded:before,.toggle-icon.is-collapsed:after {background-color: var(--color-current); content: " "; display: block; height: 1px; left: 2px; position: absolute; right: 2px; top: calc((var(--toggle-icon-size) - 3px)/2);} +.toggle-icon.is-collapsed:after {--tw-rotate: 90deg; transform: translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));} diff --git a/module/testtask/js/groupcase.ui.js b/module/testtask/js/groupcase.ui.js index 11c9ad0a03..8ffc9cb13c 100644 --- a/module/testtask/js/groupcase.ui.js +++ b/module/testtask/js/groupcase.ui.js @@ -65,7 +65,6 @@ window.deformation = function(event) if($(event.target).closest('a').find('span').hasClass('is-collapsed')) { - console.log(initialOptions.data); $.each(options.data, function(index) { if(!options.data[index]) return; diff --git a/module/testtask/js/unitcases.ui.js b/module/testtask/js/unitcases.ui.js new file mode 100644 index 0000000000..8b1546a644 --- /dev/null +++ b/module/testtask/js/unitcases.ui.js @@ -0,0 +1,107 @@ +$(function() +{ + const options = zui.DTable.query().options; + initialOptions = $.extend(true, {}, options); +}); + +/** + * 需求列显示展开收起的图标。 + * Display show icon in the suite column. + * + * @param object result + * @param object info + * @access public + * @return object + */ +window.onRenderCell = function(result, {row, col}) +{ + if(result && col.name == 'suite') + { + if(row.data.hidden) + { + result.unshift({html: ''}); + } + else + { + result.unshift({html: ''}); + result.push({outer: false, style: {alignItems: 'start', 'padding-top': '8px'}}) + } + } + if(result && col.name == 'id' && row.data.hidden) + { + result.push({outer: false, style: {alignItems: 'center', justifyContent: 'start'}}) + } + + return result; +} + +/** + * 需求列合并单元格。 + * cell span in the suite column. + * + * @param object cell + * @access public + * @return object + */ +window.getCellSpan = function(cell) +{ + if(cell.col.name == 'suite' && cell.row.data.rowspan) + { + return {rowSpan: cell.row.data.rowspan}; + } + if(cell.col.name == 'id' && cell.row.data.colspan) + { + return {colSpan: cell.row.data.colspan}; + } +} + +window.deformation = function(event) +{ + let newData = []; + const options = zui.DTable.query().options; + const suite = $(event.target).closest('a').data('suite'); + const oldOptions = $.extend(true, {}, initialOptions); + + + if($(event.target).closest('a').find('span').hasClass('is-collapsed')) + { + $.each(options.data, function(index) + { + if(!options.data[index]) return; + if(options.data[index].suite == suite) + { + $.each(oldOptions.data, function(key) + { + if(!oldOptions.data[key]) return; + if(oldOptions.data[key].suite == suite) newData.push(oldOptions.data[key]); + }); + } + else + { + newData.push(options.data[index]); + } + }); + options.data = newData; + $(event.target).closest('a').find('span').removeClass('is-collapsed').addClass('is-expanded'); + $('#groupCaseTable').zui('dtable').render(options); + } + else + { + options.data = options.data.filter(function(option) + { + return option.suite != suite || option.rowspan != 0; + }); + $.each(options.data, function(index) + { + if(options.data[index] && options.data[index].suite == suite) + { + options.data[index].id = {html: '' + allTestcases + ' ' + '' + options.data[index].rowspan + ''}; + options.data[index].rowspan = 1; + options.data[index].colspan = 12; + options.data[index].hidden = 1; + } + }); + $(event.target).closest('a').find('span').removeClass('is-expanded').addClass('is-collapsed'); + $('#groupCaseTable').zui('dtable').render(); + } +} diff --git a/module/testtask/ui/unitcases.html.php b/module/testtask/ui/unitcases.html.php new file mode 100644 index 0000000000..3dca4a2b17 --- /dev/null +++ b/module/testtask/ui/unitcases.html.php @@ -0,0 +1,43 @@ + + * @package testtask + * @link https://www.zentao.net + */ +namespace zin; +jsVar('allTestcases', $lang->testcase->allTestcases); + +$canExport = hasPriv('testcase', 'export'); + +featureBar(); + +toolbar +( + set::items + ( + array + ( + $canExport ? array('class' => 'ghost', 'icon' => 'export', 'text' => $lang->export, 'url' => $this->createLink('testcase', 'export', "productID=$productID&orderBy=id&taskID=0&browseType="), 'data-toggle' => 'modal') : null, + array('class' => 'ghost', 'icon' => 'back', 'text' => $lang->goback, 'url' => $this->session->testtaskList ? $this->session->testtaskList : $this->createLink('testtask', 'browseUnits')) + ) + ) +); + +$runs = initTableData($runs, $config->testtask->unitgroup->dtable->fieldList); + +dtable +( + set::id('groupCaseTable'), + set::userMap($users), + set::cols($config->testtask->unitgroup->dtable->fieldList), + set::data($runs), + set::plugins(array('cellspan')), + set::onRenderCell(jsRaw('window.onRenderCell')), + set::getCellSpan(jsRaw('window.getCellSpan')), +); + +render();