activate.ui.js 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. $(document).on('#left', 'input', setTeamUser);
  2. window.waitDom('.picker-box [name=assignedTo]', function()
  3. {
  4. if(taskMode == 'linear' || taskMode == 'multi')
  5. {
  6. $('#multiple').trigger('click');
  7. updateAssignedTo();
  8. computeTotalLeft();
  9. }
  10. });
  11. window.manageTeam = function()
  12. {
  13. const showTeam = $('#multiple').is(":checked");
  14. let $assignedToPicker = $('[name=assignedTo]').zui('picker');
  15. $assignedToPicker.$.setValue('');
  16. $assignedToPicker.render({items: teamItems, disabled: showTeam});
  17. $('.multi-append').empty();
  18. $('.member-done').find('input[name^=teamLeft]').val(0);
  19. $('#left').val('');
  20. if(showTeam)
  21. {
  22. $('#left').attr('readonly', true);
  23. $('.team-group').removeClass('hidden');
  24. }
  25. else
  26. {
  27. $('#left').removeAttr('readonly');
  28. $('.team-group').addClass('hidden');
  29. }
  30. if(taskMode == 'multi') disableMembers();
  31. }
  32. /**
  33. * 设置团队成员。
  34. * Set team members.
  35. *
  36. * @access public
  37. * @return void
  38. */
  39. function setTeamUser()
  40. {
  41. $('.multi-append').empty();
  42. const assignedTo = $('[name=assignedTo]').val();
  43. const estimate = parseInt($('#left').val());
  44. if(!assignedTo || !estimate) return;
  45. if(taskMode == 'multi')
  46. {
  47. $('.member-done').each(function()
  48. {
  49. if($(this).find('[name^team]').val() == assignedTo) $(this).find('input[name^=teamLeft]').val(estimate);
  50. });
  51. }
  52. else
  53. {
  54. let teamLine = '<input type="hidden" name="team[]" value="' + assignedTo + '">';
  55. teamLine += '<input type="hidden" name="teamSource[]" value="' + assignedTo + '">';
  56. teamLine += '<input type="hidden" name="teamEstimate[]" value="' + estimate + '">';
  57. teamLine += '<input type="hidden" name="teamConsumed[]" value="0">';
  58. teamLine += '<input type="hidden" name="teamLeft[]" value="' + estimate + '">';
  59. $('.multi-append').html(teamLine);
  60. }
  61. }
  62. /**
  63. * 检查团队成员数量。
  64. * Check the number of team members.
  65. *
  66. * @access public
  67. * @return void
  68. */
  69. $(document).off('click', '#confirmButton').on('click', '#confirmButton', function()
  70. {
  71. let memberCount = '';
  72. let totalEstimate = 0;
  73. let totalConsumed = oldConsumed;
  74. let totalLeft = 0;
  75. let error = false;
  76. $('.picker-box [name^=team]').each(function()
  77. {
  78. if($(this).val() == '') return;
  79. memberCount++;
  80. let $tr = $(this).closest('tr');
  81. let account = $tr.find('.picker-single-selection').text();
  82. let estimate = parseFloat($tr.find('[name^=teamEstimate]').val());
  83. if(!isNaN(estimate)) totalEstimate += estimate;
  84. if($tr.hasClass('member-wait') && (isNaN(estimate) || estimate <= 0))
  85. {
  86. zui.Modal.alert(account + ' ' + estimateNotEmpty);
  87. error = true;
  88. return false;
  89. }
  90. let consumed = parseFloat($tr.find('[name^=teamConsumed]').val());
  91. if(!isNaN(consumed)) totalConsumed += consumed;
  92. let $left = $tr.find('[name^=teamLeft]');
  93. let left = parseFloat($left.val());
  94. if(!isNaN(left)) totalLeft += left;
  95. if(!$left.prop('readonly') && $tr.hasClass('member-wait') && (isNaN(left) || left <= 0))
  96. {
  97. zui.Modal.alert(account + ' ' + leftNotEmpty);
  98. error = true;
  99. return false;
  100. }
  101. });
  102. if(error) return false;
  103. if(memberCount < 2)
  104. {
  105. zui.Modal.alert(teamMemberError);
  106. return false;
  107. }
  108. $('#left').val(totalLeft);
  109. updateAssignedTo();
  110. zui.Modal.hide();
  111. });
  112. /**
  113. * 更新指派人。
  114. * Update assignedTo.
  115. *
  116. * @access public
  117. * @return void
  118. */
  119. function updateAssignedTo()
  120. {
  121. const multiple = $('#multiple').is(":checked");
  122. let assignedTo = $('[name=assignedTo]').val();
  123. let $assignedToPicker = $('[name=assignedTo]').zui('picker');
  124. if(multiple)
  125. {
  126. let isTeamMember = false;
  127. let mode = $('#mode').val();
  128. let assignedToItems = new Array();
  129. let index = 0;
  130. $('.picker-box [name^=team]').each(function()
  131. {
  132. let $tr = $(this).closest('tr');
  133. let realName = $tr.find('.picker-single-selection').text();
  134. if(realName == '') return;
  135. let account = $(this).val();
  136. assignedToItems[index] = {'value': account, 'text': realName};
  137. index ++;
  138. });
  139. if(multiple && mode == 'linear' && $('#modalTeam tr.member-doing').length == 0 && $('#modalTeam tr.member-wait').length >= 1)
  140. {
  141. index --;
  142. assignedTo = assignedToItems.includes(index) ? assignedToItems[index].value : '';
  143. }
  144. $assignedToPicker.render({items: assignedToItems, disabled: true});
  145. }
  146. else
  147. {
  148. $assignedToPicker.render({items: memberItems});
  149. }
  150. $assignedToPicker.$.setValue(assignedTo);
  151. }
  152. function computeTotalLeft()
  153. {
  154. let totalLeft = 0;
  155. $('tr.member').each(function()
  156. {
  157. let $leftBox = $(this).find('[name^=teamLeft]');
  158. let left = parseFloat($leftBox.val());
  159. if(!isNaN(left)) totalLeft += left;
  160. });
  161. $('#left').val(totalLeft);
  162. }
  163. $('#teamTable').on('change', '.picker-box [name^=team]', function()
  164. {
  165. disableMembers();
  166. let $teamSource = $(this).siblings('[name^=teamSource]');
  167. if($teamSource.val() == '') return;
  168. let $tr = $(this).closest('tr');
  169. let consumed = 0;
  170. let estimate = $tr.attr('data-left');;
  171. if($(this).val() == $teamSource.val())
  172. {
  173. consumed = $tr.attr('data-consumed');
  174. estimate = $tr.attr('data-estimate');
  175. }
  176. $tr.find('[name^=teamConsumed]').val(consumed);
  177. $tr.find('[name^=teamEstimate]').val(estimate);
  178. });
  179. window.clickSubmit = function()
  180. {
  181. if(isMultiple)
  182. {
  183. var multiple = $('#multiple').is(":checked");
  184. if(!multiple)
  185. {
  186. var assignedTo = $('[name=assignedTo]').val();
  187. if(!assignedTo)
  188. {
  189. zui.Modal.alert(teamNotEmpty);
  190. return false;
  191. }
  192. }
  193. var estimate = parseFloat($('#left').val());
  194. if(isNaN(estimate) || estimate <= 0)
  195. {
  196. zui.Modal.alert(multiple ? teamLeftEmpty : leftNotEmpty);
  197. return false;
  198. }
  199. $('#assignedTo').val('');
  200. }
  201. }
  202. window.renderRowData = function($row, index, row)
  203. {
  204. $row.addClass('member member-' + (row ? row.status : 'wait'));
  205. $row.attr('data-estimate', row ? row.teamEstimate : 0);
  206. $row.attr('data-consumed', row ? row.teamConsumed : 0);
  207. $row.attr('data-left', row ? row.teamLeft : 0);
  208. if(row && row.memberDisabled)
  209. {
  210. $row.find('[data-name=team]').find('.picker-box').on('inited', function(e, info)
  211. {
  212. const $team = info[0];
  213. $team.render({disabled: true});
  214. })
  215. $row.find('[data-name=ACTIONS]').find('[data-type=delete]').remove();
  216. }
  217. if(row && row.hourDisabled)
  218. {
  219. $row.find('[name^=teamEstimate]').attr('readonly', 'readonly');
  220. $row.find('[name^=teamLeft]').attr('readonly', 'readonly');
  221. }
  222. $row.find('[name^=teamConsumed]').attr('readonly', 'readonly');
  223. $row.find('[data-name=id]').addClass('center').html("<span class='team-number'>" + $row.find('[data-name=id]').text() + "</span><i class='icon-angle-down " + (taskMode == 'linear' ? '' : 'hidden') + "'><i/>");
  224. }