projectstatisticblock.html.php 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418
  1. <?php
  2. /**
  3. * The project statistic block view file of block 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 block
  8. * @link https://www.zentao.net
  9. */
  10. namespace zin;
  11. $active = isset($params['active']) ? $params['active'] : key($projects);
  12. $project = null;
  13. $isEn = $app->getClientLang() == 'en';
  14. $items = array();
  15. foreach($projects as $projectItem)
  16. {
  17. $params = helper::safe64Encode("module={$block->module}&active={$projectItem->id}");
  18. $items[] = array
  19. (
  20. 'id' => $projectItem->id,
  21. 'text' => $projectItem->name,
  22. 'url' => createLink('project', 'index', "projectID={$projectItem->id}"),
  23. 'activeUrl' => createLink('block', 'printBlock', "blockID={$block->id}&params={$params}")
  24. );
  25. if($projectItem->id == $active) $project = $projectItem;
  26. }
  27. $remainingDays = !empty($project->remainingDays) ? $project->remainingDays : 0;
  28. $projectOverview = array();
  29. if($project)
  30. {
  31. $projectOverview[] = cell
  32. (
  33. setClass('text-left'),
  34. $project->status != 'closed' && $project->end != LONG_TIME ? span
  35. (
  36. setClass('text-gray block'),
  37. $remainingDays >= 0 ? $lang->block->projectstatistic->leftDaysPre : $lang->block->projectstatistic->delayDaysPre,
  38. span
  39. (
  40. setClass('font-bold text-gray-950 px-1'),
  41. abs($remainingDays)
  42. ),
  43. $lang->block->projectstatistic->day
  44. ) : span
  45. (
  46. setClass('text-gray'),
  47. $project->status == 'closed' ? $lang->block->projectstatistic->projectClosed : $lang->block->projectstatistic->longTimeProject
  48. )
  49. );
  50. $projectOverview[] = $config->edition != 'open' && $config->edition != 'biz' ? div(setClass('divider mx-1 my-auto h-4')) : null;
  51. $projectOverview[] = $config->edition != 'open' && $config->edition != 'biz' ? cell
  52. (
  53. setClass('flex-0 text-left' . (!$longBlock ? ' w-full' : '')),
  54. span
  55. (
  56. setClass('text-gray mr-4'),
  57. $lang->block->projectstatistic->existRisks,
  58. span
  59. (
  60. setClass('font-bold ml-2 text-danger'),
  61. $project->risks
  62. )
  63. ),
  64. span
  65. (
  66. setClass('text-gray'),
  67. $lang->block->projectstatistic->existIssues,
  68. span
  69. (
  70. setClass('font-bold ml-2 text-gray-950'),
  71. $project->issues
  72. )
  73. )
  74. ) : '';
  75. $lastestExecution = !empty($project->executions) && $project->multiple ? cell
  76. (
  77. setClass('flex overflow-hidden whitespace-nowrap clip w-full' . (!$longBlock ? ' flex-0 text-left w-full' : ' flex-1')),
  78. span
  79. (
  80. setClass('text-gray'),
  81. $lang->block->projectstatistic->lastestExecution,
  82. hasPriv('execution', 'task') ? a
  83. (
  84. setClass('pl-2'),
  85. set::href(helper::createLink('execution', 'task', "executionID={$project->executions[0]->id}")),
  86. set('title', $project->executions[0]->name),
  87. $project->executions[0]->name
  88. ) : span
  89. (
  90. setClass('pl-2'),
  91. $project->executions[0]->name
  92. )
  93. )
  94. ) : null;
  95. $cells = array();
  96. if(in_array($project->model, array('scrum', 'kanban', 'agileplus')))
  97. {
  98. foreach($config->block->projectstatistic->items as $module => $moduleItems)
  99. {
  100. $cellItems = array();
  101. foreach($moduleItems as $item)
  102. {
  103. $field = $item['field'];
  104. $unit = $item['unit'];
  105. $cellItems[] = item
  106. (
  107. set::name($lang->block->projectstatistic->{$field}),
  108. to::suffixName
  109. (
  110. isset($lang->block->tooltips[$field]) ? icon
  111. (
  112. setClass('text-light text-sm'),
  113. toggle::tooltip
  114. (
  115. array
  116. (
  117. 'title' => $lang->block->tooltips[$field],
  118. 'placement' => 'bottom',
  119. 'type' => 'white',
  120. 'className' => 'text-dark border border-light leading-5'
  121. )
  122. ),
  123. 'help'
  124. ) : null
  125. ),
  126. span
  127. (
  128. setClass('font-bold text-black mr-0.5'),
  129. round(zget($project, $field, 0), 2)
  130. ),
  131. span
  132. (
  133. setClass('text-gray'),
  134. $field == 'storyPoints' ? $config->block->storyUnitList[$config->custom->hourPoint] : zget($lang->block->projectstatistic, $unit, '')
  135. )
  136. );
  137. }
  138. $cells[] = cell
  139. (
  140. setClass('flex-1 overflow-hidden whitespace-nowrap project-statistic-table scrum bg-gray-50 border border-1 pt-2 px-1'),
  141. set::width($longBlock ? '25%' : 'calc(50% - 1rem)'),
  142. div
  143. (
  144. span
  145. (
  146. setClass('font-bold ml-3'),
  147. $lang->block->projectstatistic->{$module}
  148. )
  149. ),
  150. tableData
  151. (
  152. set::width('100%'),
  153. $cellItems
  154. )
  155. );
  156. }
  157. }
  158. else
  159. {
  160. $cells[] = cell
  161. (
  162. setClass('flex flex-wrap items-center progress-circle pt-2 mb-2'),
  163. set::width($longBlock ? '36%' : '100%'),
  164. div
  165. (
  166. setClass('flex justify-center w-full'),
  167. progressCircle
  168. (
  169. set::percent($project->progress),
  170. set::size(112),
  171. set::text(false),
  172. set::circleWidth(0.06),
  173. div(span(setClass('text-2xl font-bold'), $project->progress), '%'),
  174. div
  175. (
  176. setClass('row text-sm text-gray items-center gap-1'),
  177. $lang->block->projectstatistic->totalProgress,
  178. icon
  179. (
  180. setClass('pl-0.5 text-light text-sm'),
  181. toggle::tooltip
  182. (
  183. array
  184. (
  185. 'content' => array('html' => $lang->block->projectstatistic->totalProgressTip),
  186. 'placement' => 'bottom',
  187. 'type' => 'white',
  188. 'className' => 'text-dark border border-light leading-5'
  189. )
  190. ),
  191. 'help'
  192. )
  193. )
  194. )
  195. )
  196. );
  197. $cells[] = cell
  198. (
  199. setClass('project-statistic-table waterfall bg-gray-50 border border-1 pt-2 px-1' . ($isEn ? ' en-statistics' : '')),
  200. set::width($longBlock ? '32%' : 'calc(50% - 0.25rem)'),
  201. div
  202. (
  203. setClass('w-full'),
  204. span
  205. (
  206. setClass('font-bold ml-3'),
  207. $lang->project->progress
  208. )
  209. ),
  210. tableData
  211. (
  212. item
  213. (
  214. set::name($lang->block->projectstatistic->sv),
  215. to::suffixName(icon
  216. (
  217. setClass('text-light text-sm'),
  218. toggle::tooltip
  219. (
  220. array
  221. (
  222. 'title' => $lang->block->tooltips['sv'],
  223. 'placement' => 'bottom',
  224. 'type' => 'white',
  225. 'className' => 'text-dark border border-light leading-5'
  226. )
  227. ),
  228. 'help'
  229. )),
  230. span
  231. (
  232. setClass('font-bold text-black mr-1'),
  233. (!empty($project->sv) ? $project->sv : 0) . $lang->percent
  234. )
  235. ),
  236. item
  237. (
  238. set::name($lang->block->projectstatistic->pv),
  239. to::suffixName(icon
  240. (
  241. setClass('text-light text-sm'),
  242. toggle::tooltip
  243. (
  244. array
  245. (
  246. 'title' => array('html' => $lang->block->tooltips['pv']),
  247. 'placement' => 'bottom',
  248. 'type' => 'white',
  249. 'className' => 'text-dark border border-light leading-5'
  250. )
  251. ),
  252. 'help'
  253. )),
  254. span
  255. (
  256. setClass('font-bold text-black mr-1'),
  257. !empty($project->pv) ? $project->pv : 0
  258. )
  259. ),
  260. item
  261. (
  262. set::name($lang->block->projectstatistic->ev),
  263. to::suffixName(icon
  264. (
  265. setClass('text-light text-sm'),
  266. toggle::tooltip
  267. (
  268. array
  269. (
  270. 'content' => array('html' => $lang->block->tooltips['ev']),
  271. 'placement' => 'bottom',
  272. 'type' => 'white',
  273. 'className' => 'text-dark border border-light leading-5'
  274. )
  275. ),
  276. 'help'
  277. )),
  278. span
  279. (
  280. setClass('font-bold text-black mr-1'),
  281. !empty($project->ev) ? $project->ev : 0
  282. )
  283. )
  284. )
  285. );
  286. $cells[] = cell
  287. (
  288. setClass('project-statistic-table waterfall bg-gray-50 border border-1 pt-2 px-1' . ($isEn ? ' en-statistics' : '')),
  289. set::width($longBlock ? '32%' : 'calc(50% - 0.25rem)'),
  290. div
  291. (
  292. setClass('w-full'),
  293. span
  294. (
  295. setClass('font-bold ml-3'),
  296. $lang->block->projectstatistic->currentCost
  297. )
  298. ),
  299. tableData
  300. (
  301. item(set::name($lang->block->projectstatistic->cv), to::suffixName(icon
  302. (
  303. setClass('text-light text-sm'),
  304. toggle::tooltip
  305. (
  306. array
  307. (
  308. 'title' => $lang->block->tooltips['cv'],
  309. 'placement' => 'bottom',
  310. 'type' => 'white',
  311. 'className' => 'text-dark border border-light leading-5'
  312. )
  313. ),
  314. 'help'
  315. )), span
  316. (
  317. setClass('font-bold text-black mr-1'),
  318. (!empty($project->cv) ? $project->cv : 0) . $lang->percent
  319. )),
  320. item
  321. (
  322. set::name($lang->block->projectstatistic->ev),
  323. to::suffixName(icon
  324. (
  325. setClass('text-light text-sm'),
  326. toggle::tooltip
  327. (
  328. array
  329. (
  330. 'content' => array('html' => $lang->block->tooltips['ev']),
  331. 'placement' => 'bottom',
  332. 'type' => 'white',
  333. 'className' => 'text-dark border border-light leading-5'
  334. )
  335. ),
  336. 'help'
  337. )),
  338. span
  339. (
  340. setClass('font-bold text-black mr-1'),
  341. !empty($project->ev) ? $project->ev : 0
  342. )
  343. ),
  344. item
  345. (
  346. set::name($lang->block->projectstatistic->ac),
  347. to::suffixName(icon
  348. (
  349. setClass('text-light text-sm'),
  350. toggle::tooltip
  351. (
  352. array
  353. (
  354. 'content' => array('html' => $lang->block->tooltips['ac']),
  355. 'placement' => 'bottom',
  356. 'type' => 'white',
  357. 'className' => 'text-dark border border-light leading-5'
  358. )
  359. ),
  360. 'help'
  361. )),
  362. span
  363. (
  364. setClass('font-bold text-black mr-1'),
  365. !empty($project->ac) ? $project->ac : 0
  366. )
  367. )
  368. )
  369. );
  370. }
  371. }
  372. statisticBlock
  373. (
  374. to::titleSuffix
  375. (
  376. icon
  377. (
  378. setClass('text-light text-sm cursor-pointer'),
  379. toggle::tooltip
  380. (
  381. array
  382. (
  383. 'title' => sprintf($lang->block->tooltips['metricTime'], $metricTime),
  384. 'placement' => $app->getClientLang() == 'en' ? 'bottom-end' : 'bottom',
  385. 'type' => 'white',
  386. 'className' => 'text-dark border border-light leading-5'
  387. )
  388. ),
  389. 'help'
  390. )
  391. ),
  392. set::block($block),
  393. set::active($active),
  394. set::moreLink(createLink('project', 'browse', 'programID=0&browseType=' . zget($block->params, 'type', ''))),
  395. set::items($items),
  396. set::className('projectstatistic-block'),
  397. $project ? div
  398. (
  399. div
  400. (
  401. setClass('flex bg-white leading-6 px-2 py-1 mt-1 mx-3 items-center gap-x-2 gap-y-1 justify-between' . ($longBlock ? ' h-10 my-3 flex-nowrap' : ' h-14 mb-1 flex-wrap')),
  402. !empty($lastestExecution) || !$longBlock ? $lastestExecution : div(),
  403. div(setClass('flex justify-end gap-x-2 nowrap'), $projectOverview)
  404. ),
  405. div
  406. (
  407. setClass('flex gap-2 p-3 pt-1' . (!$longBlock ? ' flex-wrap gap-y-3' : ' pt-0')),
  408. $cells
  409. )
  410. ) : null
  411. );