design.html.php 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747
  1. <?php
  2. /**
  3. * The design file of approval 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 approval
  8. * @link https://www.zentao.net
  9. */
  10. namespace zin;
  11. $reviewTypeLang = $lang->approvalflow->reviewTypeList;
  12. $noticeTypeLang = $lang->approvalflow->noticeTypeList;
  13. $productRoles = $lang->approvalflow->productRoleList;
  14. $projectRoles = $lang->approvalflow->projectRoleList;
  15. $executionRoles = $lang->approvalflow->executionRoleList;
  16. $superiorList = $lang->approvalflow->superiorList;
  17. $userRange = $lang->approvalflow->userRangeList;
  18. if($node)
  19. {
  20. $node = json_decode($node);
  21. if(!empty($node->type) && $node->type != 'conditions')
  22. {
  23. $reviewerTypes = array();
  24. $ccTypes = array();
  25. $reviewerBox = array();
  26. $ccerBox = array();
  27. foreach($lang->approvalflow->reviewerTypeList as $type => $info)
  28. {
  29. if((!empty($node->nodeIndex) && $node->nodeIndex > 1) || $type != 'setByPrev') $reviewerTypes[$type] = $info['name'];
  30. if($type != 'self' && $type != 'setByPrev' && $type != 'productRole' && $type != 'projectRole' && $type != 'executionRole') $ccTypes[$type] = $info['name'];
  31. if(empty($info['options'])) continue;
  32. $multiple = $type != 'select' && $type != 'superiorList' ? true : false;
  33. $reviewerBox[] = picker(set::name($info['options']), set::required(true), setClass($type == 'select' ? '' : 'hidden'), set::multiple($multiple), set::items(${$info['options']}), setData(array('on' => 'change', 'call' => 'changeOption', 'params' => 'event', 'type' => $type)));
  34. $ccerBox[] = picker(set::name("cc{$info['options']}"), set::required(true), setClass($type == 'select' ? '' : 'hidden'), set::multiple($multiple), set::items(${$info['options']}), setData(array('on' => 'change', 'call' => 'changeOption', 'params' => 'event', 'type' => $type)));
  35. }
  36. foreach($lang->approvalflow->userRangeList as $range => $label)
  37. {
  38. if($range == 'all') continue;
  39. $rangeType = "{$range}s";
  40. $reviewerBox[] = picker(set::name("range{$range}"), setClass('hidden'), set::multiple(true), set::items(${$rangeType}), setData(array('type' => "range$range")));
  41. $ccerBox[] = picker(set::name("ccrange{$range}"), setClass('hidden'), set::multiple(true), set::items(${$rangeType}), setData(array('type' => "ccrange$range")));
  42. }
  43. $reviewerBox[] = picker(set::name('required'), set::required(true), set::items($lang->approvalflow->required), setData(array('type' => 'required')));
  44. if(!empty($node->reviewers))
  45. {
  46. foreach($node->reviewers as $index => $reviewer)
  47. {
  48. if(!empty($reviewer->type) && $reviewer->type == 'select')
  49. {
  50. $dd = new stdclass();
  51. foreach($reviewer as $key => $value)
  52. {
  53. $field = $key;
  54. if($key != 'type' && $key != 'userRange' && $key != 'required') $field = "range" . substr($key, 0, -1);
  55. $dd->{$field} = $value;
  56. }
  57. $node->reviewers[$index] = $dd;
  58. }
  59. }
  60. }
  61. if(!empty($node->ccs))
  62. {
  63. foreach($node->ccs as $index => $cc)
  64. {
  65. $before = 'cc';
  66. if(!empty($cc->type) && $cc->type == 'select') $before = 'ccrange';
  67. $dd = new stdclass();
  68. foreach($cc as $key => $value)
  69. {
  70. if($key == 'type') $field = 'ccType';
  71. if($key == 'userRange') $field = 'ccuserRange';
  72. if($key != 'type' && $key != 'userRange')
  73. {
  74. $field = $before . $key;
  75. if($cc->type == 'select') $field = substr($field, 0, -1);
  76. }
  77. $dd->{$field} = $value;
  78. }
  79. $node->ccs[$index] = $dd;
  80. }
  81. }
  82. }
  83. }
  84. $renderConditionText = function($conditions) use($users, $depts, $roles, $positions, $fields)
  85. {
  86. global $lang;
  87. $conditionTextLang = (array)$lang->approvalflow->conditionTypeList;
  88. $operatorList = (array)$lang->workflowcondition->operatorList;
  89. $conditionText = '';
  90. $conditionTitleText = '';
  91. $conditionNum = 0;
  92. foreach($conditions as $condition)
  93. {
  94. $conditionNum ++;
  95. if(!$condition->conditionValue) continue;
  96. if($condition->conditionField == 'submitUsers')
  97. {
  98. $userConditionText = '';
  99. $userName = zget($users, $condition->conditionValue, '');
  100. if($userName) $userConditionText .= $userName . ' ';
  101. if($conditionNum <= 2) $conditionText .= $conditionTextLang['submitUsers'] . $operatorList[$condition->conditionOperator] . trim($userConditionText, ' ') . '<br>';
  102. $conditionTitleText .= $conditionTextLang['submitUsers'] . $operatorList[$condition->conditionOperator] . trim($userConditionText, ' ');
  103. }
  104. elseif($condition->conditionField == 'submitDepts')
  105. {
  106. $deptConditionText = '';
  107. $deptName = zget($depts, $condition->conditionValue, '');
  108. if($deptName) $deptConditionText .= $deptName . '、';
  109. if($conditionNum <= 2) $conditionText .= $conditionTextLang['submitDepts'] . $operatorList[$condition->conditionOperator] . trim($deptConditionText, ' ') . '<br>';
  110. $conditionTitleText .= $conditionTextLang['submitDepts'] . $operatorList[$condition->conditionOperator] . trim($deptConditionText, ' ');
  111. }
  112. elseif($condition->conditionField == 'submitRoles')
  113. {
  114. $roleConditionText = '';
  115. $roleName = zget($roles, $condition->conditionValue, '');
  116. if($roleName) $roleConditionText .= $roleName . '、';;
  117. if($conditionNum <= 2) $conditionText .= $conditionTextLang['submitRoles'] . $operatorList[$condition->conditionOperator] . trim($roleConditionText, ' ') . '<br>';
  118. $conditionTitleText .= $conditionTextLang['submitRoles'] . $operatorList[$condition->conditionOperator] . trim($roleConditionText, ' ');
  119. }
  120. elseif($condition->conditionField == 'submitPositions')
  121. {
  122. $positionConditionText = '';
  123. $positionName = zget($positions, $condition->conditionValue, '');
  124. $positionConditionText .= $positionName . '、';
  125. if($conditionNum <= 2) $conditionText .= $conditionTextLang['submitPositions'] . $operatorList[$condition->conditionOperator] . trim($positionConditionText, ' ') . '<br>';
  126. $conditionTitleText .= $conditionTextLang['submitPositions'] . $operatorList[$condition->conditionOperator] . trim($positionConditionText, ' ');
  127. }
  128. elseif(isset($fields[$condition->conditionField]))
  129. {
  130. $field = $fields[$condition->conditionField];
  131. $text = '';
  132. $value = $field->options ? zget($field->options, $condition->conditionValue, '') : $condition->conditionValue;
  133. if($value) $text .= $value . '、';
  134. if($conditionNum <= 2) $conditionText .= $field->name . $operatorList[$condition->conditionOperator] . trim($text, ' ') . '<br>';
  135. $conditionTitleText .= $field->name . $operatorList[$condition->conditionOperator] . trim($text, ' ');
  136. }
  137. if($conditionNum == 3) $conditionText .= '...';
  138. $conditionTitleText .= '&#10;';
  139. }
  140. return array('text' => $conditionText, 'titleText' => trim($conditionTitleText, '&#10;'));
  141. };
  142. $renderNodes = function($nodes) use(&$renderNodes, &$renderConditionText)
  143. {
  144. global $lang;
  145. $editorNodes = array();
  146. $noticeTypeLang = $lang->approvalflow->noticeTypeList;
  147. $reviewerTypeLang = $lang->approvalflow->reviewerTypeList;
  148. $reviewTypeLang = $lang->approvalflow->reviewTypeList;
  149. $nodeTypeLang = $lang->approvalflow->nodeTypeList;
  150. foreach($nodes as $node)
  151. {
  152. if($node->type == 'branch')
  153. {
  154. $nodeType = $node->branchType == 'parallel' ? 'default' : 'other';
  155. $branchType = $node->branchType == 'parallel' ? 'addParallel' : 'addCondition';
  156. $noticeType = $node->branchType == 'condition' ? 'otherBranch' : 'defaultBranch';
  157. $branchesHTML = array();
  158. foreach($node->branches as $index => $branches)
  159. {
  160. $brancheNodes = $branches->nodes;
  161. $conditions = $branches->conditions;
  162. $conditionLabel = $renderConditionText($conditions);
  163. $branchesHTML[] = div
  164. (
  165. setData('id', $branches->id),
  166. setClass('editor-node branch'),
  167. div(setClass('top-line-mask')),
  168. div(setClass('top-v-line')),
  169. div
  170. (
  171. setClass('nodes'),
  172. div
  173. (
  174. setClass('editor-node condition'),
  175. div
  176. (
  177. setClass('editor-node-container'),
  178. div
  179. (
  180. setClass('node-title node-title-condition'),
  181. span(setClass('node-title-name'), $nodeTypeLang['condition'] . ' ' . ((int)$index + 1)),
  182. div
  183. (
  184. setClass('node-btns'),
  185. button
  186. (
  187. set::type('button'),
  188. setClass('delete-btn operate-icon'),
  189. setData(array('on' => 'click', 'call' => 'deleteBranch', 'params' => 'event')),
  190. span
  191. (
  192. setClass('universe-icon'),
  193. h::svg
  194. (
  195. set::width('1em'),
  196. set::height('1em'),
  197. set::viewBox('0 0 24 24'),
  198. set::fill('none'),
  199. set::xmlns('http://www.w3.org/2000/svg'),
  200. h::path(set::d('M12.0001 10.5858L19.7176 2.86825C19.9129 2.67299 20.2295 2.67299 20.4247 2.86825L21.1318 3.57536C21.3271 3.77062 21.3271 4.0872 21.1318 4.28246L13.4143 12L21.1318 19.7175C21.3271 19.9128 21.3271 20.2293 21.1318 20.4246L20.4247 21.1317C20.2295 21.327 19.9129 21.327 19.7176 21.1317L12.0001 13.4142L4.28258 21.1317C4.08732 21.327 3.77074 21.327 3.57548 21.1317L2.86837 20.4246C2.67311 20.2293 2.67311 19.9128 2.86837 19.7175L10.5859 12L2.86837 4.28246C2.67311 4.0872 2.67311 3.77062 2.86837 3.57536L3.57548 2.86825C3.77074 2.67299 4.08732 2.67299 4.28258 2.86825L12.0001 10.5858Z'), set::fill('currentColor'))
  201. )
  202. )
  203. )
  204. )
  205. ),
  206. div
  207. (
  208. setClass('node-content node-content-placeholder'),
  209. setData(array('on' => 'click', 'call' => 'clickConditionNode', 'params' => 'event', 'title' => $conditionLabel['titleText'])),
  210. set::title($conditionLabel['titleText']),
  211. div
  212. (
  213. setClass('node-detail-item'),
  214. div(setClass('text-ellipsis'), html($conditionLabel['text']))
  215. )
  216. ),
  217. icon('arrow', setClass('iconfont-approval-admin'))
  218. ),
  219. div(setClass('bottom-v-line')),
  220. div
  221. (
  222. setClass('add-node-btn'),
  223. setData(array('on' => 'click', 'call' => 'addNodeType', 'params' => 'event')),
  224. div
  225. (
  226. setClass('add-btn'),
  227. icon('plus', setClass('add-btn-icon iconfont-approval-admin'))
  228. )
  229. )
  230. ),
  231. $brancheNodes ? $renderNodes($brancheNodes) : null
  232. ),
  233. div(setClass('bottom-v-line')),
  234. div(setClass('bottom-line-mask'))
  235. );
  236. }
  237. $branchesHTML[] = div
  238. (
  239. setData('id', $node->default->id),
  240. setClass('editor-node branch'),
  241. div(setClass('top-line-mask')),
  242. div(setClass('top-v-line')),
  243. div
  244. (
  245. setClass('nodes'),
  246. div
  247. (
  248. setClass('editor-node condition'),
  249. div
  250. (
  251. setClass('editor-node-container'),
  252. setData('condition-id', 'CONDITION_648325_5857434'),
  253. setData('data-node-id', 'l10f2gm2-004'),
  254. div
  255. (
  256. setClass('node-title node-title-condition'),
  257. span(setClass('node-title-name'), $nodeTypeLang[$nodeType])
  258. ),
  259. div
  260. (
  261. setClass('node-content'),
  262. div
  263. (
  264. setClass('node-detail-item'),
  265. div($noticeTypeLang[$noticeType])
  266. )
  267. ),
  268. icon('arrow', setClass('iconfont-approval-admin'))
  269. ),
  270. div(setClass('bottom-v-line')),
  271. div
  272. (
  273. setClass('add-node-btn'),
  274. setData(array('on' => 'click', 'call' => 'addNodeType', 'params' => 'event')),
  275. div
  276. (
  277. setClass('add-btn'),
  278. icon('plus', setClass('add-btn-icon iconfont-approval-admin'))
  279. )
  280. )
  281. ),
  282. $renderNodes($node->default->nodes)
  283. ),
  284. div(setClass('bottom-v-line')),
  285. div(setClass('bottom-line-mask'))
  286. );
  287. $editorNodes[] = div
  288. (
  289. setData('id', $node->id),
  290. setClass('editor-node route'),
  291. div(setClass('top-h-line')),
  292. div
  293. (
  294. setClass('add-condition'),
  295. setData(array('on' => 'click', 'call' => 'addCondition', 'params' => 'event')),
  296. div
  297. (
  298. setClass('add-condition-inner'),
  299. $noticeTypeLang[$branchType],
  300. icon('arrow', setClass('iconfont-approval-admin'))
  301. )
  302. ),
  303. div
  304. (
  305. setClass('branches'),
  306. $branchesHTML
  307. ),
  308. div(setClass('bottom-h-line')),
  309. div(setClass('bottom-v-line')),
  310. div
  311. (
  312. setClass('add-node-btn'),
  313. setData(array('on' => 'click', 'call' => 'addNodeType', 'params' => 'event')),
  314. div
  315. (
  316. setClass('add-btn'),
  317. icon('plus', setClass('add-btn-icon iconfont-approval-admin'))
  318. )
  319. )
  320. );
  321. }
  322. else
  323. {
  324. $id = '';
  325. $title = '';
  326. $notice = '';
  327. switch($node->type)
  328. {
  329. case 'start':
  330. case 'end':
  331. $id = $node->type;
  332. $title = $noticeTypeLang['setCC'];
  333. $notice = $noticeTypeLang['setCC'];
  334. if(!empty($node->ccs[0]->type))
  335. {
  336. foreach($node->ccs as $cc) $notice = $reviewerTypeLang[$cc->type]['name'] . ' ';
  337. }
  338. break;
  339. case 'approval':
  340. $id = $node->id;
  341. $title = $noticeTypeLang['setReviewer'];
  342. if(empty($node->reviewType) || $node->reviewType == 'manual')
  343. {
  344. foreach($node->reviewers as $reviewer) $notice = $reviewerTypeLang[$reviewer->type]['name'] . ' ';
  345. }
  346. else
  347. {
  348. $notice = $reviewTypeLang[$node->reviewType];
  349. }
  350. break;
  351. case 'cc':
  352. $id = $node->id;
  353. $title = $noticeTypeLang['setCC'];
  354. foreach($node->ccs as $cc) $notice = $reviewerTypeLang[$cc->type]['name'] . ' ';
  355. break;
  356. }
  357. $editorNodes[] = div
  358. (
  359. setData('id', $id),
  360. setClass("editor-node {$node->type}"),
  361. div(setClass('editor-node-container'), div
  362. (
  363. setClass('node-title'),
  364. div
  365. (
  366. setClass('node-title-name text-ellipsis'),
  367. set::title(!empty($node->title) ? $node->title : $nodeTypeLang[$node->type]),
  368. !empty($node->title) ? $node->title : $nodeTypeLang[$node->type]
  369. )
  370. ), div
  371. (
  372. setClass('node-content'),
  373. setData(array('on' => 'click', 'call' => 'clickNode', 'params' => 'event')),
  374. set::title($title),
  375. div
  376. (
  377. setClass('node-detail'),
  378. div
  379. (
  380. setClass('node-detail-item'),
  381. $notice
  382. )
  383. )
  384. ), $node->type != 'start' && $node->type != 'end' ? icon('close', setClass('delete-btn iconfont-approval-admin'), setData(array('on' => 'click', 'call' => 'deleteNode', 'params' => 'event'))) : null),
  385. $node->type != 'end' ? div
  386. (
  387. div(setClass('bottom-v-line')),
  388. div
  389. (
  390. setClass('add-node-btn'),
  391. setData(array('on' => 'click', 'call' => 'addNodeType', 'params' => 'event')),
  392. div
  393. (
  394. setClass('add-btn'),
  395. icon('plus', setClass('add-btn-icon iconfont-approval-admin'))
  396. )
  397. )
  398. ) : null
  399. );
  400. }
  401. }
  402. return $editorNodes;
  403. };
  404. jsVar('nodeTypeLang', $lang->approvalflow->nodeTypeList);
  405. jsVar('warningLang', $lang->approvalflow->warningList);
  406. jsVar('link', inlink('design', "flowID={$flow->id}"));
  407. jsVar('workflow', $flow->workflow);
  408. $btnClass = isInModal() ? 'mr-4' : '';
  409. detailHeader
  410. (
  411. to::title
  412. (
  413. entityLabel
  414. (
  415. set::entityID($flow->id),
  416. set::level(1),
  417. set::text($flow->name)
  418. )
  419. ),
  420. to::suffix
  421. (
  422. btn
  423. (
  424. setClass("btn primary $btnClass"),
  425. set::icon('save'),
  426. setData(array('on' => 'click', 'call' => "$('#editorForm [type=submit]').trigger('click')")),
  427. $lang->save
  428. )
  429. )
  430. );
  431. div
  432. (
  433. formPanel
  434. (
  435. setID('editorForm'),
  436. set::ajax(array('beforeSubmit' => jsRaw('clickSubmit'))),
  437. set::size('full'),
  438. set::width('auto'),
  439. set::actionsClass('hidden'),
  440. div
  441. (
  442. setID('graph'),
  443. div
  444. (
  445. setID('editor'),
  446. setClass('editor-node branch'),
  447. setData(array('on' => 'click', 'call' => 'hideAddType', 'params' => 'event')),
  448. div
  449. (
  450. setID('root'),
  451. setClass('nodes')
  452. ),
  453. $renderNodes(json_decode($flow->nodes)),
  454. formHidden('nodes', $flow->nodes)
  455. )
  456. )
  457. ),
  458. modal
  459. (
  460. setID('modal'),
  461. set::title(!empty($node->type) && $node->type == 'conditions' ? $lang->approvalflow->noticeTypeList['setCondition'] : $lang->approvalflow->noticeTypeList['setNode']),
  462. !empty($node->type) ? formPanel
  463. (
  464. set::layout('grid'),
  465. set::actions(array('submit' => array('text' => $noticeTypeLang['confirm'], 'class' => 'primary', 'data-on' => 'click', 'data-call' => $node->type == 'conditions' ? 'saveCondition' : 'saveNode', 'data-params' => 'event', 'data-id' => isset($node->id) ? $node->id : $node->type))),
  466. $node->type == 'approval' || $node->type == 'cc' ? formGroup
  467. (
  468. set::label($noticeTypeLang["{$node->type}Title"]),
  469. set::width('full'),
  470. set::id('title'),
  471. set::name('title'),
  472. set::value(!empty($node->title) ? $node->title : $lang->approvalflow->nodeTypeList[$node->type])
  473. ) : null,
  474. $node->type == 'approval' ? formGroup
  475. (
  476. set::label($lang->approvalflow->type),
  477. set::width('full'),
  478. radioList(set::name('reviewType'), set::inline(true), set::items(array('manual' => $reviewTypeLang['manual'], 'pass' => $reviewTypeLang['pass'], 'reject' => $reviewTypeLang['reject'])), set::value(!empty($node->reviewType) ? $node->reviewType : 'manual'), setData(array('on' => 'change', 'call' => 'changeReviewType', 'params' => 'event')))
  479. ) : null,
  480. $node->type != 'conditions' ? formGroup
  481. (
  482. setID('reviewTypeBox'),
  483. set::width('full'),
  484. setClass(!empty($node->reviewType) && $node->reviewType == 'reject' ? 'hidden' : ''),
  485. tabs
  486. (
  487. set::navClass('flex-1'),
  488. set::titleClass('w-full'),
  489. $node->type == 'approval' ? tabPane
  490. (
  491. set::key('reviewer'),
  492. set::title($lang->approvalflow->reviewer),
  493. set::active(empty($node->reviewType) || $node->reviewType == 'manual'),
  494. set::hide(!empty($node->reviewType) && $node->reviewType != 'manual'),
  495. div
  496. (
  497. setClass('section-list', 'canvas', 'col', 'pt-4', 'pb-6'),
  498. formBatch
  499. (
  500. set::actions(''),
  501. set::actionsWidth('64px'),
  502. set::tagName('div'),
  503. set::mode('add'),
  504. set::minRows(1),
  505. set::onRenderRow(jsRaw('renderRowData')),
  506. !empty($node->reviewers) ? set::data(array_values($node->reviewers)) : null,
  507. formBatchItem
  508. (
  509. set::label($noticeTypeLang['reviewType']),
  510. set::name('type'),
  511. set::width('1/4'),
  512. set::control(array('control' => 'picker', 'required' => true, 'data-on' => 'change', 'data-call' => 'changeType', 'data-params' => 'event')),
  513. set::items($reviewerTypes)
  514. ),
  515. formBatchItem
  516. (
  517. set::label($noticeTypeLang['reviewRange']),
  518. set::name('approval'),
  519. set::control(array('control' => 'inputGroup')),
  520. inputGroup(setClass('gap-4'), $reviewerBox)
  521. )
  522. ),
  523. formGroup
  524. (
  525. set::label($lang->approvalflow->priv),
  526. set::width('full'),
  527. checkList(set::name('priv'), set::inline(true), set::items($lang->approvalflow->privList), set::value(!empty($node->priv) ? $node->priv : ''))
  528. )
  529. )
  530. ) : null,
  531. tabPane
  532. (
  533. set::key('ccer'),
  534. set::title($lang->approvalflow->ccer),
  535. set::active(!empty($node->reviewType) && $node->reviewType == 'pass'),
  536. div
  537. (
  538. setClass('section-list', 'canvas', 'col', 'pt-4', 'pb-6'),
  539. toolbar
  540. (
  541. btn
  542. (
  543. setClass('btn primary ghost hidden add-ccer-btn'),
  544. set::icon('plus'),
  545. set::text($lang->approvalflow->noticeTypeList['addCC'] ),
  546. set::size('md')
  547. )
  548. ),
  549. formBatch
  550. (
  551. setID('ccerForm'),
  552. set::actions(''),
  553. set::actionsWidth('64px'),
  554. set::tagName('div'),
  555. set::mode('add'),
  556. set::minRows(1),
  557. set::onRenderRow(jsRaw('renderRowData')),
  558. !empty($node->ccs) ? set::data(array_values($node->ccs)) : null,
  559. formBatchItem(set::label($noticeTypeLang['ccType']), set::name('ccType'), set::width('1/4'), set::control(array('control' => 'picker', 'required' => true, 'data-on' => 'change', 'data-call' => 'changeType', 'data-params' => 'event')), set::items($ccTypes)),
  560. formBatchItem
  561. (
  562. set::label($noticeTypeLang['ccRange']),
  563. set::name('approval'),
  564. set::control(array('control' => 'inputGroup')),
  565. inputGroup(setClass('gap-4'), $ccerBox)
  566. )
  567. )
  568. )
  569. ),
  570. $node->type == 'approval' ? tabPane
  571. (
  572. set::key('approvalflow'),
  573. set::title($lang->approvalflow->approval),
  574. set::hide(!empty($node->reviewType) && $node->reviewType != 'manual'),
  575. div(setClass('section-list', 'canvas', 'col', 'pt-4', 'pb-6'), $node->type == 'approval' ? formGroup
  576. (
  577. set::label($noticeTypeLang['multipleType']),
  578. set::width('full'),
  579. div
  580. (
  581. setClass('check-list'),
  582. checkbox(set::name('multiple'), set::type('radio'), set::text($noticeTypeLang['multipleAnd']), set::value('and'), set::checked(empty($node->multiple) || $node->multiple == 'and'), setData(array('on' => 'change', 'call' => 'changeMultiple', 'params' => 'event')), checkBox(set::name('needAll'), set::text($lang->approvalflow->needAll), set::value(1), set::checked(!empty($node->needAll) && !empty($node->multiple) && $node->multiple == 'and'), set::rootClass('mx-4', empty($node->multiple) || $node->multiple == 'and' ? '' : 'hidden'))),
  583. checkbox(set::name('multiple'), set::type('radio'), set::text($noticeTypeLang['multipleOr']), set::value('or'), set::checked(!empty($node->multiple) && $node->multiple == 'or'), setData(array('on' => 'change', 'call' => 'changeMultiple', 'params' => 'event')), checkBox(set::name('needAll'), set::text($lang->approvalflow->needAll), set::value(2), set::checked(!empty($node->needAll) && !empty($node->multiple) && $node->multiple == 'or'), set::rootClass('mx-4', !empty($node->multiple) && $node->multiple == 'or' ? '' : 'hidden'))),
  584. checkbox
  585. (
  586. set::rootClass('items-center h-5'),
  587. set::name('multiple'), set::type('radio'), set::text($noticeTypeLang['multiplePercent']), set::value('percent'), set::checked(!empty($node->multiple) && $node->multiple == 'percent'),
  588. setData(array('on' => 'change', 'call' => 'changeMultiple', 'params' => 'event')),
  589. div
  590. (
  591. setClass('input-control flex items-center has-suffix-sm w-28 mx-4', !empty($node->multiple) && $node->multiple == 'percent' ? '' : 'hidden'),
  592. cell(setClass('flex-1'), set::width('1/1'), $lang->approvalflow->percent),
  593. input(set::name('percent'), set::value(!empty($node->percent) ? $node->percent : '50'), setData(array('on' => 'change', 'call' => 'checkPercent', 'params' => 'event'))),
  594. span(setClass('input-control-suffix'), '%')
  595. ),
  596. checkBox(set::name('needAll'), set::text($lang->approvalflow->needAll), set::value(3), set::checked(!empty($node->needAll) && !empty($node->multiple) && $node->multiple == 'percent'), set::rootClass(!empty($node->multiple) && $node->multiple == 'percent' ? '' : 'hidden'))
  597. ),
  598. checkbox(set::name('multiple'), set::type('radio'), set::text($noticeTypeLang['multipleSolicit']), set::value('solicit'), set::checked(!empty($node->multiple) && $node->multiple == 'solicit'), setData(array('on' => 'change', 'call' => 'changeMultiple', 'params' => 'event')))
  599. )
  600. ) : null, $node->type == 'approval' ? formGroup
  601. (
  602. set::label($noticeTypeLang['commentType']),
  603. set::width('full'),
  604. radioList
  605. (
  606. set::name('commentType'),
  607. set::inline(true),
  608. set::items(array('noRequired' => $noticeTypeLang['noRequired'], 'required' => $noticeTypeLang['required'])),
  609. set::value(!empty($node->commentType) ? $node->commentType : 'noRequired')
  610. )
  611. ) : null, $node->type == 'approval' ? formGroup
  612. (
  613. set::label($noticeTypeLang['agentType']),
  614. set::width('full'),
  615. radioList(set::name('agentType'), set::inline(true), set::items(array('pass' => $noticeTypeLang['agentPass'], 'reject' => $noticeTypeLang['agentReject'], 'appointee' => $noticeTypeLang['agentUser'], 'admin' => $noticeTypeLang['agentAdmin'])), set::value(!empty($node->agentType) ? $node->agentType : 'pass'), setData(array('on' => 'change', 'call' => 'changeAgentType', 'params' => 'event'))),
  616. picker(set::name('agentUser'), set::items($users), set::value(!empty($node->agentUser) ? $node->agentUser : ''), setClass(!empty($node->agentType) && $node->agentType == 'appointee' ? '' : 'hidden'), set::width('200px'), set::required(true))
  617. ) : null, $node->type == 'approval' ? formGroup
  618. (
  619. set::label($noticeTypeLang['selfType']),
  620. set::width('full'),
  621. radioList
  622. (
  623. set::name('selfType'),
  624. set::inline(true),
  625. set::items(array('selfReview' => $noticeTypeLang['selfReview'], 'selfPass' => $noticeTypeLang['selfPass'], 'selfNext' => $noticeTypeLang['selfNext'], 'selfManager' => $noticeTypeLang['selfManager'])),
  626. set::value(!empty($node->selfType) ? $node->selfType : 'selfReview')
  627. )
  628. ) : null, $node->type == 'approval' ? formGroup
  629. (
  630. set::label($noticeTypeLang['deletedType']),
  631. set::width('full'),
  632. radioList(set::name('deletedType'), set::inline(true), set::items(array('autoPass' => $noticeTypeLang['autoPass'], 'autoReject' => $noticeTypeLang['autoReject'], 'setUser' => $noticeTypeLang['setUser'], 'setSuperior' => $noticeTypeLang['setSuperior'], 'setManager' => $noticeTypeLang['setManager'], 'setAdmin' => $noticeTypeLang['setAdmin'])), set::value(!empty($node->deletedType) ? $node->deletedType : 'setAdmin'), setData(array('on' => 'change', 'call' => 'changeDeletedType', 'params' => 'event'))),
  633. picker(set::name('setUser'), set::items($users), set::value(!empty($node->setUser) ? $node->setUser : ''), setClass(!empty($node->deletedType) && $node->deletedType == 'setUser' ? '' : 'hidden'), set::width('200px'), set::required(true))
  634. ) : null)
  635. ) : null
  636. )
  637. ) : null,
  638. $node->type == 'conditions' ? formBatch
  639. (
  640. set::actions(''),
  641. set::actionsWidth('64px'),
  642. set::tagName('div'),
  643. set::mode('add'),
  644. set::minRows(1),
  645. set::onRenderRow(jsRaw('renderConditionRowData')),
  646. !empty($node->conditions) ? set::data(array_values($node->conditions)) : null,
  647. formBatchItem
  648. (
  649. set::width('1/6'),
  650. set::name('conditionLogical'),
  651. set::control(array('control' => 'picker', 'required' => true)),
  652. set::items($lang->workflowcondition->logicalOperatorList),
  653. set::value('or')
  654. ),
  655. formBatchItem
  656. (
  657. set::width('1/2'),
  658. set::label($noticeTypeLang['when']),
  659. set::name('conditionField'),
  660. set::control(array('control' => 'picker', 'required' => true, 'data-on' => 'change', 'data-call' => 'changeConditionField', 'data-params' => 'event')),
  661. set::items($conditionFields)
  662. ),
  663. formBatchItem
  664. (
  665. set::width('1/6'),
  666. set::name('conditionOperator'),
  667. set::control(array('control' => 'picker', 'required' => true)),
  668. set::value('equal'),
  669. set::items($lang->workflowcondition->operatorList)
  670. ),
  671. formBatchItem
  672. (
  673. set::width('1/2'),
  674. set::label($noticeTypeLang['value']),
  675. set::name('conditionValue')
  676. )
  677. ) : null
  678. ) : div()
  679. ),
  680. div
  681. (
  682. setID('addNode'),
  683. setClass('hidden'),
  684. div
  685. (
  686. setClass('add-node-types'),
  687. div
  688. (
  689. setClass('node-type add-reviewer'),
  690. setData(array('on' => 'click', 'call' => 'addNode', 'params' => 'event', 'type' => 'reviewer')),
  691. icon('review', setClass('node-type-icon iconfont-approval-admin')),
  692. div(setClass('node-type-name'), $lang->approvalflow->reviewer)
  693. ),
  694. div
  695. (
  696. setClass('node-type add-cc'),
  697. setData(array('on' => 'click', 'call' => 'addNode', 'params' => 'event', 'type' => 'cc')),
  698. icon('send', setClass('node-type-icon iconfont-approval-admin')),
  699. div(setClass('node-type-name'), $lang->approvalflow->ccer)
  700. ),
  701. div
  702. (
  703. setClass('node-type add-branch type-condition'),
  704. setData(array('on' => 'click', 'call' => 'addNode', 'params' => 'event', 'type' => 'condition')),
  705. icon('treemap', setClass('node-type-icon iconfont-approval-admin')),
  706. div(setClass('node-type-name'), $lang->approvalflow->condition)
  707. ),
  708. div
  709. (
  710. setClass('node-type add-branch type-parallel'),
  711. setData(array('on' => 'click', 'call' => 'addNode', 'params' => 'event', 'type' => 'parallel')),
  712. icon('tree', setClass('node-type-icon iconfont-approval-admin')),
  713. div(setClass('node-type-name'), $lang->approvalflow->parallel)
  714. )
  715. )
  716. )
  717. );