Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.
 
 
 
 
 
 

230 рядки
5.7 KiB

  1. // Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
  2. // MIT License. See license.txt
  3. frappe.ui.form.Attachments = class Attachments {
  4. constructor(opts) {
  5. $.extend(this, opts);
  6. this.make();
  7. }
  8. make() {
  9. var me = this;
  10. this.parent.find(".add-attachment-btn").click(function() {
  11. me.new_attachment();
  12. });
  13. this.add_attachment_wrapper = this.parent.find(".add-attachment-btn");
  14. this.attachments_label = this.parent.find(".attachments-label");
  15. }
  16. max_reached(raise_exception=false) {
  17. const attachment_count = Object.keys(this.get_attachments()).length;
  18. const attachment_limit = this.frm.meta.max_attachments;
  19. if (attachment_limit && attachment_count >= attachment_limit) {
  20. if (raise_exception) {
  21. frappe.throw({
  22. title: __("Attachment Limit Reached"),
  23. message: __("Maximum attachment limit of {0} has been reached.", [cstr(attachment_limit).bold()]),
  24. });
  25. }
  26. return true;
  27. }
  28. return false;
  29. }
  30. refresh() {
  31. var me = this;
  32. if(this.frm.doc.__islocal) {
  33. this.parent.toggle(false);
  34. return;
  35. }
  36. this.parent.toggle(true);
  37. this.parent.find(".attachment-row").remove();
  38. var max_reached = this.max_reached();
  39. this.add_attachment_wrapper.toggle(!max_reached);
  40. // add attachment objects
  41. var attachments = this.get_attachments();
  42. if(attachments.length) {
  43. let exists = {};
  44. let unique_attachments = attachments.filter(attachment => {
  45. return Object.prototype.hasOwnProperty.call(
  46. exists,
  47. attachment.file_name
  48. )
  49. ? false
  50. : (exists[attachment.file_name] = true);
  51. });
  52. unique_attachments.forEach(attachment => {
  53. me.add_attachment(attachment);
  54. });
  55. } else {
  56. this.attachments_label.removeClass("has-attachments");
  57. }
  58. }
  59. get_attachments() {
  60. return this.frm.get_docinfo().attachments;
  61. }
  62. add_attachment(attachment) {
  63. var file_name = attachment.file_name;
  64. var file_url = this.get_file_url(attachment);
  65. var fileid = attachment.name;
  66. if (!file_name) {
  67. file_name = file_url;
  68. }
  69. var me = this;
  70. let file_label = `
  71. <a href="${file_url}" target="_blank" title="${file_name}" class="ellipsis" style="max-width: calc(100% - 43px);">
  72. <span>${file_name}</span>
  73. </a>`;
  74. let remove_action = null;
  75. if (frappe.model.can_write(this.frm.doctype, this.frm.name)) {
  76. remove_action = function(target_id) {
  77. frappe.confirm(__("Are you sure you want to delete the attachment?"),
  78. function() {
  79. let target_attachment = me
  80. .get_attachments()
  81. .find(attachment => attachment.name === target_id);
  82. let to_be_removed = me
  83. .get_attachments()
  84. .filter(
  85. attachment =>
  86. attachment.file_name ===
  87. target_attachment.file_name
  88. );
  89. to_be_removed.forEach(attachment =>
  90. me.remove_attachment(attachment.name)
  91. );
  92. }
  93. );
  94. return false;
  95. };
  96. }
  97. const icon = `<a href="/app/file/${fileid}">
  98. ${frappe.utils.icon(attachment.is_private ? 'lock' : 'unlock', 'sm ml-0')}
  99. </a>`;
  100. $(`<li class="attachment-row">`)
  101. .append(frappe.get_data_pill(
  102. file_label,
  103. fileid,
  104. remove_action,
  105. icon
  106. ))
  107. .insertAfter(this.attachments_label.addClass("has-attachments"));
  108. }
  109. get_file_url(attachment) {
  110. var file_url = attachment.file_url;
  111. if (!file_url) {
  112. if (attachment.file_name.indexOf('files/') === 0) {
  113. file_url = '/' + attachment.file_name;
  114. }
  115. else {
  116. file_url = '/files/' + attachment.file_name;
  117. }
  118. }
  119. // hash is not escaped, https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURI
  120. return encodeURI(file_url).replace(/#/g, '%23');
  121. }
  122. get_file_id_from_file_url(file_url) {
  123. var fid;
  124. $.each(this.get_attachments(), function(i, attachment) {
  125. if (attachment.file_url === file_url) {
  126. fid = attachment.name;
  127. return false;
  128. }
  129. });
  130. return fid;
  131. }
  132. remove_attachment_by_filename(filename, callback) {
  133. this.remove_attachment(this.get_file_id_from_file_url(filename), callback);
  134. }
  135. remove_attachment(fileid, callback) {
  136. if (!fileid) {
  137. if (callback) callback();
  138. return;
  139. }
  140. var me = this;
  141. return frappe.call({
  142. method: 'frappe.desk.form.utils.remove_attach',
  143. args: {
  144. fid: fileid,
  145. dt: me.frm.doctype,
  146. dn: me.frm.docname
  147. },
  148. callback: function(r,rt) {
  149. if(r.exc) {
  150. if(!r._server_messages)
  151. frappe.msgprint(__("There were errors"));
  152. return;
  153. }
  154. me.remove_fileid(fileid);
  155. me.frm.sidebar.reload_docinfo();
  156. if (callback) callback();
  157. }
  158. });
  159. }
  160. new_attachment(fieldname) {
  161. if (this.dialog) {
  162. // remove upload dialog
  163. this.dialog.$wrapper.remove();
  164. }
  165. new frappe.ui.FileUploader({
  166. doctype: this.frm.doctype,
  167. docname: this.frm.docname,
  168. frm: this.frm,
  169. folder: 'Home/Attachments',
  170. on_success: (file_doc) => {
  171. this.attachment_uploaded(file_doc);
  172. }
  173. });
  174. }
  175. get_args() {
  176. return {
  177. from_form: 1,
  178. doctype: this.frm.doctype,
  179. docname: this.frm.docname,
  180. }
  181. }
  182. attachment_uploaded(attachment) {
  183. this.dialog && this.dialog.hide();
  184. this.update_attachment(attachment);
  185. this.frm.sidebar.reload_docinfo();
  186. if(this.fieldname) {
  187. this.frm.set_value(this.fieldname, attachment.file_url);
  188. }
  189. }
  190. update_attachment(attachment) {
  191. if(attachment.name) {
  192. this.add_to_attachments(attachment);
  193. this.refresh();
  194. }
  195. }
  196. add_to_attachments (attachment) {
  197. var form_attachments = this.get_attachments();
  198. for(var i in form_attachments) {
  199. // prevent duplicate
  200. if(form_attachments[i]["name"] === attachment.name) return;
  201. }
  202. form_attachments.push(attachment);
  203. }
  204. remove_fileid(fileid) {
  205. var attachments = this.get_attachments();
  206. var new_attachments = [];
  207. $.each(attachments, function(i, attachment) {
  208. if(attachment.name!=fileid) {
  209. new_attachments.push(attachment);
  210. }
  211. });
  212. this.frm.get_docinfo().attachments = new_attachments;
  213. this.refresh();
  214. }
  215. };