25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

316 lines
7.2 KiB

  1. // Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
  2. // MIT License. See license.txt
  3. frappe.provide("frappe.messages")
  4. frappe.messages.waiting = function(parent, msg) {
  5. return $(frappe.messages.get_waiting_message(msg))
  6. .appendTo(parent);
  7. };
  8. frappe.messages.get_waiting_message = function(msg) {
  9. return repl('<div class="msg-box" style="width: 63%; margin: 30px auto;">\
  10. <p class="text-center">%(msg)s</p></div>', { msg: msg });
  11. }
  12. frappe.throw = function(msg) {
  13. if(typeof msg==='string') {
  14. msg = {message: msg, title: __('Error')};
  15. }
  16. if(!msg.indicator) msg.indicator = 'red';
  17. frappe.msgprint(msg);
  18. throw new Error(msg.message);
  19. }
  20. frappe.confirm = function(message, ifyes, ifno) {
  21. var d = new frappe.ui.Dialog({
  22. title: __("Confirm"),
  23. fields: [
  24. {fieldtype:"HTML", options:"<p class='frappe-confirm-message'>" + message + "</p>"}
  25. ],
  26. primary_action_label: __("Yes"),
  27. primary_action: function() {
  28. if(ifyes) ifyes();
  29. d.hide();
  30. },
  31. secondary_action_label: __("No")
  32. });
  33. d.show();
  34. // flag, used to bind "okay" on enter
  35. d.confirm_dialog = true;
  36. // no if closed without primary action
  37. if(ifno) {
  38. d.onhide = function() {
  39. if(!d.primary_action_fulfilled) {
  40. ifno();
  41. }
  42. };
  43. }
  44. return d;
  45. }
  46. frappe.prompt = function(fields, callback, title, primary_label) {
  47. if (typeof fields === "string") {
  48. fields = [{
  49. label: fields,
  50. fieldname: "value",
  51. fieldtype: "Data",
  52. reqd: 1
  53. }];
  54. }
  55. if(!$.isArray(fields)) fields = [fields];
  56. var d = new frappe.ui.Dialog({
  57. fields: fields,
  58. title: title || __("Enter Value"),
  59. });
  60. d.set_primary_action(primary_label || __("Submit"), function() {
  61. var values = d.get_values();
  62. if(!values) {
  63. return;
  64. }
  65. d.hide();
  66. callback(values);
  67. });
  68. d.show();
  69. return d;
  70. }
  71. var msg_dialog=null;
  72. frappe.msgprint = function(msg, title) {
  73. if(!msg) return;
  74. if($.isPlainObject(msg)) {
  75. var data = msg;
  76. } else {
  77. // passed as JSON
  78. if(typeof msg==='string' && msg.substr(0,1)==='{') {
  79. var data = JSON.parse(msg);
  80. } else {
  81. var data = {'message': msg, 'title': title};
  82. }
  83. }
  84. if(!data.indicator) {
  85. data.indicator = 'blue';
  86. }
  87. if(data.message instanceof Array) {
  88. data.message.forEach(function(m) {
  89. frappe.msgprint(m);
  90. });
  91. return;
  92. }
  93. if(data.alert) {
  94. frappe.show_alert(data);
  95. return;
  96. }
  97. if(!msg_dialog) {
  98. msg_dialog = new frappe.ui.Dialog({
  99. title: __("Message"),
  100. onhide: function() {
  101. if(msg_dialog.custom_onhide) {
  102. msg_dialog.custom_onhide();
  103. }
  104. msg_dialog.msg_area.empty();
  105. }
  106. });
  107. msg_dialog.msg_area = $('<div class="msgprint">')
  108. .appendTo(msg_dialog.body);
  109. msg_dialog.loading_indicator = $('<div class="loading-indicator text-center" \
  110. style="margin: 15px;">\
  111. <img src="/assets/frappe/images/ui/ajax-loader.gif"></div>')
  112. .appendTo(msg_dialog.body);
  113. msg_dialog.clear = function() {
  114. msg_dialog.msg_area.empty();
  115. }
  116. msg_dialog.indicator = msg_dialog.header.find('.indicator');
  117. }
  118. if(data.message==null) {
  119. data.message = '';
  120. }
  121. if(data.message.search(/<br>|<p>|<li>/)==-1) {
  122. msg = replace_newlines(data.message);
  123. }
  124. var msg_exists = false;
  125. if(data.clear) {
  126. msg_dialog.msg_area.empty();
  127. } else {
  128. msg_exists = msg_dialog.msg_area.html();
  129. }
  130. if(data.title || !msg_exists) {
  131. // set title only if it is explicitly given
  132. // and no existing title exists
  133. msg_dialog.set_title(data.title || __('Message'));
  134. }
  135. // show / hide indicator
  136. if(data.indicator) {
  137. msg_dialog.indicator.removeClass().addClass('indicator ' + data.indicator);
  138. } else {
  139. msg_dialog.indicator.removeClass().addClass('hidden');
  140. }
  141. if(msg_exists) {
  142. msg_dialog.msg_area.append("<hr>");
  143. // append a <hr> if another msg already exists
  144. }
  145. msg_dialog.msg_area.append(data.message);
  146. msg_dialog.loading_indicator.addClass("hide");
  147. msg_dialog.show_loading = function() {
  148. msg_dialog.loading_indicator.removeClass("hide");
  149. }
  150. // make msgprint always appear on top
  151. msg_dialog.$wrapper.css("z-index", 2000);
  152. msg_dialog.show();
  153. return msg_dialog;
  154. }
  155. // Proxy for frappe.msgprint
  156. Object.defineProperty(window, 'msgprint', {
  157. get: function() {
  158. console.warn('Please use `frappe.msgprint` instead of `msgprint`. It will be deprecated soon.');
  159. return frappe.msgprint;
  160. }
  161. });
  162. frappe.hide_msgprint = function(instant) {
  163. // clear msgprint
  164. if(msg_dialog && msg_dialog.msg_area) {
  165. msg_dialog.msg_area.empty();
  166. }
  167. if(msg_dialog && msg_dialog.$wrapper.is(":visible")) {
  168. if(instant) {
  169. msg_dialog.$wrapper.removeClass("fade");
  170. }
  171. msg_dialog.hide();
  172. if(instant) {
  173. msg_dialog.$wrapper.addClass("fade");
  174. }
  175. }
  176. }
  177. // update html in existing msgprint
  178. frappe.update_msgprint = function(html) {
  179. if(!msg_dialog || (msg_dialog && !msg_dialog.$wrapper.is(":visible"))) {
  180. frappe.msgprint(html);
  181. } else {
  182. msg_dialog.msg_area.html(html);
  183. }
  184. }
  185. frappe.verify_password = function(callback) {
  186. frappe.prompt({
  187. fieldname: "password",
  188. label: __("Enter your password"),
  189. fieldtype: "Password",
  190. reqd: 1
  191. }, function(data) {
  192. frappe.call({
  193. method: "frappe.core.doctype.user.user.verify_password",
  194. args: {
  195. password: data.password
  196. },
  197. callback: function(r) {
  198. if(!r.exc) {
  199. callback();
  200. }
  201. }
  202. });
  203. }, __("Verify Password"), __("Verify"))
  204. }
  205. frappe.show_progress = function(title, count, total=100, description) {
  206. if(frappe.cur_progress && frappe.cur_progress.title === title
  207. && frappe.cur_progress.$wrapper.is(":visible")) {
  208. var dialog = frappe.cur_progress;
  209. } else {
  210. var dialog = new frappe.ui.Dialog({
  211. title: title,
  212. });
  213. dialog.progress = $(`<div class="progress">
  214. <div class="progress-bar"></div>
  215. <p class="description text-muted small"></p>
  216. </div>`)
  217. .appendTo(dialog.body);
  218. dialog.progress_bar = dialog.progress.css({"margin-top": "10px"})
  219. .find(".progress-bar");
  220. dialog.$wrapper.removeClass("fade");
  221. dialog.show();
  222. frappe.cur_progress = dialog;
  223. }
  224. if (description) {
  225. dialog.progress.find('.description').text(description);
  226. }
  227. dialog.percent = cint(flt(count) * 100 / total);
  228. dialog.progress_bar.css({"width": dialog.percent + "%" });
  229. return dialog;
  230. }
  231. frappe.hide_progress = function() {
  232. if(frappe.cur_progress) {
  233. frappe.cur_progress.hide();
  234. frappe.cur_progress = null;
  235. }
  236. }
  237. // Floating Message
  238. frappe.show_alert = function(message, seconds=7) {
  239. if(typeof message==='string') {
  240. message = {
  241. message: message
  242. }
  243. }
  244. if(!$('#dialog-container').length) {
  245. $('<div id="dialog-container"><div id="alert-container"></div></div>').appendTo('body');
  246. }
  247. var message_html;
  248. if(message.indicator) {
  249. message_html = $('<span class="indicator ' + message.indicator + '"></span>').append(message.message);
  250. } else {
  251. message_html = message.message;
  252. }
  253. var div = $(`
  254. <div class="alert desk-alert">
  255. <span class="alert-message"></span><a class="close">&times;</a>
  256. </div>`);
  257. div.find('.alert-message').append(message_html);
  258. div.hide()
  259. .appendTo("#alert-container")
  260. .fadeIn(300);
  261. div.find('.close').click(function() {
  262. $(this).parent().remove();
  263. return false;
  264. });
  265. div.delay(seconds * 1000).fadeOut(300);
  266. return div;
  267. }
  268. // Proxy for frappe.show_alert
  269. Object.defineProperty(window, 'show_alert', {
  270. get: function() {
  271. console.warn('Please use `frappe.show_alert` instead of `show_alert`. It will be deprecated soon.');
  272. return frappe.show_alert;
  273. }
  274. });