暫無描述

comments.js 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. var g_comment_desc_editor = null;
  2. function comment_element(element_id, element_type, is_alert=false) {
  3. const prefix = is_alert ? '/alerts' : `/case/${element_type}`;
  4. const url = `${prefix}/${element_id}/comments/modal`;
  5. $('#modal_comment_content').load(url + case_param(),
  6. function (response, status, xhr) {
  7. if (status !== "success") {
  8. ajax_notify_error(xhr, url);
  9. return false;
  10. }
  11. $('#modal_comment_content').resizable({
  12. minHeight: 300,
  13. minWidth: 300,
  14. handles: "n, e, s, w, ne, se, sw, nw"
  15. });
  16. $('.modal-comment').draggable({
  17. cursor: 'move'
  18. });
  19. $('#modal_comment').modal('show');
  20. g_comment_desc_editor = get_new_ace_editor('comment_message', 'comment_content', 'target_comment_content',
  21. function() {
  22. $('#last_saved').addClass('btn-danger').removeClass('btn-success');
  23. $('#last_saved > i').attr('class', "fa-solid fa-file-circle-exclamation");
  24. }, null, false, false);
  25. headers = get_editor_headers('g_comment_desc_editor', null, 'comment_edition_btn');
  26. $('#comment_edition_btn').append(headers);
  27. load_comments(element_id, element_type, undefined, undefined, is_alert);
  28. }
  29. );
  30. }
  31. function preview_comment() {
  32. if(!$('#container_comment_preview').is(':visible')) {
  33. let comment_text = g_comment_desc_editor.getValue();
  34. let converter = get_showdown_convert();
  35. let html = converter.makeHtml(comment_text);
  36. let comment_html = do_md_filter_xss(html);
  37. $('#target_comment_content').html(comment_html);
  38. $('#container_comment_preview').show();
  39. $('#comment_preview_button').html('<i class="fa-solid fa-eye-slash"></i> Edit');
  40. $('#container_comment_content').hide();
  41. }
  42. else {
  43. $('#container_comment_preview').hide();
  44. $('#comment_preview_button').html('<i class="fa-solid fa-eye"></i> Preview');
  45. $('#container_comment_content').show();
  46. }
  47. }
  48. function save_comment(element_id, element_type) {
  49. data = Object();
  50. data['comment_text'] = g_comment_desc_editor.getValue();
  51. data['csrf_token'] = $('#csrf_token').val();
  52. const is_alert = element_type === 'alerts';
  53. const prefix = is_alert ? '/alerts' : `/case/${element_type}`;
  54. post_request_api(`${prefix}/${element_id}/comments/add`, JSON.stringify(data), true)
  55. .done((data) => {
  56. if(notify_auto_api(data)) {
  57. load_comments(element_id, element_type, undefined, undefined, is_alert);
  58. g_comment_desc_editor.setValue('');
  59. increase_modal_comments_count(element_type, element_id);
  60. }
  61. });
  62. }
  63. function decrease_modal_comments_count(element_type, element_id) {
  64. let tid = '#object_comments_number';
  65. if (element_type === 'timeline/events' || element_type === 'alerts') {
  66. tid = '#object_comments_number_' + element_id;
  67. }
  68. let curr_count = $(tid).text();
  69. if (curr_count > 0) {
  70. $(tid).text(curr_count - 1);
  71. if (element_type === 'timeline/events' || element_type === 'alerts') {
  72. $('#object_comments_number').text(parseInt(curr_count) - 1);
  73. }
  74. }
  75. }
  76. function increase_modal_comments_count(element_type, element_id) {
  77. let tid = '#object_comments_number';
  78. if (element_type === 'timeline/events' || element_type === 'alerts') {
  79. tid = '#object_comments_number_' + element_id;
  80. }
  81. let curr_count = $(tid).text();
  82. if (curr_count === '') {
  83. curr_count = 0;
  84. }
  85. $(tid).text(parseInt(curr_count) + 1);
  86. if (element_type === 'timeline/events' || element_type === 'alerts') {
  87. $('#object_comments_number').text(parseInt(curr_count) + 1);
  88. }
  89. }
  90. function delete_comment(comment_id, element_id, element_type) {
  91. do_deletion_prompt("You are about to delete comment #" + comment_id)
  92. .then((doDelete) => {
  93. if (doDelete) {
  94. data = Object();
  95. data['csrf_token'] = $('#csrf_token').val();
  96. const is_alert = element_type === 'alerts';
  97. const prefix = is_alert ? '/alerts' : `/case/${element_type}`;
  98. post_request_api(`${prefix}/${element_id}/comments/${comment_id}/delete`, JSON.stringify(data))
  99. .done((data) => {
  100. if(notify_auto_api(data)) {
  101. load_comments(element_id, element_type, undefined, undefined, is_alert);
  102. decrease_modal_comments_count(element_type, element_id);
  103. }
  104. });
  105. }
  106. });
  107. }
  108. function edit_comment(comment_id, element_id, element_type) {
  109. const is_alert = element_type === 'alerts';
  110. const prefix = is_alert ? '/alerts' : `/case/${element_type}`;
  111. get_request_api(`${prefix}/${element_id}/comments/${comment_id}`)
  112. .done((data) => {
  113. if (api_request_failed(data)) {
  114. return;
  115. }
  116. $('#comment_'+comment_id).addClass('comment_editing');
  117. $('#comment_'+comment_id).data('comment_id', comment_id);
  118. g_comment_desc_editor.setValue(data.data.comment_text);
  119. $('#comment_edition').show();
  120. $('#comment_submit').hide();
  121. $('#cancel_edition').show();
  122. });
  123. }
  124. function save_edit_comment(element_id, element_type) {
  125. data = Object();
  126. data['comment_text'] = g_comment_desc_editor.getValue();
  127. comment_id = $('.comment_editing').data('comment_id');
  128. data['csrf_token'] = $('#csrf_token').val();
  129. const is_alert = element_type === 'alerts';
  130. const prefix = is_alert ? '/alerts' : `/case/${element_type}`;
  131. post_request_api(`${prefix}/${element_id}/comments/${comment_id}/edit`, JSON.stringify(data), true)
  132. .done((data) => {
  133. if(notify_auto_api(data)) {
  134. cancel_edition(comment_id);
  135. load_comments(element_id, element_type, comment_id, undefined, is_alert);
  136. }
  137. });
  138. }
  139. function cancel_edition(comment_id) {
  140. $('.comment_editing').css('background-color', '');
  141. $('.comment_editing').css('border-radius', '');
  142. $('.comment_editing').removeClass('comment_editing');
  143. $('.comment_editing').data('comment_id', '');
  144. $('#comment_edition').hide();
  145. $('#cancel_edition').hide();
  146. $('#comment_submit').show();
  147. g_comment_desc_editor.setValue('');
  148. }
  149. function load_comments(element_id, element_type, comment_id, do_notification, is_alert=false) {
  150. if (do_notification !== undefined) {
  151. silent_success = !do_notification;
  152. } else {
  153. silent_success = true;
  154. }
  155. const prefix = is_alert || element_type === 'alerts' ? '/alerts' : `/case/${element_type}`;
  156. get_request_api(`${prefix}/${element_id}/comments/list`)
  157. .done((data) => {
  158. if (api_request_failed(data)) {
  159. return;
  160. }
  161. if (!silent_success) {
  162. notify_api_request_success(data)
  163. }
  164. $('#comments_list').empty();
  165. var names = Object;
  166. for (var i = 0; i < data['data'].length; i++) {
  167. comment_text = data['data'][i].comment_text;
  168. converter = get_showdown_convert();
  169. html = converter.makeHtml(do_md_filter_xss(comment_text));
  170. comment_html = do_md_filter_xss(html);
  171. const username = data['data'][i].user.user_name;
  172. if (names.hasOwnProperty(username)) {
  173. avatar = names[username];
  174. } else {
  175. avatar = get_avatar_initials(username);
  176. names[username] = avatar;
  177. }
  178. can_edit = "";
  179. current_user = $('#current_username').text();
  180. if (current_user === data['data'][i].user.user_login) {
  181. can_edit = '<a href="#" class="btn btn-sm comment-edition-hidden" title="Edit comment" onclick="edit_comment(\'' + data['data'][i].comment_id + '\', \'' + element_id + '\',\''+ element_type +'\'); return false;"><i class="fa-solid fa-edit text-dark"></i></a>';
  182. can_edit += '<a href="#" class="btn btn-sm comment-edition-hidden" title="Delete comment" onclick="delete_comment(\'' + data['data'][i].comment_id + '\', \'' + element_id + '\',\''+ element_type +'\'); return false;"><i class="fa-solid fa-trash text-dark"></i></a>';
  183. }
  184. comment = `
  185. <div class="row mb-2 mr-1" >
  186. <div class="col-12" id="comment_${data['data'][i].comment_id}">
  187. <div class="row mt-2">
  188. <div class="col">
  189. <div class="row mr-2">
  190. <div class="col">
  191. <div class="ml-2 row">
  192. ${avatar}
  193. <h6 class="text-uppercase fw-bold mb-1 ml-1 mt-2">${filterXSS(data['data'][i].name)}</h6>
  194. <div class="ml-auto">
  195. ${can_edit} <small class="text-muted text-wrap">${data['data'][i].comment_date}</small>
  196. </div>
  197. </div>
  198. <div class="row" style="border-left: 3px solid #eaeaea;margin-left:30px;">
  199. <span class="text-muted ml-2">${comment_html}</span>
  200. </div>
  201. </div>
  202. </div>
  203. </div>
  204. </div>
  205. </div>
  206. </div>
  207. `;
  208. $('#comments_list').append(comment);
  209. }
  210. $('#comments_list').append('<div id="last-comment"><div>');
  211. if (data['data'].length === 0) {
  212. $('#comments_list').html('<div class="text-center">No comments yet</div>');
  213. } else if (comment_id === undefined || comment_id === null) {
  214. offset = document.getElementById("last-comment").offsetTop;
  215. if (offset > 20) {
  216. $('.comments-listing').animate({ scrollTop: offset});
  217. }
  218. } else {
  219. if (document.getElementById('#comment_'+comment_id) !== null) {
  220. offset = document.getElementById('#comment_'+comment_id).offsetTop;
  221. if (offset > 20) {
  222. $('.comments-listing').animate({ scrollTop: offset});
  223. }
  224. }
  225. }
  226. });
  227. }