view.html.php 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. <?php
  2. /**
  3. * The activate view file of task 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 Shujie Tian<tianshujie@easycorp.ltd>
  7. * @package task
  8. * @link https://www.zentao.net
  9. */
  10. namespace zin;
  11. include($this->app->getModuleRoot() . 'ai/ui/promptmenu.html.php');
  12. jsVar('delayWarning', $lang->task->delayWarning);
  13. jsVar('todayLabel', $lang->today);
  14. jsVar('yesterdayLabel', $lang->yesterday);
  15. $isInModal = isInModal();
  16. /* 初始化头部右上方工具栏。Init detail toolbar. */
  17. $toolbar = array();
  18. if(!$isInModal && hasPriv('task', 'create', $task))
  19. {
  20. $toolbar[] = array
  21. (
  22. 'icon' => 'plus',
  23. 'type' => 'primary',
  24. 'text' => $lang->task->create,
  25. 'url' => createLink('task', 'create', "executionID={$task->execution}"),
  26. 'data-app' => $app->tab == 'project' ? 'project' : ''
  27. );
  28. }
  29. /* 初始化底部操作栏。Init bottom actions. */
  30. $config->task->actionList['batchCreate']['hint'] = $config->task->actionList['batchCreate']['text'] = $lang->task->children;
  31. /* 检查是否需要确认撤销/移除。*/
  32. /* Build confirmeObject. */
  33. if($this->config->edition == 'ipd')
  34. {
  35. $execution->canStartExecution = $this->loadModel('execution')->checkStageStatus($execution->id, 'start');
  36. $task = $this->loadModel('story')->getAffectObject(array(), 'task', $task);
  37. if(!empty($task->confirmeActionType)) $config->task->actions->view['mainActions'] = array('confirmDemandRetract', 'confirmDemandUnlin');
  38. if(!empty($task->confirmeActionType)) $config->task->actions->view['suffixActions'] = array();
  39. }
  40. $task->executionInfo = $execution;
  41. $task->estimate = helper::formatHours($task->estimate);
  42. $task->consumed = helper::formatHours($task->consumed);
  43. $task->left = helper::formatHours($task->left);
  44. $actions = !$task->deleted && common::canModify('execution', $execution) ? $this->loadModel('common')->buildOperateMenu($task) : array();
  45. $hasDivider = !empty($actions['mainActions']) && !empty($actions['suffixActions']);
  46. if(!empty($actions)) $actions = array_merge($actions['mainActions'], $hasDivider ? array(array('type' => 'divider')) : array(), $actions['suffixActions']);
  47. foreach($actions as $key => $action)
  48. {
  49. if(isset($action['url']) && strpos($action['url'], 'createBranch') !== false && empty($hasGitRepo)) unset($actions[$key]);
  50. if(isset($action['url']) && strpos($action['url'], 'view') !== false && strpos($action['url'], 'review') === false && strpos($action['url'], 'delete') === false)
  51. {
  52. if($isInModal)
  53. {
  54. $actions[$key]['data-toggle'] = 'modal';
  55. $actions[$key]['data-size'] = 'lg';
  56. }
  57. if($task->parent == 0) unset($actions[$key]);
  58. }
  59. if($isInModal && isset($actions[$key]['data-load']))
  60. {
  61. unset($actions[$key]['data-load']);
  62. $actions[$key]['data-toggle'] = 'modal';
  63. }
  64. if($isInModal && isset($action['url']) && stripos($action['url'], 'batchCreate') !== false)
  65. {
  66. $actions[$key]['data-toggle'] = 'modal';
  67. $actions[$key]['data-size'] = 'lg';
  68. }
  69. if(isset($actions[$key]['url'])) $actions[$key]['url'] = str_replace(array('{rawStory}', '{module}', '{parent}', '{execution}'), array($task->story, $task->module, $task->parent, $task->execution), $action['url']);
  70. // 如果是删除按钮且是父任务,修改提示语
  71. if(isset($action['url']) && strpos($action['url'], 'delete') !== false && $task->isParent)
  72. {
  73. $actions[$key]['data-confirm'] = array('message' => $lang->task->confirmDeleteParent, 'icon' => 'icon-exclamation-sign', 'iconClass' => 'warning-pale rounded-full icon-2x');
  74. }
  75. if($isInModal && isset($action['icon']) && $action['icon'] == 'edit')
  76. {
  77. $actions[$key]['data-toggle'] = 'modal';
  78. $actions[$key]['data-size'] = 'lg';
  79. }
  80. }
  81. /* 初始化主栏内容。Init sections in main column. */
  82. $sections = array();
  83. $sections[] = setting()
  84. ->title($lang->task->legendDesc)
  85. ->control('html')
  86. ->content(empty($task->desc) ? $lang->noDesc : $task->desc);
  87. if($task->fromBug)
  88. {
  89. $sections[] = setting()
  90. ->title($lang->task->fromBug)
  91. ->control('detailCard')
  92. ->url(createLink('bug', 'view', "bugID=$fromBug->id"))
  93. ->object($fromBug)
  94. ->content(setting()->title($lang->bug->steps)->control('html')->content(empty($fromBug->steps) ? $lang->noData : $fromBug->steps));
  95. }
  96. if(!$task->fromBug && $task->story)
  97. {
  98. $disabledConirmStoryChange = false;
  99. $hintConirmStoryChange = '';
  100. if(empty($task->team) && !empty($task->assignedTo) && $task->assignedTo != $this->app->user->account)
  101. {
  102. $disabledConirmStoryChange = true;
  103. $hintConirmStoryChange = $lang->task->disabledHint->assignedConfirmStoryChange;
  104. }
  105. elseif(!empty($task->team))
  106. {
  107. $taskMembers = !empty($task->team) ? array_column($task->team, 'account') : array();
  108. $disabledConirmStoryChange = !in_array($this->app->user->account, $taskMembers);
  109. if($disabledConirmStoryChange) $hintConirmStoryChange = $lang->task->disabledHint->memberConfirmStoryChange;
  110. }
  111. $storyDetailProps = array
  112. (
  113. 'control' => 'detailCard',
  114. 'title' => $task->storyTitle,
  115. 'url' => createLink('story', 'view', "storyID=$task->storyID") . ($execution->multiple ? '' : '#app=project'),
  116. 'objectID' => $task->storyID,
  117. 'color' => '',
  118. 'deleted' => $task->storyDeleted,
  119. 'toolbar' => $task->needConfirm ? array
  120. (
  121. array('text' => $lang->task->storyChange, 'class' => 'ghost pointer-events-none'),
  122. array('text' => $lang->confirm, 'type' => 'primary', 'class' => 'ajax-submit', 'url' => createLink('task', 'confirmStoryChange', "taskID={$task->id}"), 'disabled' => $disabledConirmStoryChange, 'hint' => $hintConirmStoryChange)
  123. ) : null,
  124. 'sections' => array
  125. (
  126. setting()->title("[{$lang->story->legendSpec}]")->control('html')->content(empty($task->storySpec) && empty($task->storyFiles) ? $lang->noData : $task->storySpec),
  127. setting()->title("[{$lang->task->storyVerify}]")->control('html')->content(empty($task->storyVerify) ? $lang->noData : $task->storyVerify),
  128. setting()->title("[{$lang->task->storyFiles}]")->control('fileList')->files($task->storyFiles)->padding(false)->showEdit(false)->showDelete(false)
  129. )
  130. );
  131. $sections[] = setting()
  132. ->title($lang->task->story)
  133. ->control($storyDetailProps);
  134. }
  135. if(!empty($task->cases))
  136. {
  137. $sections[] = setting()
  138. ->title($lang->task->case)
  139. ->control('entityList')
  140. ->type('testcase')
  141. ->items($task->cases);
  142. }
  143. if($task->children)
  144. {
  145. foreach($task->children as $child)
  146. {
  147. $child->rawStory = $child->story;
  148. if($child->mode == 'multi' && strpos('done,closed', $child->status) === false)
  149. {
  150. $child->assignedTo = '';
  151. $taskTeam = $this->task->getTeamByTask($child->id);
  152. foreach($taskTeam as $teamMember)
  153. {
  154. if($this->app->user->account == $teamMember->account && $teamMember->status != 'done')
  155. {
  156. $child->assignedTo = $this->app->user->account;
  157. break;
  158. }
  159. }
  160. }
  161. }
  162. $children = initTableData($task->children, $config->task->dtable->children->fieldList, $this->task);
  163. $sections[] = setting()
  164. ->title($lang->task->children)
  165. ->control('dtable')
  166. ->className('ring')
  167. ->defaultNestedState(true)
  168. ->onRenderCell(jsRaw('window.renderCell'))
  169. ->cols(array_values($config->task->dtable->children->fieldList))
  170. ->userMap($users)
  171. ->data($children)
  172. ->checkable(false);
  173. }
  174. if($task->files)
  175. {
  176. $sections[] = array
  177. (
  178. 'control' => 'fileList',
  179. 'files' => $task->files,
  180. 'object' => $task,
  181. 'padding' => false,
  182. 'showEdit' => false,
  183. 'showDelete' => false
  184. );
  185. }
  186. /* 初始化侧边栏标签页。Init sidebar tabs. */
  187. $tabs = array();
  188. /* 基本信息。Legend basic items. */
  189. $tabs[] = setting()
  190. ->group('basic')
  191. ->title($lang->task->legendBasic)
  192. ->control('taskBasicInfo')
  193. ->statusText($this->processStatus('task', $task));
  194. /* 一生信息。Legend life items. */
  195. $tabs[] = setting()
  196. ->group('basic')
  197. ->title($lang->task->legendLife)
  198. ->control('taskLifeInfo');
  199. if($task->team)
  200. {
  201. $tabs[] = setting()
  202. ->group('basic')
  203. ->title($lang->task->team)
  204. ->control('taskTeam');
  205. }
  206. $tabs[] = setting()
  207. ->group('related')
  208. ->title($lang->task->legendEffort)
  209. ->control('taskEffortInfo');
  210. $tabs['taskMiscInfo'] = setting()
  211. ->group('related')
  212. ->title($lang->task->legendMisc)
  213. ->control('taskMiscInfo');
  214. detail
  215. (
  216. $task->parent > 0 ? array
  217. (
  218. set::parentTitle($task->parentName),
  219. set::parentUrl(createLink('task', 'view', "taskID={$task->parent}")),
  220. set::parentTitleProps(array('data-load' => 'modal')),
  221. to::title(to::leading(label(setClass('gray-pale rounded-full'), $lang->task->childrenAB)))
  222. ) : null,
  223. set::urlFormatter(array('{id}' => $task->id, '{parent}' => $task->parent, '{execution}' => $task->execution, '{confirmeObjectID}' => isset($task->confirmeObjectID) ? $task->confirmeObjectID : 0)),
  224. set::toolbar($toolbar),
  225. set::sections($sections),
  226. set::tabs($tabs),
  227. set::actions(array_values($actions))
  228. );