diff --git a/module/testcase/config/action.php b/module/testcase/config/action.php index 7a8bf2056b..e78f94fed6 100644 --- a/module/testcase/config/action.php +++ b/module/testcase/config/action.php @@ -55,7 +55,7 @@ $config->testcase->actionList['create']['url'] = array('module' => 'testcase', $config->testcase->actionList['unlinkCase']['icon'] = 'unlink'; $config->testcase->actionList['unlinkCase']['text'] = $lang->testtask->unlinkCase; $config->testcase->actionList['unlinkCase']['hint'] = $lang->testtask->unlinkCase; -$config->testcase->actionList['unlinkCase']['url'] = array('module' => 'testtask', 'method' => 'unlinkCase', 'params' => 'caseID={id}&confirm=yes'); +$config->testcase->actionList['unlinkCase']['url'] = array('module' => 'testtask', 'method' => 'unlinkCase', 'params' => 'runID={id}&confirm=yes'); $config->testcase->actionList['showScript']['icon'] = 'file-code'; $config->testcase->actionList['showScript']['text'] = $lang->testcase->showScript; diff --git a/module/testtask/control.php b/module/testtask/control.php index f27bc04da0..d04e6a35c0 100644 --- a/module/testtask/control.php +++ b/module/testtask/control.php @@ -714,13 +714,11 @@ class testtask extends control $this->loadModel('common')->saveQueryCondition($this->dao->get(), 'testcase', false); $runs = $this->testcase->appendData($runs, 'run'); $groupCases = array(); - $groupByList = array(); foreach($runs as $run) { if($groupBy == 'story') { $groupCases[$run->story][] = $run; - $groupByList[$run->story] = $run->storyTitle; } elseif($groupBy == 'assignedTo') { @@ -735,7 +733,17 @@ class testtask extends control foreach($buildStories as $buildStory) { $groupCases[$buildStory->id][] = $buildStory; - $groupByList[$buildStory->id] = $buildStory->title; + } + } + + $story = ''; + foreach($runs as $index => $case) + { + $case->rowspan = 0; + if($story !== $case->story) + { + $story = $case->story; + if(!empty($groupCases[$case->story])) $case->rowspan = count($groupCases[$case->story]); } } @@ -747,8 +755,7 @@ class testtask extends control $this->view->taskID = $taskID; $this->view->browseType = 'group'; $this->view->groupBy = $groupBy; - $this->view->groupByList = $groupByList; - $this->view->cases = $runs; + $this->view->runs = $runs; $this->view->account = 'all'; $this->view->canBeChanged = $canBeChanged; $this->display(); diff --git a/module/testtask/css/groupcase.ui.css b/module/testtask/css/groupcase.ui.css new file mode 100644 index 0000000000..ab88b822a1 --- /dev/null +++ b/module/testtask/css/groupcase.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 new file mode 100644 index 0000000000..11c9ad0a03 --- /dev/null +++ b/module/testtask/js/groupcase.ui.js @@ -0,0 +1,108 @@ +$(function() +{ + const options = zui.DTable.query().options; + initialOptions = $.extend(true, {}, options); +}); + +/** + * 需求列显示展开收起的图标。 + * Display show icon in the story column. + * + * @param object result + * @param object info + * @access public + * @return object + */ +window.onRenderCell = function(result, {row, col}) +{ + if(result && col.name == 'storyTitle') + { + 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 story column. + * + * @param object cell + * @access public + * @return object + */ +window.getCellSpan = function(cell) +{ + if(cell.col.name == 'storyTitle' && 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 story = $(event.target).closest('a').data('story'); + const oldOptions = $.extend(true, {}, initialOptions); + + + if($(event.target).closest('a').find('span').hasClass('is-collapsed')) + { + console.log(initialOptions.data); + $.each(options.data, function(index) + { + if(!options.data[index]) return; + if(options.data[index].story == story) + { + $.each(oldOptions.data, function(key) + { + if(!oldOptions.data[key]) return; + if(oldOptions.data[key].story == story) 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.story != story || option.rowspan != 0; + }); + $.each(options.data, function(index) + { + if(options.data[index] && options.data[index].story == story) + { + 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/cases.html.php b/module/testtask/ui/cases.html.php index 3ce3a98c33..af46e2dabd 100644 --- a/module/testtask/ui/cases.html.php +++ b/module/testtask/ui/cases.html.php @@ -27,7 +27,7 @@ $canBatchAssign = hasPriv('testtask', 'batchAssign'); $canBatchRun = hasPriv('testtask', 'batchRun'); $canBatchAction = ($canBeChanged && ($canBatchEdit || $canBatchUnlink || $canBatchAssign || $canBatchRun)); -$closeLink = $browseType == 'bymodule' ? inlink('cases', "taskID=$task->id&browseType=$browseType¶m=0&orderBy=$orderBy&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}") : 'javascript:removeCookieByKey("taskCaseModule")'; +$closeLink = $browseType == 'bymodule' ? inlink('cases', "taskID={$task->id}&browseType={$browseType}¶m=0&orderBy={$orderBy}&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}") : 'javascript:removeCookieByKey("taskCaseModule")'; sidebar ( moduleMenu(set(array @@ -40,7 +40,7 @@ sidebar /* Process variables of sutie menu. */ $suiteItems = array(); -if(empty($suiteList)) +if(empty($suites)) { if($canCreateSuite && (empty($productID) || common::canModify('product', $product))) { diff --git a/module/testtask/ui/groupcase.html.php b/module/testtask/ui/groupcase.html.php index d9229b3f55..f7897b5aac 100644 --- a/module/testtask/ui/groupcase.html.php +++ b/module/testtask/ui/groupcase.html.php @@ -11,14 +11,95 @@ declare(strict_types=1); namespace zin; jsVar('allTestcases', $lang->testcase->allTestcases); -$cases = initTableData(array_values($cases), $config->testcase->group->dtable->fieldList); +$canCreateSuite = hasPriv('testsuite', 'create'); +$canLinkCase = hasPriv('testtask', 'linkCase'); +$canExport = hasPriv('testcase', 'export'); +$canReport = hasPriv('testtask', 'report'); +$canView = hasPriv('testtask', 'view'); + +/* Process variables of sutie menu. */ +$suiteItems = array(); +if(empty($suites)) +{ + if($canCreateSuite && (empty($productID) || common::canModify('product', $product))) + { + $suiteItems[] = array('text' => $lang->testsuite->create, 'url' => $this->createLink('testsuite', 'create', "productID=$productID")); + } +} +else +{ + foreach($suites as $id => $name) + { + $suiteItems[] = array('text' => $name, 'url' => inlink('cases', "taskID=$task->id&browseType=bySuite¶m=$id"), 'active' => $name == $suiteName); + } +} + +featureBar +( + li + ( + set::class('nav-item'), + a + ( + set::href(inlink('cases', "taskID=$task->id&browseType=all")), + set('data-app', $app->tab), + $lang->testtask->allCases + ) + ), + li + ( + set::class('nav-item'), + a + ( + set::href(inlink('cases', "taskID=$task->id&browseType=assignedtome")), + set('data-app', $app->tab), + $lang->testtask->assignedToMe + ) + ) +); + +$viewItems = array(array('text' => $lang->testcase->listView, 'url' => inlink('browse', "productID=$productID&branch=$branch&browseType=all"), 'active' => $rawMethod != 'groupcase' ? true : false)); +toolbar +( + dropdown + ( + btn + ( + setClass('btn btn-link ghost square'), + set::icon('kanban') + ), + set::items($viewItems), + set::placement('bottom-end'), + ), + set::items + ( + array + ( + $canLinkCase ? array('class' => 'ghost', 'icon' => 'link', 'text' => $lang->testtask->linkCase, 'url' => inlink('linkCase', "taskID=$task->id")) : null, + $canExport ? array('class' => 'ghost', 'icon' => 'export', 'text' => $lang->export, 'url' => $this->createLink('testcase', 'export', "productID=$productID&orderBy=case_desc&taskID=$task->id"), 'data-toggle' => 'modal') : null, + $canReport ? array('class' => 'ghost', 'icon' => 'bar-chart', 'text' => $lang->testtask->report->common, 'url' => inlink('report', "productID=$productID&taskID=$task->id&browseType=$browseType&branchID=$task->branch&moduleID=" . (empty($moduleID) ? '' : $moduleID))) : null, + $canView ? array('class' => 'ghost', 'icon' => 'list-alt', 'text' => $lang->testtask->view, 'url' => inlink('view', "taskID=$task->id")) : null, + array('class' => 'ghost', 'icon' => 'back', 'text' => $lang->goback, 'url' => $this->session->testtaskList) + ) + ) +); + +$config->testcase->actionList['runCase']['url'] = array('module' => 'testtask', 'method' => 'runCase', 'params' => 'runID={id}&caseID={case}&version={version}'); +$config->testcase->actionList['edit']['url'] = array('module' => 'testcase', 'method' => 'edit', 'params' => 'caseID={case}&comment=false&executionID=%executionID%'); + +$config->testcase->group->dtable->fieldList['actions']['list'] = $config->testcase->actionList; +$config->testcase->group->dtable->fieldList['id']['name'] = 'case'; +$config->testcase->group->dtable->fieldList['actions']['menu'] = array('runCase', 'edit', 'unlinkCase'); +$config->testcase->group->dtable->fieldList['title']['link']['params'] = 'caseID={case}'; + +$runs = initTableData($runs, $config->testcase->group->dtable->fieldList); dtable ( set::id('groupCaseTable'), set::userMap($users), set::cols($config->testcase->group->dtable->fieldList), - set::data($cases), + set::data($runs), set::plugins(array('cellspan')), set::onRenderCell(jsRaw('window.onRenderCell')), set::getCellSpan(jsRaw('window.getCellSpan')),