edit.html.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  1. <?php
  2. /**
  3. * The edit file of story module 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 Yidong Wang<Yidong@easycorp.ltd>
  8. * @package story
  9. * @link http://www.zentao.net
  10. */
  11. namespace zin;
  12. $uid = uniqid();
  13. $canEditContent = strpos(',draft,changing,', ",{$story->status},") !== false;
  14. $forceReview = $this->story->checkForceReview();
  15. $assignedToList = $story->status == 'closed' ? $users + array('closed' => 'Closed') : $users;
  16. $planCount = !empty($story->planTitle) ? count($story->planTitle) : 0;
  17. $multiplePlan = ($this->session->currentProductType != 'normal' && empty($story->branch) && $planCount > 1);
  18. $minStage = $story->stage;
  19. $stageList = implode(',', array_keys($this->lang->story->stageList));
  20. $minStagePos = strpos($stageList, $minStage);
  21. if(!empty($story->stages) and $branchTagOption)
  22. {
  23. foreach($story->stages as $branch => $stage)
  24. {
  25. $position = strpos(",{$stageList},", ",{$stage},");
  26. if($position !== false and $position > $minStagePos)
  27. {
  28. $minStage = $stage;
  29. $minStagePos = $position;
  30. }
  31. }
  32. }
  33. jsVar('storyType', $story->type);
  34. jsVar('storyID', $story->id);
  35. jsVar('storyStatus', $story->status);
  36. jsVar('lastReviewer', explode(',', $lastReviewer));
  37. jsVar('storyReviewers', $storyReviewers);
  38. jsVar('reviewerNotEmpty', $lang->story->notice->reviewerNotEmpty);
  39. jsVar('oldProductID', $story->product);
  40. jsVar('twins', $story->twins);
  41. jsVar('relievedTwinsTip', $lang->story->relievedTwinsTip);
  42. jsVar('parentStory', !empty($story->children));
  43. jsVar('moveChildrenTips', $lang->story->moveChildrenTips);
  44. jsVar('executionID', isset($objectID) ? $objectID : 0);
  45. jsVar('langTreeManage', $lang->tree->manage);
  46. detailHeader
  47. (
  48. to::prefix($lang->story->edit),
  49. to::title
  50. (
  51. entityLabel
  52. (
  53. set::level(1),
  54. set::entityID($story->id),
  55. set::reverse(true),
  56. $story->title
  57. )
  58. )
  59. );
  60. detailBody
  61. (
  62. set::id('dataform'),
  63. set::isForm(true),
  64. set::ajax(array('beforeSubmit' => jsRaw('clickSubmit'))),
  65. $canEditContent ? set::actions(array
  66. (
  67. array('btnType' => 'submit', 'class' => 'primary', 'data-status' => 'active', 'text' => $lang->save),
  68. array('btnType' => 'submit', 'class' => 'secondary', 'data-status' => 'draft', 'text' => $story->status == 'changing' ? $lang->story->doNotSubmit : $lang->story->saveDraft),
  69. isInModal() ? null : array('text' => $lang->goback, 'back' => 'APP')
  70. )) : null,
  71. sectionList
  72. (
  73. section
  74. (
  75. set::title($lang->story->title),
  76. formGroup
  77. (
  78. set::name('title'),
  79. set::value($fields['title']['default']),
  80. set::disabled(!$canEditContent)
  81. )
  82. ),
  83. $canEditContent ? section
  84. (
  85. set::title($lang->story->reviewers),
  86. formGroup
  87. (
  88. row
  89. (
  90. setClass('reviewerRow'),
  91. span
  92. (
  93. setClass('reviewerBox'),
  94. setStyle('width', '100%'),
  95. picker
  96. (
  97. set::id('reviewer'),
  98. set::name('reviewer[]'),
  99. set::items($fields['reviewer']['options']),
  100. set::value($fields['reviewer']['default']),
  101. set::multiple(true),
  102. on::change('changeReviewer')
  103. )
  104. ),
  105. $forceReview ? null : checkbox
  106. (
  107. set::id('needNotReview'),
  108. set::name('needNotReview'),
  109. set::checked(empty($fields['reviewer']['default'])),
  110. set::value(1),
  111. set::text($lang->story->needNotReview),
  112. on::change('changeNeedNotReview(e.target)')
  113. )
  114. )
  115. )
  116. ) : null,
  117. section
  118. (
  119. set::title($lang->story->legendSpec),
  120. $canEditContent ? formGroup(editor(set::name('spec'), set::uid($uid), html($story->spec))) : set::content($story->spec),
  121. $canEditContent ? null : set::useHtml(true)
  122. ),
  123. empty($twins) ? null : section
  124. (
  125. set::title($lang->story->changeSyncTip),
  126. to::suffix(set::title($lang->story->syncTip), icon('help')),
  127. h::ul
  128. (
  129. array_values(array_map(function($twin) use($story, $branches, $lang)
  130. {
  131. $branch = isset($branches[$twin->branch]) ? $branches[$twin->branch] : '';
  132. $stage = $lang->story->stageList[$twin->stage];
  133. $labelClass = $story->branch == $twin->branch ? 'primary' : '';
  134. return h::li
  135. (
  136. setClass('twins'),
  137. $branch ? label(setClass($labelClass . ' circle branch size-sm'), set::title($branch), $branch) : null,
  138. label(setClass('circle size-sm'), $twin->id),
  139. common::hasPriv('story', 'view') ? a(set::href($this->createLink('story', 'view', "id={$twin->id}")), setClass('title'), set::title($twin->title), set('data-toggle', 'modal'), $twin->title) : span(setClass('title'), $twin->title),
  140. label(setClass('size-sm'), set::title($stage), $stage),
  141. common::hasPriv('story', 'relieved') ? a(set::title($lang->story->relievedTwins), setClass("relievedTwins unlink size-xs"), on::click('unlinkTwins'), set('data-id', $twin->id), icon('unlink')) : null
  142. );
  143. }, $twins))
  144. )
  145. ),
  146. $canEditContent || $story->files ? section
  147. (
  148. set::title($lang->story->legendAttach),
  149. $canEditContent ? fileSelector() : null,
  150. $story->files ? fileList
  151. (
  152. set::files($story->files),
  153. set::fieldset(false),
  154. set::object($story)
  155. ) : null
  156. ) : null,
  157. section
  158. (
  159. set::title($lang->story->comment),
  160. formGroup(editor(set::name('comment')))
  161. )
  162. ),
  163. history(),
  164. detailSide
  165. (
  166. set::isForm(true),
  167. tableData
  168. (
  169. set::title($lang->story->legendBasicInfo),
  170. item
  171. (
  172. set::name($lang->story->module),
  173. inputGroup
  174. (
  175. span
  176. (
  177. set('id', 'moduleIdBox'),
  178. picker
  179. (
  180. set::name('module'),
  181. set::items($fields['module']['options']),
  182. set::value($fields['module']['default'])
  183. )
  184. ),
  185. count($moduleOptionMenu) == 1 ? btn(set::url($this->createLink('tree', 'browse', "rootID={$story->product}&view=story&currentModuleID=0&branch={$story->branch}")), set('data-toggle', 'modal'), $lang->tree->manage) : null,
  186. count($moduleOptionMenu) == 1 ? btn(set('onclick', "loadProductModules({$story->product})"), setClass('refresh'), icon('refresh')) : null
  187. )
  188. ),
  189. $story->parent >= 0 && $story->type == 'story' ? item
  190. (
  191. set::trClass(zget($fields['parent'], 'className', '')),
  192. set::name($lang->story->parent),
  193. picker(setID('parent'), set::name('parent'), set::items($fields['parent']['options']), set::value($fields['parent']['default']))
  194. ) : null,
  195. item
  196. (
  197. set::name($lang->story->status),
  198. span(setClass("status-{$story->status}"), $this->processStatus('story', $story)),
  199. formHidden('status', $story->status)
  200. ),
  201. item
  202. (
  203. set::name($lang->story->pri),
  204. priPicker(set::name('pri'), set::items($fields['pri']['options']), set::value($fields['pri']['default']))
  205. ),
  206. item
  207. (
  208. set::name($lang->story->estimate),
  209. $story->parent >= 0 ? input(set::name('estimate'), set::value($story->estimate)) : $story->estimate
  210. ),
  211. item
  212. (
  213. set::trClass('feedbackBox'),
  214. set::trClass(in_array($story->source, $config->story->feedbackSource) ? '' : 'hidden'),
  215. set::name($lang->story->feedbackBy),
  216. input(set::name('feedbackBy'), set::value($story->feedbackBy))
  217. ),
  218. item
  219. (
  220. set::trClass('feedbackBox'),
  221. set::trClass(in_array($story->source, $config->story->feedbackSource) ? '' : 'hidden'),
  222. set::name($lang->story->notifyEmail),
  223. input(set::name('notifyEmail'), set::value($story->notifyEmail))
  224. ),
  225. item
  226. (
  227. set::name($lang->story->keywords),
  228. input(set::name('keywords'), set::value($story->keywords))
  229. ),
  230. item
  231. (
  232. set::name($lang->story->mailto),
  233. inputGroup
  234. (
  235. picker(setID('mailto'), set::name('mailto[]'), set::items($fields['mailto']['options']), set::value($fields['mailto']['default']), set::multiple(true)),
  236. isset($contactList) ? picker
  237. (
  238. setID('contactListMenu'),
  239. set::name('contactListMenu'),
  240. set::items($contactList),
  241. set::value()
  242. ) : btn
  243. (
  244. set('url', createLink('my', 'managecontacts', 'listID=0&mode=new')),
  245. set('title', $lang->user->contacts->manage),
  246. set('data-toggle', 'modal'),
  247. icon('cog')
  248. ),
  249. isset($contactList) ? null : btn
  250. (
  251. set('id', 'refreshMailto'),
  252. set('class', 'text-black'),
  253. icon('refresh')
  254. )
  255. )
  256. )
  257. ),
  258. tableData
  259. (
  260. set::title($lang->story->legendLifeTime),
  261. item
  262. (
  263. set::name($lang->story->openedBy),
  264. zget($users, $story->openedBy)
  265. ),
  266. item
  267. (
  268. set::name($lang->story->assignedTo),
  269. picker
  270. (
  271. setID('assignedTo'),
  272. set::name('assignedTo'),
  273. set::items($fields['assignedTo']['options']),
  274. set::value($fields['assignedTo']['default'])
  275. )
  276. ),
  277. $story->status == 'reviewing' ? item
  278. (
  279. set::name($lang->story->reviewers),
  280. picker
  281. (
  282. set::id('reviewer'),
  283. set::name('reviewer[]'),
  284. set::items($fields['reviewer']['options']),
  285. set::value($fields['reviewer']['default']),
  286. set::multiple(true),
  287. on::change('changeReviewer')
  288. )
  289. ) : null,
  290. $story->status == 'closed' ? item
  291. (
  292. set::name($lang->story->closedBy),
  293. picker(setID('closedBy'), set::name('closedBy'), set::items($fields['closedBy']['options']), set::value($fields['closedBy']['default']))
  294. ) : null,
  295. $story->status == 'closed' ? item
  296. (
  297. set::name($lang->story->closedReason),
  298. picker(setID('closedReason'), set::name('closedReason'), set::items($fields['closedReason']['options']), set::value($fields['closedReason']['default']), on::change('setStory'))
  299. ) : null
  300. )
  301. )
  302. );
  303. render();