You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

doclistview.js 8.2 KiB

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