browse.ui.js 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. window.renderCell = function(result, {col, row})
  2. {
  3. if(col.name === 'name')
  4. {
  5. if(typeof result[0].props == 'object') result[0].props.className = 'clip w-max';
  6. if(row.data.postponed) result[result.length] = {html:'<span class="label size-sm circle danger-pale w-max">' + row.data.delayInfo + '</span>'};
  7. if(row.data.type == 'program' && !isAdmin && !privPrograms.includes(row.data.id.toString())) result[0].type = 'span';
  8. return result;
  9. }
  10. if(col.name === 'budget')
  11. {
  12. let budgetHtml = `<div>${row.data.budget}</div>`;
  13. if(typeof(row.data.exceedBudget) != 'undefined')
  14. {
  15. let iconSign = ' <span class="icon icon-exclamation text-danger"></span>';
  16. let menu = '<menu class="dropdown-menu custom">';
  17. let dropMenu = menu;
  18. dropMenu += '<div class="mb-1"><span class="text-gray">' + projectBudgetLang + ': </span><span class="font-bold">' + row.data.rawBudget + '</span></div>';
  19. dropMenu += '<div class="mb-1"><span class="text-gray">' + remainingBudgetLang + ': </span><span class="font-bold">' + row.data.remainingBudget + '</span></div>';
  20. dropMenu += '<div class="text-danger">' + exceededBudgetLang + ': <span class="font-bold">' + row.data.exceedBudget + '</span></div>';
  21. if(row.data.type == 'program')
  22. {
  23. if(row.data.parent == 0) iconSign = ' <span class="icon icon-exclamation-sign text-danger"></span>';
  24. dropMenu = menu;
  25. dropMenu += '<div class="mb-1"><span class="text-gray">' + programBudgetLang + ': </span><span class="font-bold">' + row.data.rawBudget + '</span></div>';
  26. dropMenu += '<div class="mb-1"><span class="text-gray">' + sumSubBudgetLang + ': </span><span class="font-bold">' + row.data.subBudget + '</span></div>';
  27. dropMenu += '<div class="text-danger">' + exceededBudgetLang + ': <span class="font-bold">' + row.data.exceedBudget + '</span></div>';
  28. }
  29. iconSign = '<span data-toggle="dropdown" data-trigger="hover" data-placement="right-start">' + iconSign + '</span>';
  30. budgetHtml = `<div>${row.data.budget}${iconSign}${dropMenu}</div>`
  31. }
  32. result[0] = {html: budgetHtml, className:'flex w-full items-end mr-1', style:{flexDirection:"column"}};
  33. return result;
  34. }
  35. if(col.name === 'invested')
  36. {
  37. result[0] = {html: '<div>' + row.data.invested + ' <small class="text-gray">' + langManDay + '</small></div>', className:'flex w-full items-end', style:{flexDirection:"column"}};
  38. return result;
  39. }
  40. return result;
  41. }
  42. window.confirmDelete = function(projectID, module, projectName)
  43. {
  44. let deleteURL = $.createLink(module, 'delete', "projectID=" + projectID);
  45. if(module == 'program')
  46. {
  47. $.ajaxSubmit(
  48. {
  49. url: deleteURL,
  50. onComplete: function(result)
  51. {
  52. if(result.result == 'success') loadCurrentPage();
  53. }
  54. });
  55. }
  56. else
  57. {
  58. zui.Modal.confirm({message: confirmDeleteLang[module].replace('%s', projectName), icon:'icon-exclamation-sign', iconClass: 'warning-pale rounded-full icon-2x'}).then((res) =>
  59. {
  60. if(res) $.ajaxSubmit({url: deleteURL, load: true});
  61. });
  62. }
  63. }
  64. $(document).off('click', '[data-formaction]').on('click', '[data-formaction]', function()
  65. {
  66. const $this = $(this);
  67. const dtable = zui.DTable.query($('#projectviews'));
  68. const checkedList = dtable.$.getChecks();
  69. if(!checkedList.length) return;
  70. const postData = new FormData();
  71. checkedList.forEach(function(id)
  72. {
  73. let data = dtable.$.getRowInfo(id).data;
  74. if(data.type == 'program') return;
  75. postData.append('projectIdList[]', id);
  76. });
  77. if($this.data('page') == 'batch') postAndLoadPage($this.data('formaction'), postData);
  78. });
  79. window.footerSummary = function(element, checkedIdList)
  80. {
  81. if(typeof(checkedIdList) == 'undefined') return {};
  82. if(typeof checkedIdList == 'string') return {html: checkedIdList, className: 'text-dark'};
  83. if(!checkedIdList || checkedIdList.length == 0) return {html: element.options.customData.pageSummary, className: 'text-dark'};
  84. const dtable = zui.DTable.query($('#projectviews'));
  85. let totalProjects = 0;
  86. checkedIdList.forEach(function(id)
  87. {
  88. if(dtable)
  89. {
  90. let data = dtable.$.getRowInfo(id).data;
  91. if(data.type == 'program') return;
  92. }
  93. totalProjects++;
  94. });
  95. var summary = element.options.customData.checkedSummary.replace('%s', totalProjects);
  96. return {html: summary};
  97. };
  98. /**
  99. * 拖拽的项目集或者项目是否允许放下。
  100. * Is it allowed to drop the dragged program or project.
  101. *
  102. * @param from 被拿起的元素
  103. * @param to 放下时的目标元素
  104. * @access public
  105. * @return bool
  106. */
  107. window.canSortTo = function(from, to)
  108. {
  109. if(!from || !to) return false;
  110. if(from.data.parent != to.data.parent) return false;
  111. return true;
  112. };
  113. /**
  114. * 拖拽项目集或项目。
  115. * Drag program or project.
  116. *
  117. * @param from 被拿起的元素 * @param to 放下时的目标元素
  118. * @param type 放在目标元素的上方还是下方
  119. * @access public
  120. * @return bool
  121. */
  122. window.onSortEnd = function(from, to, type)
  123. {
  124. if(!from || !to) return false;
  125. if(!canSortTo(from, to)) return false;
  126. const url = $.createLink('program', 'updateOrder');
  127. const form = new FormData();
  128. form.append('programIdList', JSON.stringify(this.state.rowOrders));
  129. $.ajaxSubmit({url, data:form});
  130. return true;
  131. };