選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。
 
 
 
 
 
 

290 行
8.4 KiB

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