edittask.html.php 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541
  1. <?php
  2. /**
  3. * The edit view of task of ZenTaoPMS.
  4. *
  5. * @copyright Copyright 2009-2023 禅道软件(青岛)有限公司(ZenTao Software (Qingdao) Co., Ltd. www.zentao.net)
  6. * @license ZPL(https://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
  7. * @author zenggang<zenggang@easycorp.ltd>
  8. * @package task
  9. * @link https://www.zentao.net
  10. */
  11. namespace zin;
  12. include($this->app->getModuleRoot() . 'ai/ui/inputinject.html.php');
  13. /* ====== Preparing and processing page data ====== */
  14. jsVar('oldAssignedTo', $task->assignedTo);
  15. jsVar('oldExecutionID', $task->execution);
  16. jsVar('oldConsumed', $task->consumed);
  17. jsVar('taskStatus', $task->status);
  18. jsVar('currentUser', $app->user->account);
  19. jsVar('team', array_values($task->members));
  20. jsVar('members', $members);
  21. jsVar('page', 'edit');
  22. jsVar('confirmChangeExecution', $lang->task->confirmChangeExecution);
  23. jsVar('teamMemberError', $lang->task->error->teamMember);
  24. jsVar('totalLeftError', sprintf($this->lang->task->error->leftEmptyAB, $this->lang->task->statusList[$task->status]));
  25. jsVar('confirmRecord', $lang->task->confirmRecord);
  26. jsVar('estimateNotEmpty', sprintf($lang->error->gt, $lang->task->estimate, '0'));
  27. jsVar('leftNotEmpty', sprintf($lang->error->gt, $lang->task->left, '0'));
  28. jsVar('requiredFields', $config->task->edit->requiredFields);
  29. /* zin: Set variables to define picker options for form */
  30. $formTitle = $task->name;
  31. $executionOptions = $executions;
  32. $moduleOptions = $modules;
  33. $storyOptions = $stories;
  34. if($task->status == 'wait' and $task->parent == 0)
  35. {
  36. $modeOptions = $lang->task->editModeList;
  37. }
  38. else
  39. {
  40. $modeText = $task->mode == '' ? $lang->task->editModeList['single'] : zget($lang->task->editModeList, $task->mode);
  41. }
  42. $assignedToOptions = $taskMembers;
  43. $typeOptions = $lang->task->typeList;
  44. $statusOptions = (array)$lang->task->statusList;
  45. $priOptions = $lang->task->priList;
  46. $mailtoOptions = $users;
  47. $finishedByOptions = $members;
  48. $canceledByOptions = $users;
  49. $closedByOptions = $users;
  50. $closedReasonOptions = $lang->task->reasonList;
  51. $teamOptions = $members;
  52. $hiddenTeam = $task->mode != '' ? '' : 'hidden';
  53. if(!empty($task->team))
  54. {
  55. foreach($task->team as $member)
  56. {
  57. $member->team = $member->account;
  58. $member->teamSource = $member->account;
  59. $member->teamEstimate = (float)$member->estimate;
  60. $member->teamConsumed = (float)$member->consumed;
  61. $member->teamLeft = (float)$member->left;
  62. $member->memberDisabled = false;
  63. $member->memberStatus = $member->status;
  64. if($member->memberStatus == 'done') $member->memberDisabled = true;
  65. if(strpos('|closed|cancel|pause|', $task->status) !== false && $app->rawMethod != 'activate')
  66. {
  67. $member->memberStatus = $task->status;
  68. $member->memberDisabled = true;
  69. }
  70. $member->hourDisabled = $member->memberDisabled;
  71. }
  72. }
  73. /* ====== Define the page structure with zin widgets ====== */
  74. detailHeader
  75. (
  76. to::prefix(null),
  77. to::title
  78. (
  79. entityLabel
  80. (
  81. set::entityID($task->id),
  82. set::level(1),
  83. set::text($task->name),
  84. set::reverse(true)
  85. )
  86. )
  87. );
  88. detailBody
  89. (
  90. set::isForm(true),
  91. sectionList
  92. (
  93. section
  94. (
  95. set::title($lang->task->name),
  96. set::required(true),
  97. formGroup
  98. (
  99. inputControl
  100. (
  101. input(set::name('name'), set::value($task->name), set::placeholder($lang->task->name)),
  102. to::suffix
  103. (
  104. colorPicker
  105. (
  106. set::heading($lang->task->colorTag),
  107. set::name('color'),
  108. set::value($task->color),
  109. set::syncColor('#name')
  110. )
  111. ),
  112. set::suffixWidth('35')
  113. )
  114. )
  115. ),
  116. section
  117. (
  118. set::title($lang->task->desc),
  119. editor
  120. (
  121. set::name('desc'),
  122. $task->desc && isHTML($task->desc) ? html($task->desc) : $task->desc
  123. )
  124. ),
  125. section
  126. (
  127. set::title($lang->files),
  128. $task->files ? fileList
  129. (
  130. set::files($task->files),
  131. set::fieldset(false),
  132. set::showEdit(true),
  133. set::showDelete(true)
  134. ) : null,
  135. fileSelector()
  136. ),
  137. formHidden('lastEditedDate', helper::isZeroDate($task->lastEditedDate) ? '' : $task->lastEditedDate)
  138. ),
  139. history(),
  140. detailSide
  141. (
  142. set::isForm(true),
  143. tableData
  144. (
  145. setClass('mt-5'),
  146. set::title($lang->task->legendBasic),
  147. item
  148. (
  149. set::name($lang->marketresearch->execution),
  150. formGroup
  151. (
  152. picker
  153. (
  154. set::name('execution'),
  155. set::value($task->execution),
  156. set::items($executionOptions),
  157. on::change('loadAll')
  158. )
  159. )
  160. ),
  161. $task->parent >= 0 && empty($task->team) ? item
  162. (
  163. set::name($lang->task->parent),
  164. picker
  165. (
  166. set::name('parent'),
  167. set::value($task->parent),
  168. set::items($tasks)
  169. )
  170. ) : formHidden('parent', $task->parent),
  171. item
  172. (
  173. set::name($lang->task->assignedTo),
  174. inputGroup
  175. (
  176. div
  177. (
  178. setClass('flex grow'),
  179. picker
  180. (
  181. setID('assignedTo'),
  182. setClass('w-full'),
  183. set::name('assignedTo'),
  184. set::value($task->assignedTo),
  185. set::items($assignedToOptions),
  186. !empty($task->team) ? set::required(true) : null,
  187. !empty($task->team) && $task->mode == 'linear' && !in_array($task->status, array('done', 'closed')) ? set::disabled(true) : null
  188. )
  189. ),
  190. div
  191. (
  192. btn
  193. (
  194. $lang->task->team,
  195. setClass('input-group-btn team-group', empty($task->team) && (!$task->mode) ? 'hidden' : ''),
  196. set::url('#modalTeam'),
  197. setData('toggle', 'modal'),
  198. $task->mode == 'multi' ? on::click('disableMembers') : null
  199. )
  200. )
  201. )
  202. ),
  203. item
  204. (
  205. set::name($lang->task->type),
  206. picker
  207. (
  208. set::name('type'),
  209. set::value($task->type),
  210. set::items($typeOptions),
  211. set::required(true)
  212. )
  213. ),
  214. empty($task->children) ? item
  215. (
  216. set::name($lang->task->status),
  217. picker
  218. (
  219. set::name('status'),
  220. set::value($task->status),
  221. set::items($statusOptions),
  222. set::required(true)
  223. )
  224. ) : formHidden('status', $task->status),
  225. item
  226. (
  227. set::name($lang->task->pri),
  228. set::required(strpos(",{$this->config->task->edit->requiredFields},", ",pri,") !== false),
  229. formGroup
  230. (
  231. priPicker(set::name('pri'), set::value($task->pri), set::items($priOptions))
  232. )
  233. ),
  234. item
  235. (
  236. set::name($lang->task->progress),
  237. progresscircle
  238. (
  239. set::percent($task->progress),
  240. set::circleColor('var(--color-success-500)'),
  241. set::circleBg('var(--color-border)'),
  242. set::circleWidth(1)
  243. )
  244. ),
  245. item
  246. (
  247. set::name($lang->task->keywords),
  248. input(set::name('keywords'), set::value($task->keywords))
  249. ),
  250. item
  251. (
  252. set::name($lang->task->mailto),
  253. mailto(set::items($mailtoOptions), set::value($task->mailto))
  254. )
  255. ),
  256. modalTrigger
  257. (
  258. modal
  259. (
  260. setID('modalTeam'),
  261. set::title($lang->task->teamMember),
  262. formBatch
  263. (
  264. set::tagName('div'),
  265. setID('teamTable'),
  266. set::mode('add'),
  267. !empty($task->team) ? set::data(array_values($task->team)) : null,
  268. set::sortable(true),
  269. set::size('sm'),
  270. set::minRows(3),
  271. set::onRenderRow(jsRaw('renderRowData')),
  272. formBatchItem
  273. (
  274. set::name('id'),
  275. set::width('32px'),
  276. set::control('index')
  277. ),
  278. formBatchItem
  279. (
  280. set::name('team'),
  281. set::label($lang->task->teamMember),
  282. set::width('160px'),
  283. set::control('picker'),
  284. set::items($members)
  285. ),
  286. formBatchItem
  287. (
  288. set::name('estimateBox'),
  289. set::label($lang->task->estimateAB),
  290. set::width('135px'),
  291. set::control('inputGroup'),
  292. inputControl
  293. (
  294. input(set::name("teamEstimate")),
  295. to::suffix($lang->task->suffixHour),
  296. set::suffixWidth(20)
  297. )
  298. ),
  299. !empty($task->team) ? formBatchItem
  300. (
  301. set::name('consumedBox'),
  302. set::label($lang->task->consumedAB),
  303. set::width('135px'),
  304. set::control('inputGroup'),
  305. inputControl
  306. (
  307. input(set::name("teamConsumed")),
  308. to::suffix($lang->task->suffixHour),
  309. set::suffixWidth(20)
  310. )
  311. ) : null,
  312. !empty($task->team) ? formBatchItem
  313. (
  314. set::name('leftBox'),
  315. set::label($lang->task->left),
  316. set::width('135px'),
  317. set::control('inputGroup'),
  318. set::required(true),
  319. inputControl
  320. (
  321. input(set::name("teamLeft")),
  322. to::suffix($lang->task->suffixHour),
  323. set::suffixWidth(20)
  324. )
  325. ) : null,
  326. formBatchItem
  327. (
  328. set::name('teamSource'),
  329. set::control('input'),
  330. set::hidden(true)
  331. ),
  332. set::actions(array(array('text' => $lang->save, 'class' => 'primary team-saveBtn')))
  333. )
  334. )
  335. ),
  336. tableData
  337. (
  338. setClass('mt-4'),
  339. set::title($lang->task->legendEffort),
  340. item
  341. (
  342. set::name($lang->task->estStarted),
  343. set::required(strpos(",{$this->config->task->edit->requiredFields},", ",estStarted,") !== false),
  344. formGroup
  345. (
  346. datePicker
  347. (
  348. set::name('estStarted'),
  349. helper::isZeroDate($task->estStarted) ? null : set::value($task->estStarted)
  350. )
  351. )
  352. ),
  353. item
  354. (
  355. set::name($lang->task->deadline),
  356. set::required(strpos(",{$this->config->task->edit->requiredFields},", ",deadline,") !== false),
  357. formGroup
  358. (
  359. datePicker
  360. (
  361. set::name('deadline'),
  362. helper::isZeroDate($task->deadline) ? null : set::value($task->deadline)
  363. )
  364. )
  365. ),
  366. item
  367. (
  368. set::name($lang->task->estimate),
  369. set::required(strpos(",{$this->config->task->edit->requiredFields},", ",estimate,") !== false),
  370. formGroup
  371. (
  372. inputControl
  373. (
  374. input
  375. (
  376. set::name('estimate'),
  377. set::value($task->estimate),
  378. !empty($task->team) || !empty($task->children) ? set::readonly(true) : null
  379. ),
  380. to::suffix($lang->task->suffixHour),
  381. set::suffixWidth(20)
  382. )
  383. )
  384. ),
  385. item
  386. (
  387. set::name($lang->task->consumed),
  388. inputGroup
  389. (
  390. setClass('items-center'),
  391. span
  392. (
  393. setClass('span-text'),
  394. setID('consumedSpan'),
  395. $task->consumed . $lang->task->suffixHour
  396. ),
  397. common::hasPriv('task', 'recordWorkhour') ? btn
  398. (
  399. setClass('ghost text-primary', !empty($task->children) ? 'disabled' : true),
  400. icon('time'),
  401. set::href(inlink('recordWorkhour', "id={$task->id}&from=edittask")),
  402. setData('toggle', 'modal')
  403. ) : null,
  404. formHidden('consumed', $task->consumed)
  405. )
  406. ),
  407. item
  408. (
  409. set::name($lang->task->left),
  410. formGroup
  411. (
  412. inputControl
  413. (
  414. input
  415. (
  416. set::name('left'),
  417. set::value($task->left),
  418. !empty($task->team) || !empty($task->children) ? set::readonly(true) : null
  419. ),
  420. to::suffix($lang->task->suffixHour),
  421. set::suffixWidth(20)
  422. )
  423. )
  424. )
  425. ),
  426. tableData
  427. (
  428. setClass('mt-4'),
  429. set::title($lang->task->legendLife),
  430. item
  431. (
  432. set::name($lang->task->realStarted),
  433. formGroup
  434. (
  435. datetimePicker
  436. (
  437. set::name('realStarted'),
  438. set::value(helper::isZeroDate($task->realStarted) ? '' : $task->realStarted)
  439. )
  440. )
  441. ),
  442. item
  443. (
  444. set::name($lang->task->finishedBy),
  445. formGroup
  446. (
  447. picker
  448. (
  449. set::name('finishedBy'),
  450. set::value($task->finishedBy),
  451. set::items($finishedByOptions)
  452. )
  453. )
  454. ),
  455. item
  456. (
  457. set::name($lang->task->finishedDate),
  458. formGroup
  459. (
  460. datetimePicker
  461. (
  462. set::name('finishedDate'),
  463. set::value(helper::isZeroDate($task->finishedDate) ? '' : $task->finishedDate)
  464. )
  465. )
  466. ),
  467. item
  468. (
  469. set::name($lang->task->canceledBy),
  470. formGroup
  471. (
  472. picker
  473. (
  474. set::name('canceledBy'),
  475. set::value($task->canceledBy),
  476. set::items($canceledByOptions)
  477. )
  478. )
  479. ),
  480. item
  481. (
  482. set::name($lang->task->canceledDate),
  483. formGroup
  484. (
  485. datetimePicker
  486. (
  487. set::name('canceledDate'),
  488. set::value(helper::isZeroDate($task->canceledDate) ? '' : $task->canceledDate)
  489. )
  490. )
  491. ),
  492. item
  493. (
  494. set::name($lang->task->closedBy),
  495. formGroup
  496. (
  497. picker
  498. (
  499. set::name('closedBy'),
  500. set::value($task->closedBy),
  501. set::items($closedByOptions)
  502. )
  503. )
  504. ),
  505. item
  506. (
  507. set::name($lang->task->closedReason),
  508. formGroup
  509. (
  510. picker
  511. (
  512. set::name('closedReason'),
  513. set::value($task->closedReason),
  514. set::items($closedReasonOptions)
  515. )
  516. )
  517. ),
  518. item
  519. (
  520. set::name($lang->task->closedDate),
  521. formGroup
  522. (
  523. datetimePicker
  524. (
  525. set::name('closedDate'),
  526. set::value(helper::isZeroDate($task->closedDate) ? '' : $task->closedDate)
  527. )
  528. )
  529. )
  530. )
  531. )
  532. );