create.html.php 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569
  1. <?php
  2. /**
  3. * The create view file of testreport module of ZenTaoPMS.
  4. * @copyright Copyright 2009-2023 禅道软件(青岛)有限公司(ZenTao Software (Qingdao) Co., Ltd. www.zentao.net)
  5. * @license ZPL(https://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
  6. * @author Yuting Wang <wangyuting@easycorp.ltd>
  7. * @package testreport
  8. * @link https://www.zentao.net
  9. */
  10. namespace zin;
  11. include($this->app->getModuleRoot() . 'ai/ui/inputinject.html.php');
  12. jsVar('objectID', $objectID);
  13. jsVar('objectType', $objectType);
  14. jsVar('extra', $extra);
  15. jsVar('reportID', !empty($report->id) ? $report->id : 0);
  16. $caseCharts = array();
  17. foreach($charts as $chartType => $chartOption)
  18. {
  19. $chartData = $datas[$chartType];
  20. $chartOption = array();
  21. $tableTR = array();
  22. $colorList = array('#5470C6', '#91CC75', '#FAC858', '#EE6666', '#73C0DE', '#3BA272', '#FC8452', '#9A60B4', '#EA7CCC');
  23. foreach($chartData as $key => $data)
  24. {
  25. $color = current($colorList);
  26. $chartOption[] = array('name' => $data->name, 'value' => $data->value);
  27. $tableTR[] = h::tr
  28. (
  29. h::td(label(set::className('label-dot mr-2'), set::style(array('background-color' => $color, '--tw-ring-color' => $color))), $data->name),
  30. h::td($data->value),
  31. h::td(($data->percent * 100) . '%')
  32. );
  33. if(!next($colorList)) reset($colorList);
  34. }
  35. $caseCharts[] = div
  36. (
  37. set::className('mt-6'),
  38. div
  39. (
  40. set::className('flex border'),
  41. cell
  42. (
  43. set::width('50%'),
  44. set::className('border-r'),
  45. div(set::className('center text-base font-bold py-2'), $lang->testtask->report->charts[$chartType]),
  46. echarts
  47. (
  48. set::color($colorList),
  49. set::width('100%'),
  50. set::height('300px'),
  51. set::series
  52. (
  53. array
  54. (
  55. array
  56. (
  57. 'data' => $chartOption,
  58. 'type' => 'pie'
  59. )
  60. )
  61. ),
  62. set::tooltip(array('show' => true, 'formatter' => "{b} : {d}%"))
  63. )
  64. ),
  65. cell
  66. (
  67. set::width('50%'),
  68. h::table
  69. (
  70. set::className('table'),
  71. h::tr
  72. (
  73. h::th($lang->report->item),
  74. h::th(set::width('100px'), $lang->report->value),
  75. h::th(set::width('120px'), $lang->report->percent)
  76. ),
  77. $tableTR
  78. )
  79. )
  80. )
  81. );
  82. }
  83. $tableTR = array();
  84. $colorList = array('#D5D9DF', '#D50000', '#FF9800', '#2098EE', '#009688');
  85. $chartOption = array();
  86. foreach($lang->bug->priList as $key => $value)
  87. {
  88. $color = current($colorList);
  89. $label = $key == 0 ? $lang->null : $value;
  90. $generated = !empty($bugInfo['bugStageGroups'][$key]['generated']) ? $bugInfo['bugStageGroups'][$key]['generated'] : 0;
  91. $legacy = !empty($bugInfo['bugStageGroups'][$key]['legacy']) ? $bugInfo['bugStageGroups'][$key]['legacy'] : 0;
  92. $resolved = !empty($bugInfo['bugStageGroups'][$key]['resolved']) ? $bugInfo['bugStageGroups'][$key]['resolved'] : 0;
  93. $chartOption[] = array('name' => $label, 'type' => 'bar', 'data' => array($generated, $legacy, $resolved));
  94. $tableTR[] = h::tr
  95. (
  96. h::td(label(set::className('label-dot mr-2'), set::style(array('background-color' => $color, '--tw-ring-color' => $color))), $label),
  97. h::td($generated),
  98. h::td($legacy),
  99. h::td($resolved)
  100. );
  101. if(!next($colorList)) reset($colorList);
  102. }
  103. $bugStageChart = div
  104. (
  105. set::className('mt-6'),
  106. div
  107. (
  108. set::className('flex border'),
  109. cell
  110. (
  111. set::width('50%'),
  112. set::className('border-r'),
  113. div(set::className('center text-base font-bold py-2'), $lang->testreport->bugStageGroups),
  114. echarts
  115. (
  116. set::color($colorList),
  117. set::width('100%'),
  118. set::height('300px'),
  119. set::xAxis
  120. (
  121. array
  122. (
  123. 'type' => 'category',
  124. 'data' => array($lang->testreport->bugStageList['generated'], $lang->testreport->bugStageList['legacy'], $lang->testreport->bugStageList['resolved'])
  125. )
  126. ),
  127. set::yAxis(array('type' => 'value')),
  128. set::series($chartOption),
  129. set::tooltip(array('trigger' => 'axis', 'axisPointer' => array('type' => 'shadow')))
  130. )
  131. ),
  132. cell
  133. (
  134. set::width('50%'),
  135. h::table
  136. (
  137. set::className('table'),
  138. h::tr
  139. (
  140. h::th($lang->bug->pri),
  141. h::th($lang->testreport->bugStageList['generated']),
  142. h::th($lang->testreport->bugStageList['legacy']),
  143. h::th($lang->testreport->bugStageList['resolved'])
  144. ),
  145. $tableTR
  146. )
  147. )
  148. )
  149. );
  150. $tableTR = array();
  151. $chartOption = array();
  152. $xAxisData = array();
  153. $beginTime = isset($report->begin) ? strtotime($report->begin) : strtotime($begin);
  154. $endTime = isset($report->end) ? strtotime($report->end) : strtotime($end);
  155. foreach(array('generated', 'legacy', 'resolved') as $field)
  156. {
  157. $chartOption[$field] = array('name' => $lang->testreport->bugStageList[$field], 'type' => 'line', 'data' => array());
  158. }
  159. for($time = $beginTime; $time <= $endTime; $time += 86400)
  160. {
  161. $date = date('m-d', $time);
  162. $generated = !empty($bugInfo['bugHandleGroups']['generated'][$date]) ? $bugInfo['bugHandleGroups']['generated'][$date] : 0;
  163. $legacy = !empty($bugInfo['bugHandleGroups']['legacy'][$date]) ? $bugInfo['bugHandleGroups']['legacy'][$date] : 0;
  164. $resolved = !empty($bugInfo['bugHandleGroups']['resolved'][$date]) ? $bugInfo['bugHandleGroups']['resolved'][$date] : 0;
  165. $chartOption['generated']['data'][] = $generated;
  166. $chartOption['legacy']['data'][] = $legacy;
  167. $chartOption['resolved']['data'][] = $resolved;
  168. $xAxisData[] = $date;
  169. $tableTR[] = h::tr
  170. (
  171. h::td(setClass('text-center'), $date),
  172. h::td($generated),
  173. h::td($legacy),
  174. h::td($resolved)
  175. );
  176. }
  177. $chartOption = array_values($chartOption);
  178. $bugHandleChart = div
  179. (
  180. set::className('mt-6'),
  181. div
  182. (
  183. set::className('flex border'),
  184. cell
  185. (
  186. set::width('50%'),
  187. set::className('border-r'),
  188. div(set::className('center text-base font-bold py-2'), $lang->testreport->bugHandleGroups),
  189. echarts
  190. (
  191. set::color(array('#FF9800', '#2098EE', '#009688')),
  192. set::width('100%'),
  193. set::height('300px'),
  194. set::xAxis
  195. (
  196. array
  197. (
  198. 'type' => 'category',
  199. 'data' => $xAxisData
  200. )
  201. ),
  202. set::yAxis(array('type' => 'value')),
  203. set::series($chartOption),
  204. set::tooltip(array('trigger' => 'axis', 'axisPointer' => array('type' => 'shadow')))
  205. )
  206. ),
  207. cell
  208. (
  209. set::width('50%'),
  210. h::table
  211. (
  212. set::className('table'),
  213. h::tr
  214. (
  215. h::th($lang->testreport->date),
  216. h::th(label(set::className('label-dot mr-2'), set::style(array('background-color' => '#FF9800', '--tw-ring-color' => '#FF9800'))), $lang->testreport->bugStageList['generated']),
  217. h::th(label(set::className('label-dot mr-2'), set::style(array('background-color' => '#2098EE', '--tw-ring-color' => '#2098EE'))), $lang->testreport->bugStageList['legacy']),
  218. h::th(label(set::className('label-dot mr-2'), set::style(array('background-color' => '#009688', '--tw-ring-color' => '#009688'))), $lang->testreport->bugStageList['resolved'])
  219. ),
  220. $tableTR
  221. )
  222. )
  223. )
  224. );
  225. $bugCharts = array();
  226. foreach($bugInfo as $infoKey => $infoValue)
  227. {
  228. if($infoKey == 'bugStageGroups' || $infoKey == 'bugHandleGroups') continue;
  229. $list = $infoValue;
  230. if($infoKey == 'bugSeverityGroups') $list = $lang->bug->severityList;
  231. if($infoKey == 'bugStatusGroups') $list = $lang->bug->statusList;
  232. if($infoKey == 'bugResolutionGroups') $list = $lang->bug->resolutionList;
  233. $chartOption = array();
  234. $tableTR = array();
  235. $colorList = array('#5470C6', '#91CC75', '#FAC858', '#EE6666', '#73C0DE', '#3BA272', '#FC8452', '#9A60B4', '#EA7CCC');
  236. $sum = 0;
  237. foreach($infoValue as $value) $sum += $value->value;
  238. foreach($list as $listKey => $listValue)
  239. {
  240. $color = current($colorList);
  241. $name = $listValue;
  242. $value = 0;
  243. if(isset($infoValue[$listKey]))
  244. {
  245. $name = $infoValue[$listKey]->name;
  246. $value = $infoValue[$listKey]->value;
  247. }
  248. if(empty($name) && empty($value)) continue;
  249. $chartOption[] = array('name' => $name, 'value' => $value);
  250. $tableTR[] = h::tr
  251. (
  252. h::td(label(set::className('label-dot mr-2'), set::style(array('background-color' => $color, '--tw-ring-color' => $color))), $name),
  253. h::td($value),
  254. h::td(($sum ? round(($value / $sum * 100), 2) : '0') . '%')
  255. );
  256. if(!next($colorList)) reset($colorList);
  257. }
  258. $bugCharts[] = div
  259. (
  260. set::className('mt-6'),
  261. div
  262. (
  263. set::className('flex border'),
  264. cell
  265. (
  266. set::width('50%'),
  267. set::className('border-r'),
  268. div(set::className('center text-base font-bold py-2'), $lang->testreport->{$infoKey}),
  269. echarts
  270. (
  271. set::color($colorList),
  272. set::width('100%'),
  273. set::height('300px'),
  274. set::series
  275. (
  276. array
  277. (
  278. array
  279. (
  280. 'data' => $chartOption,
  281. 'type' => 'pie'
  282. )
  283. )
  284. ),
  285. set::tooltip(array('show' => true, 'formatter' => "{b} : {d}%"))
  286. )
  287. ),
  288. cell
  289. (
  290. set::width('50%'),
  291. h::table
  292. (
  293. set::className('table'),
  294. h::tr
  295. (
  296. h::th($lang->report->item),
  297. h::th(set::width('100px'), $lang->report->value),
  298. h::th(set::width('120px'), $lang->report->percent)
  299. ),
  300. $tableTR
  301. )
  302. )
  303. )
  304. );
  305. }
  306. panel
  307. (
  308. formPanel
  309. (
  310. on::change('#selectTask', 'changeTesttask'),
  311. set::title($lang->testreport->create),
  312. !empty($taskPairs) ? formRow
  313. (
  314. formGroup
  315. (
  316. set::width('1/2'),
  317. set::label($lang->testtask->common),
  318. set::required(true),
  319. set::control('picker'),
  320. set::name('selectTask'),
  321. set::items($taskPairs),
  322. set::value($objectID)
  323. )
  324. ) : null,
  325. formRow
  326. (
  327. formGroup(set::width('1/2'), set::label($lang->testreport->startEnd), set::required(strpos(",{$this->config->testreport->create->requiredFields},", ",begin,") !== false || strpos(",{$this->config->testreport->create->requiredFields},", ",end,") !== false), inputGroup
  328. (
  329. datePicker
  330. (
  331. set::name('begin'),
  332. set::value($begin),
  333. setData(array('on' => 'change', 'call' => 'refreshPage'))
  334. ),
  335. $lang->testtask->to,
  336. datePicker
  337. (
  338. set::name('end'),
  339. set::value($end),
  340. setData(array('on' => 'change', 'call' => 'refreshPage'))
  341. )
  342. ), input
  343. (
  344. set::className('hidden'),
  345. set::name('product'),
  346. set::value($productIdList)
  347. ), input
  348. (
  349. set::className('hidden'),
  350. set::name('execution'),
  351. set::value(isset($execution->id) ? $execution->id : 0)
  352. ), input
  353. (
  354. set::className('hidden'),
  355. set::name('tasks'),
  356. set::value($tasks)
  357. ), input
  358. (
  359. set::className('hidden'),
  360. set::name('objectID'),
  361. set::value($objectID)
  362. ), input
  363. (
  364. set::className('hidden'),
  365. set::name('objectType'),
  366. set::value($objectType)
  367. ), input
  368. (
  369. set::className('hidden'),
  370. set::name('bugs'),
  371. set::value(implode(',', array_keys($bugs)))
  372. ), input
  373. (
  374. set::className('hidden'),
  375. set::name('builds'),
  376. set::value(implode(',', array_keys($builds)))
  377. ), input
  378. (
  379. set::className('hidden'),
  380. set::name('cases'),
  381. set::value(implode(',', array_keys($caseList)))
  382. ), input
  383. (
  384. set::className('hidden'),
  385. set::name('stories'),
  386. set::value(implode(',', array_keys($stories)))
  387. )),
  388. formGroup
  389. (
  390. set::width('1/2'),
  391. set::label($lang->testreport->owner),
  392. set::control('picker'),
  393. set::name('owner'),
  394. set::items($users),
  395. set::value($owner)
  396. )
  397. ),
  398. ($maxRunDate && $maxRunDate > $end) ? formGroup
  399. (
  400. setClass('items-center runDate-tips'),
  401. set::label(''),
  402. div(
  403. setClass('text-warning'),
  404. span(sprintf($lang->testreport->runDateTips, $maxRunDate) . ' '),
  405. span(
  406. setClass('underline cursor-pointer'),
  407. on::click('ignoreRunDate'),
  408. $lang->testreport->ignore
  409. )
  410. )
  411. ) : null,
  412. formRow
  413. (
  414. formGroup(set::label($lang->testreport->members), set::required(strpos(",{$this->config->testreport->create->requiredFields},", ",members,") !== false), picker
  415. (
  416. set::multiple(true),
  417. set::name('members[]'),
  418. set::items($users),
  419. set::value($members)
  420. ))
  421. ),
  422. formRow
  423. (
  424. formGroup
  425. (
  426. set::label($lang->testreport->title),
  427. set::name('title'),
  428. set::value($reportTitle)
  429. )
  430. ),
  431. !empty($execution->desc) ? formRow
  432. (
  433. formGroup
  434. (
  435. set::className('items-center'),
  436. set::label($lang->testreport->goal),
  437. span
  438. (
  439. setClass('flex items-center'),
  440. icon
  441. (
  442. 'help',
  443. setClass('text-light mr-0.5'),
  444. setData(array('toggle' => 'tooltip', 'title' => $lang->testreport->goalTip))
  445. ),
  446. strip_tags($execution->desc)
  447. )
  448. )
  449. ) : null,
  450. formRow
  451. (
  452. formGroup
  453. (
  454. set::className('items-center'),
  455. set::label($lang->testreport->profile),
  456. div
  457. (
  458. div(html($storySummary)),
  459. div(html(sprintf($lang->testreport->buildSummary, empty($builds) ? 1 : count($builds)) . $caseSummary)),
  460. div(html(sprintf($lang->testreport->bugSummary, $bugSummary['foundBugs'], count($legacyBugs), $bugSummary['activatedBugs'], $bugSummary['countBugByTask'], $bugSummary['bugConfirmedRate'] . '%', $bugSummary['bugCreateByCaseRate'] . '%')))
  461. )
  462. )
  463. ),
  464. formRow
  465. (
  466. formGroup
  467. (
  468. set::label($lang->testreport->report),
  469. set::control('editor'),
  470. set::name('report')
  471. )
  472. ),
  473. formRow
  474. (
  475. formGroup
  476. (
  477. set::label($lang->files),
  478. fileSelector()
  479. )
  480. )
  481. ),
  482. formPanel
  483. (
  484. set::title($lang->testreport->legendStoryAndBug),
  485. set::actions(array()),
  486. dtable
  487. (
  488. set::cols($config->testreport->story->dtable->fieldList),
  489. set::data(array_values($stories)),
  490. set::emptyTip($lang->story->noStory),
  491. set::userMap($users)
  492. ),
  493. div(set::className('my-6')),
  494. dtable
  495. (
  496. set::cols($config->testreport->bug->dtable->fieldList),
  497. set::data(array_values($bugs)),
  498. set::emptyTip($lang->bug->notice->noBug),
  499. set::userMap($users)
  500. )
  501. ),
  502. formPanel
  503. (
  504. set::className('mt-6'),
  505. set::title($lang->testreport->legendBuild),
  506. set::actions(array()),
  507. dtable
  508. (
  509. set::cols($config->testreport->build->dtable->fieldList),
  510. set::data(array_values($builds)),
  511. set::userMap($users)
  512. )
  513. ),
  514. formPanel
  515. (
  516. set::className('mt-6'),
  517. set::title($lang->testreport->legendCase),
  518. set::actions(array()),
  519. dtable
  520. (
  521. set::cols($config->testreport->testcase->dtable->fieldList),
  522. set::data(array_values($caseList)),
  523. set::userMap($users)
  524. )
  525. ),
  526. formPanel
  527. (
  528. set::className('mt-6'),
  529. set::title($lang->testreport->legendLegacyBugs),
  530. set::actions(array()),
  531. dtable
  532. (
  533. set::cols($config->testreport->bug->dtable->fieldList),
  534. set::data(array_values($legacyBugs)),
  535. set::userMap($users)
  536. )
  537. ),
  538. formPanel
  539. (
  540. setID('tabReport'),
  541. set::className('mt-6'),
  542. set::title($lang->testreport->legendReport),
  543. set::actions(array()),
  544. $caseCharts,
  545. $bugStageChart,
  546. $bugHandleChart,
  547. $bugCharts
  548. )
  549. );
  550. render();