您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

doclistview.js 8.6 KiB

13 年前
13 年前
13 年前
13 年前
13 年前
13 年前
13 年前
13 年前
13 年前
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. // Copyright 2013 Web Notes Technologies Pvt Ltd
  2. // License: MIT. See license.txt
  3. wn.provide('wn.views.doclistview');
  4. wn.provide('wn.doclistviews');
  5. wn.views.doclistview.show = function(doctype) {
  6. var route = wn.get_route();
  7. var page_name = "List/" + route[1];
  8. if(wn.pages[page_name]) {
  9. wn.container.change_to(wn.pages[page_name]);
  10. if(wn.container.page.doclistview && wn.container.page.doclistview.dirty)
  11. wn.container.page.doclistview.run();
  12. } else {
  13. if(route[1]) {
  14. wn.model.with_doctype(route[1], function(r) {
  15. if(r && r['403']) {
  16. return;
  17. }
  18. new wn.views.DocListView(route[1]);
  19. });
  20. }
  21. }
  22. }
  23. $(document).on("save", function(event, doc) {
  24. var list_page = "List/" + doc.doctype;
  25. if(wn.pages[list_page]) {
  26. if(wn.pages[list_page].doclistview)
  27. wn.pages[list_page].doclistview.dirty = true;
  28. }
  29. })
  30. wn.views.DocListView = wn.ui.Listing.extend({
  31. init: function(doctype) {
  32. this.doctype = doctype;
  33. this.label = wn._(doctype);
  34. this.dirty = true;
  35. this.label = (this.label.toLowerCase().substr(-4) == 'list') ?
  36. wn._(this.label) : (wn._(this.label) + ' ' + wn._('List'));
  37. this.make_page();
  38. this.setup();
  39. },
  40. make_page: function() {
  41. var me = this;
  42. var page_name = "List/" + this.doctype;
  43. var page = wn.container.add_page(page_name);
  44. wn.container.change_to(page_name);
  45. page.doclistview = this;
  46. this.$page = $(page).css({"min-height": "400px"});
  47. wn.dom.set_style(".show-docstatus div { font-size: 90%; }");
  48. wn.ui.make_app_page({
  49. parent: page
  50. })
  51. $('<div class="wnlist-area" style="margin-bottom: 25px;">\
  52. <div class="help">'+wn._('Loading')+'...</div></div>')
  53. .appendTo(this.$page.find(".layout-main-section"));
  54. $('<div class="show-docstatus hide section">\
  55. <div class="section-head">Show</div>\
  56. <div><input data-docstatus="0" type="checkbox" \
  57. checked="checked" /> '+wn._('Drafts')+'</div>\
  58. <div><input data-docstatus="1" type="checkbox" \
  59. checked="checked" /> '+wn._('Submitted')+'</div>\
  60. <div><input data-docstatus="2" type="checkbox" \
  61. /> '+wn._('Cancelled')+'</div>\
  62. </div>')
  63. .appendTo(this.$page.find(".layout-side-section"));
  64. this.appframe = page.appframe;
  65. var module = locals.DocType[this.doctype].module;
  66. this.appframe.set_title(wn._(this.doctype) + " " + wn._("List"));
  67. this.appframe.add_home_breadcrumb();
  68. this.appframe.add_module_icon(module);
  69. this.appframe.add_breadcrumb("icon-list");
  70. this.appframe.set_views_for(this.doctype, "list");
  71. },
  72. setup: function() {
  73. var me = this;
  74. me.can_delete = wn.model.can_delete(me.doctype);
  75. me.meta = locals.DocType[me.doctype];
  76. me.$page.find('.wnlist-area').empty(),
  77. me.setup_listview();
  78. me.setup_docstatus_filter();
  79. me.init_list();
  80. me.init_stats();
  81. me.add_delete_option();
  82. me.show_match_help();
  83. if(me.listview.settings.onload) {
  84. me.listview.settings.onload(me);
  85. }
  86. me.make_help();
  87. },
  88. show_match_help: function() {
  89. var me = this;
  90. var match_rules = wn.perm.get_match_rule(this.doctype);
  91. if(keys(match_rules).length) {
  92. var match_text = []
  93. $.each(match_rules, function(key, values) {
  94. if(values.length==0) {
  95. match_text.push(wn._(wn.meta.get_label(me.doctype, key)) + wn._(" is not set"));
  96. } else if(values.length) {
  97. match_text.push(wn._(wn.meta.get_label(me.doctype, key)) + " = " + wn.utils.comma_or(values));
  98. }
  99. });
  100. wn.utils.set_footnote(this, this.$page.find(".layout-main-section"),
  101. wn._("Showing only for") + ": " + match_text.join(" & "));
  102. $(this.footnote_area).css({"margin-top":"0px", "margin-bottom":"20px"});
  103. }
  104. },
  105. make_help: function() {
  106. // Help
  107. if(this.meta.description) {
  108. this.appframe.add_help_button(this.meta.description);
  109. }
  110. },
  111. setup_docstatus_filter: function() {
  112. var me = this;
  113. this.can_submit = $.map(locals.DocPerm || [], function(d) {
  114. if(d.parent==me.meta.name && d.submit) return 1
  115. else return null;
  116. }).length;
  117. if(this.can_submit) {
  118. this.$page.find('.show-docstatus').removeClass('hide');
  119. this.$page.find('.show-docstatus input').click(function() {
  120. me.run();
  121. })
  122. }
  123. },
  124. setup_listview: function() {
  125. this.listview = wn.views.get_listview(this.doctype, this);
  126. this.wrapper = this.$page.find('.wnlist-area');
  127. this.page_length = 20;
  128. this.allow_delete = true;
  129. },
  130. init_list: function(auto_run) {
  131. var me = this;
  132. // init list
  133. this.make({
  134. method: 'webnotes.widgets.reportview.get',
  135. get_args: this.get_args,
  136. parent: this.wrapper,
  137. freeze: true,
  138. start: 0,
  139. page_length: this.page_length,
  140. show_filters: true,
  141. show_grid: true,
  142. new_doctype: this.doctype,
  143. allow_delete: this.allow_delete,
  144. no_result_message: this.make_no_result(),
  145. custom_new_doc: me.listview.make_new_doc || undefined,
  146. });
  147. // make_new_doc can be overridden so that default values can be prefilled
  148. // for example - communication list in customer
  149. $(this.wrapper).on("click", 'button[list_view_doc="'+me.doctype+'"]', function(){
  150. (me.listview.make_new_doc || me.make_new_doc)(me.doctype);
  151. });
  152. if((auto_run !== false) && (auto_run !== 0)) this.run();
  153. },
  154. run: function(more) {
  155. // set filter from route
  156. var route = wn.get_route();
  157. var me = this;
  158. if(route[2]) {
  159. $.each(wn.utils.get_args_dict_from_url(route[2]), function(key, val) {
  160. me.set_filter(key, val, true);
  161. });
  162. }
  163. this._super(more);
  164. },
  165. make_no_result: function() {
  166. var new_button = wn.boot.profile.can_create.indexOf(this.doctype)!=-1
  167. ? ('<hr><p><button class="btn btn-default btn-info" \
  168. list_view_doc="%(doctype)s">'+
  169. wn._('Make a new') + ' %(doctype_label)s</button></p>')
  170. : '';
  171. var no_result_message = repl('<div class="well">\
  172. <p>No %(doctype_label)s found</p>' + new_button + '</div>', {
  173. doctype_label: wn._(this.doctype),
  174. doctype: this.doctype,
  175. });
  176. return no_result_message;
  177. },
  178. render_row: function(row, data) {
  179. data.doctype = this.doctype;
  180. this.listview.render(row, data, this);
  181. },
  182. get_args: function() {
  183. var docstatus_list = this.can_submit ? $.map(this.$page.find('.show-docstatus :checked'),
  184. function(inp) {
  185. return $(inp).attr('data-docstatus');
  186. }) : []
  187. var args = {
  188. doctype: this.doctype,
  189. fields: this.listview.fields,
  190. filters: this.filter_list.get_filters(),
  191. docstatus: docstatus_list,
  192. order_by: this.listview.order_by || undefined,
  193. group_by: this.listview.group_by || undefined,
  194. }
  195. // apply default filters, if specified for a listing
  196. $.each((this.listview.default_filters || []), function(i, f) {
  197. args.filters.push(f);
  198. });
  199. return args;
  200. },
  201. add_delete_option: function() {
  202. var me = this;
  203. if(this.can_delete || this.listview.settings.selectable) {
  204. this.add_button(wn._('Delete'), function() { me.delete_items(); }, 'icon-remove');
  205. this.add_button(wn._('Select All'), function() {
  206. var checks = me.$page.find('.list-delete');
  207. checks.attr('checked', $(checks.get(0)).attr('checked') ? false : "checked");
  208. }, 'icon-ok');
  209. }
  210. },
  211. get_checked_items: function() {
  212. return $.map(this.$page.find('.list-delete:checked'), function(e) {
  213. return $(e).data('data');
  214. });
  215. },
  216. delete_items: function() {
  217. var me = this;
  218. var dl = this.get_checked_items();
  219. if(!dl.length)
  220. return;
  221. wn.confirm(wn._('This is permanent action and you cannot undo. Continue?'),
  222. function() {
  223. me.set_working(true);
  224. wn.call({
  225. method: 'webnotes.widgets.reportview.delete_items',
  226. args: {
  227. items: $.map(dl, function(d, i) { return d.name }),
  228. doctype: me.doctype
  229. },
  230. callback: function() {
  231. me.set_working(false);
  232. me.refresh();
  233. }
  234. })
  235. }
  236. );
  237. },
  238. init_stats: function() {
  239. var me = this;
  240. this.sidebar_stats = new wn.views.SidebarStats({
  241. doctype: this.doctype,
  242. stats: this.listview.stats,
  243. parent: me.$page.find('.layout-side-section'),
  244. set_filter: function(fieldname, label) {
  245. me.set_filter(fieldname, label);
  246. }
  247. })
  248. },
  249. set_filter: function(fieldname, label, no_run) {
  250. var filter = this.filter_list.get_filter(fieldname);
  251. if(filter) {
  252. var v = cstr(filter.field.get_parsed_value());
  253. if(v.indexOf(label)!=-1) {
  254. // already set
  255. return false;
  256. } else {
  257. // second filter set for this field
  258. if(fieldname=='_user_tags') {
  259. // and for tags
  260. this.filter_list.add_filter(this.doctype, fieldname, 'like', '%' + label);
  261. } else {
  262. // or for rest using "in"
  263. filter.set_values(this.doctype, fieldname, 'in', v + ', ' + label);
  264. }
  265. }
  266. } else {
  267. // no filter for this item,
  268. // setup one
  269. if(fieldname=='_user_tags') {
  270. this.filter_list.add_filter(this.doctype, fieldname, 'like', '%' + label);
  271. } else {
  272. this.filter_list.add_filter(this.doctype, fieldname, '=', label);
  273. }
  274. }
  275. if(!no_run)
  276. this.run();
  277. }
  278. });