Prateeksha Singh | 9b4f3cf | 2017-09-18 16:41:04 +0530 | [diff] [blame] | 1 | frappe.pages["leaderboard"].on_page_load = function (wrapper) { |
| 2 | frappe.leaderboard = new frappe.Leaderboard(wrapper); |
| 3 | } |
Ayush Shukla | a111f78 | 2017-06-20 13:04:45 +0530 | [diff] [blame] | 4 | |
| 5 | frappe.Leaderboard = Class.extend({ |
| 6 | |
| 7 | init: function (parent) { |
Prateeksha Singh | 9b4f3cf | 2017-09-18 16:41:04 +0530 | [diff] [blame] | 8 | frappe.ui.make_app_page({ |
Ayush Shukla | a111f78 | 2017-06-20 13:04:45 +0530 | [diff] [blame] | 9 | parent: parent, |
| 10 | title: "Leaderboard", |
Prateeksha Singh | 9b4f3cf | 2017-09-18 16:41:04 +0530 | [diff] [blame] | 11 | single_column: false |
Ayush Shukla | a111f78 | 2017-06-20 13:04:45 +0530 | [diff] [blame] | 12 | }); |
| 13 | |
Prateeksha Singh | 9b4f3cf | 2017-09-18 16:41:04 +0530 | [diff] [blame] | 14 | this.parent = parent; |
| 15 | this.page = this.parent.page; |
| 16 | this.page.sidebar.html(`<ul class="module-sidebar-nav overlay-sidebar nav nav-pills nav-stacked"></ul>`); |
| 17 | this.$sidebar_list = this.page.sidebar.find('ul'); |
| 18 | |
Ayush Shukla | a111f78 | 2017-06-20 13:04:45 +0530 | [diff] [blame] | 19 | // const list of doctypes |
| 20 | this.doctypes = ["Customer", "Item", "Supplier", "Sales Partner"]; |
Prateeksha Singh | 9b4f3cf | 2017-09-18 16:41:04 +0530 | [diff] [blame] | 21 | this.timespans = ["Week", "Month", "Quarter", "Year"]; |
Ayush Shukla | a111f78 | 2017-06-20 13:04:45 +0530 | [diff] [blame] | 22 | this.desc_fields = ["total_amount", "total_request", "annual_billing", "commission_rate"]; |
| 23 | this.filters = { |
Prateeksha Singh | 9b4f3cf | 2017-09-18 16:41:04 +0530 | [diff] [blame] | 24 | "Customer": ["total_amount", "total_item_purchased"], |
| 25 | "Item": ["total_request", "total_purchase", "avg_price"], |
| 26 | "Supplier": ["annual_billing", "total_unpaid"], |
| 27 | "Sales Partner": ["commission_rate", "target_qty", "target_amount"], |
Ayush Shukla | a111f78 | 2017-06-20 13:04:45 +0530 | [diff] [blame] | 28 | }; |
| 29 | |
| 30 | // for saving current selected filters |
Prateeksha Singh | 9b4f3cf | 2017-09-18 16:41:04 +0530 | [diff] [blame] | 31 | // TODO: revert to 0 index for doctype and timespan, and remove preset down |
| 32 | const _initial_doctype = this.doctypes[0]; |
| 33 | const _initial_timespan = this.timespans[0]; |
| 34 | const _initial_filter = this.filters[_initial_doctype]; |
| 35 | |
Ayush Shukla | a111f78 | 2017-06-20 13:04:45 +0530 | [diff] [blame] | 36 | this.options = { |
Prateeksha Singh | 9b4f3cf | 2017-09-18 16:41:04 +0530 | [diff] [blame] | 37 | selected_doctype: _initial_doctype, |
| 38 | selected_filter: _initial_filter, |
| 39 | selected_filter_item: _initial_filter[0], |
| 40 | selected_timespan: _initial_timespan, |
Ayush Shukla | a111f78 | 2017-06-20 13:04:45 +0530 | [diff] [blame] | 41 | }; |
| 42 | |
| 43 | this.message = null; |
| 44 | this.make(); |
| 45 | }, |
| 46 | |
Ayush Shukla | a111f78 | 2017-06-20 13:04:45 +0530 | [diff] [blame] | 47 | make: function () { |
| 48 | var me = this; |
| 49 | |
Prateeksha Singh | 9b4f3cf | 2017-09-18 16:41:04 +0530 | [diff] [blame] | 50 | var $container = $(`<div class="leaderboard page-main-content"> |
| 51 | <div class="leaderboard-graph"></div> |
| 52 | <div class="leaderboard-list"></div> |
| 53 | </div>`).appendTo(this.page.main); |
Ayush Shukla | a111f78 | 2017-06-20 13:04:45 +0530 | [diff] [blame] | 54 | |
Prateeksha Singh | 9b4f3cf | 2017-09-18 16:41:04 +0530 | [diff] [blame] | 55 | this.$graph_area = $container.find('.leaderboard-graph'); |
Ayush Shukla | a111f78 | 2017-06-20 13:04:45 +0530 | [diff] [blame] | 56 | |
Prateeksha Singh | 9b4f3cf | 2017-09-18 16:41:04 +0530 | [diff] [blame] | 57 | this.doctypes.map(doctype => { |
| 58 | this.get_sidebar_item(doctype).appendTo(this.$sidebar_list); |
| 59 | }); |
| 60 | |
| 61 | this.timespan_select = this.page.add_select(__("Timespan"), |
| 62 | this.timespans.map(d => { |
| 63 | return {"label": __(d), value: d } |
| 64 | }) |
| 65 | ); |
| 66 | |
| 67 | // this.timespan_select.val(this.timespans[1]); |
| 68 | |
| 69 | this.type_select = this.page.add_select(__("Type"), |
| 70 | me.options.selected_filter.map(d => { |
| 71 | return {"label": __(frappe.model.unscrub(d)), value: d } |
| 72 | }) |
| 73 | ); |
| 74 | |
| 75 | this.$sidebar_list.on('click', 'li', function(e) { |
| 76 | let $li = $(this); |
| 77 | let doctype = $li.find('span').html(); |
| 78 | |
| 79 | me.options.selected_doctype = doctype; |
| 80 | me.options.selected_filter = me.filters[doctype]; |
| 81 | me.options.selected_filter_item = me.filters[doctype][0]; |
| 82 | |
| 83 | me.type_select.empty().add_options( |
| 84 | me.options.selected_filter.map(d => { |
| 85 | return {"label": __(frappe.model.unscrub(d)), value: d } |
| 86 | }) |
| 87 | ); |
| 88 | |
| 89 | me.$sidebar_list.find('li').removeClass('active'); |
| 90 | $li.addClass('active'); |
| 91 | |
| 92 | me.make_request($container); |
| 93 | }); |
| 94 | |
| 95 | this.timespan_select.on("change", function() { |
| 96 | me.options.selected_timespan = this.value; |
| 97 | me.make_request($container); |
| 98 | }); |
| 99 | |
| 100 | this.type_select.on("change", function() { |
| 101 | me.options.selected_filter_item = this.value |
| 102 | me.make_request($container); |
| 103 | }); |
Ayush Shukla | a111f78 | 2017-06-20 13:04:45 +0530 | [diff] [blame] | 104 | |
| 105 | // now get leaderboard |
Prateeksha Singh | 9b4f3cf | 2017-09-18 16:41:04 +0530 | [diff] [blame] | 106 | this.$sidebar_list.find('li:first').trigger('click'); |
Ayush Shukla | a111f78 | 2017-06-20 13:04:45 +0530 | [diff] [blame] | 107 | }, |
| 108 | |
Prateeksha Singh | 9b4f3cf | 2017-09-18 16:41:04 +0530 | [diff] [blame] | 109 | make_request: function ($container) { |
Ayush Shukla | a111f78 | 2017-06-20 13:04:45 +0530 | [diff] [blame] | 110 | var me = this; |
| 111 | |
| 112 | frappe.model.with_doctype(me.options.selected_doctype, function () { |
Prateeksha Singh | 9b4f3cf | 2017-09-18 16:41:04 +0530 | [diff] [blame] | 113 | me.get_leaderboard(me.get_leaderboard_data, $container); |
Ayush Shukla | a111f78 | 2017-06-20 13:04:45 +0530 | [diff] [blame] | 114 | }); |
| 115 | }, |
| 116 | |
Prateeksha Singh | 9b4f3cf | 2017-09-18 16:41:04 +0530 | [diff] [blame] | 117 | get_leaderboard: function (notify, $container, start=0) { |
Ayush Shukla | a111f78 | 2017-06-20 13:04:45 +0530 | [diff] [blame] | 118 | var me = this; |
| 119 | |
| 120 | frappe.call({ |
| 121 | method: "erpnext.utilities.page.leaderboard.leaderboard.get_leaderboard", |
| 122 | args: { |
Prateeksha Singh | 9b4f3cf | 2017-09-18 16:41:04 +0530 | [diff] [blame] | 123 | doctype: me.options.selected_doctype, |
| 124 | timespan: me.options.selected_timespan, |
| 125 | field: me.options.selected_filter_item, |
| 126 | start: start |
Ayush Shukla | a111f78 | 2017-06-20 13:04:45 +0530 | [diff] [blame] | 127 | }, |
Prateeksha Singh | 9b4f3cf | 2017-09-18 16:41:04 +0530 | [diff] [blame] | 128 | callback: function (r) { |
| 129 | let results = r.message || []; |
| 130 | |
| 131 | let graph_items = results.slice(0, 10); |
| 132 | |
| 133 | me.$graph_area.show().empty(); |
| 134 | let args = { |
| 135 | parent: me.$graph_area, |
| 136 | y: [ |
| 137 | { |
| 138 | color: 'light-green', |
| 139 | values: graph_items.map(d=>d.value), |
| 140 | formatted: graph_items.map(d=>d[me.options.selected_filter_item]) |
| 141 | } |
| 142 | ], |
| 143 | x: { |
| 144 | values: graph_items.map(d=>d.name) |
| 145 | }, |
| 146 | mode: 'bar', |
| 147 | height: 140 |
| 148 | }; |
| 149 | new frappe.ui.Graph(args); |
| 150 | |
| 151 | notify(me, r, $container); |
Ayush Shukla | a111f78 | 2017-06-20 13:04:45 +0530 | [diff] [blame] | 152 | } |
| 153 | }); |
| 154 | }, |
| 155 | |
Prateeksha Singh | 9b4f3cf | 2017-09-18 16:41:04 +0530 | [diff] [blame] | 156 | get_leaderboard_data: function (me, res, $container) { |
Ayush Shukla | a111f78 | 2017-06-20 13:04:45 +0530 | [diff] [blame] | 157 | if (res && res.message) { |
| 158 | me.message = null; |
Prateeksha Singh | 9b4f3cf | 2017-09-18 16:41:04 +0530 | [diff] [blame] | 159 | $container.find(".leaderboard-list").html(me.render_list_view(res.message)); |
Ayush Shukla | a111f78 | 2017-06-20 13:04:45 +0530 | [diff] [blame] | 160 | } else { |
Prateeksha Singh | 9b4f3cf | 2017-09-18 16:41:04 +0530 | [diff] [blame] | 161 | me.$graph_area.hide(); |
Ayush Shukla | a111f78 | 2017-06-20 13:04:45 +0530 | [diff] [blame] | 162 | me.message = "No items found."; |
Prateeksha Singh | 9b4f3cf | 2017-09-18 16:41:04 +0530 | [diff] [blame] | 163 | $container.find(".leaderboard-list").html(me.render_list_view()); |
Ayush Shukla | a111f78 | 2017-06-20 13:04:45 +0530 | [diff] [blame] | 164 | } |
| 165 | }, |
| 166 | |
| 167 | render_list_view: function (items = []) { |
| 168 | var me = this; |
| 169 | |
| 170 | var html = |
| 171 | `${me.render_message()} |
| 172 | <div class="result" style="${me.message ? "display:none;" : ""}"> |
| 173 | ${me.render_result(items)} |
| 174 | </div>`; |
| 175 | |
| 176 | return $(html); |
| 177 | }, |
| 178 | |
| 179 | render_result: function (items) { |
| 180 | var me = this; |
| 181 | |
| 182 | var html = |
| 183 | `${me.render_list_header()} |
Prateeksha Singh | 9b4f3cf | 2017-09-18 16:41:04 +0530 | [diff] [blame] | 184 | ${me.render_list_result(items)}`; |
Ayush Shukla | a111f78 | 2017-06-20 13:04:45 +0530 | [diff] [blame] | 185 | |
| 186 | return html; |
| 187 | }, |
| 188 | |
| 189 | render_list_header: function () { |
| 190 | var me = this; |
| 191 | const _selected_filter = me.options.selected_filter |
Prateeksha Singh | 9b4f3cf | 2017-09-18 16:41:04 +0530 | [diff] [blame] | 192 | .map(i => frappe.model.unscrub(i)); |
| 193 | const fields = ['name', me.options.selected_filter_item]; |
Ayush Shukla | a111f78 | 2017-06-20 13:04:45 +0530 | [diff] [blame] | 194 | |
| 195 | const html = |
| 196 | `<div class="list-headers"> |
| 197 | <div class="list-item list-item--head" data-list-renderer="${"List"}"> |
| 198 | ${ |
Prateeksha Singh | 9b4f3cf | 2017-09-18 16:41:04 +0530 | [diff] [blame] | 199 | fields.map(filter => { |
| 200 | const col = frappe.model.unscrub(filter); |
Ayush Shukla | a111f78 | 2017-06-20 13:04:45 +0530 | [diff] [blame] | 201 | return ( |
| 202 | `<div class="leaderboard-item list-item_content ellipsis text-muted list-item__content--flex-2 |
Prateeksha Singh | 9b4f3cf | 2017-09-18 16:41:04 +0530 | [diff] [blame] | 203 | header-btn-base |
Ayush Shukla | a111f78 | 2017-06-20 13:04:45 +0530 | [diff] [blame] | 204 | ${(col && _selected_filter.indexOf(col) !== -1) ? "text-right" : ""}"> |
| 205 | <span class="list-col-title ellipsis"> |
| 206 | ${col} |
Ayush Shukla | a111f78 | 2017-06-20 13:04:45 +0530 | [diff] [blame] | 207 | </span> |
| 208 | </div>`); |
| 209 | }).join("") |
| 210 | } |
| 211 | </div> |
| 212 | </div>`; |
| 213 | return html; |
| 214 | }, |
| 215 | |
| 216 | render_list_result: function (items) { |
| 217 | var me = this; |
| 218 | |
Prateeksha Singh | 9b4f3cf | 2017-09-18 16:41:04 +0530 | [diff] [blame] | 219 | let _html = items.map((item, index) => { |
Ayush Shukla | a111f78 | 2017-06-20 13:04:45 +0530 | [diff] [blame] | 220 | const $value = $(me.get_item_html(item)); |
Prateeksha Singh | 9b4f3cf | 2017-09-18 16:41:04 +0530 | [diff] [blame] | 221 | |
| 222 | let item_class = ""; |
| 223 | if(index == 0) { |
| 224 | item_class = "first"; |
| 225 | } else if (index == 1) { |
| 226 | item_class = "second"; |
| 227 | } else if(index == 2) { |
| 228 | item_class = "third"; |
| 229 | } |
| 230 | const $item_container = $(`<div class="list-item-container ${item_class}">`).append($value); |
Ayush Shukla | a111f78 | 2017-06-20 13:04:45 +0530 | [diff] [blame] | 231 | return $item_container[0].outerHTML; |
| 232 | }).join(""); |
| 233 | |
| 234 | let html = |
| 235 | `<div class="result-list"> |
| 236 | <div class="list-items"> |
| 237 | ${_html} |
| 238 | </div> |
| 239 | </div>`; |
| 240 | |
| 241 | return html; |
| 242 | }, |
| 243 | |
| 244 | render_message: function () { |
| 245 | var me = this; |
| 246 | |
| 247 | let html = |
Prateeksha Singh | 9b4f3cf | 2017-09-18 16:41:04 +0530 | [diff] [blame] | 248 | `<div class="no-result text-center" style="${me.message ? "" : "display:none;"}"> |
Ayush Shukla | a111f78 | 2017-06-20 13:04:45 +0530 | [diff] [blame] | 249 | <div class="msg-box no-border"> |
| 250 | <p>No Item found</p> |
Prateeksha Singh | 9b4f3cf | 2017-09-18 16:41:04 +0530 | [diff] [blame] | 251 | </div> |
Ayush Shukla | a111f78 | 2017-06-20 13:04:45 +0530 | [diff] [blame] | 252 | </div>`; |
| 253 | |
| 254 | return html; |
| 255 | }, |
| 256 | |
| 257 | get_item_html: function (item) { |
| 258 | var me = this; |
| 259 | const _selected_filter = me.options.selected_filter |
Prateeksha Singh | 9b4f3cf | 2017-09-18 16:41:04 +0530 | [diff] [blame] | 260 | .map(i => frappe.model.unscrub(i)); |
| 261 | const fields = ['name', me.options.selected_filter_item]; |
Ayush Shukla | a111f78 | 2017-06-20 13:04:45 +0530 | [diff] [blame] | 262 | |
| 263 | const html = |
| 264 | `<div class="list-item"> |
| 265 | ${ |
Prateeksha Singh | 9b4f3cf | 2017-09-18 16:41:04 +0530 | [diff] [blame] | 266 | fields.map(filter => { |
| 267 | const col = frappe.model.unscrub(filter); |
| 268 | let val = item[filter]; |
Ayush Shukla | a111f78 | 2017-06-20 13:04:45 +0530 | [diff] [blame] | 269 | if (col === "Modified") { |
| 270 | val = comment_when(val); |
| 271 | } |
| 272 | return ( |
| 273 | `<div class="list-item_content ellipsis list-item__content--flex-2 |
Prateeksha Singh | 9b4f3cf | 2017-09-18 16:41:04 +0530 | [diff] [blame] | 274 | ${(col !== "Name" && col !== "Modified") ? "hidden-xs" : ""} |
Ayush Shukla | a111f78 | 2017-06-20 13:04:45 +0530 | [diff] [blame] | 275 | ${(col && _selected_filter.indexOf(col) !== -1) ? "text-right" : ""}"> |
| 276 | ${ |
Prateeksha Singh | 9b4f3cf | 2017-09-18 16:41:04 +0530 | [diff] [blame] | 277 | col === "Name" |
| 278 | ? `<a class="grey list-id ellipsis" href="${item["href"]}"> ${val} </a>` |
Ayush Shukla | a111f78 | 2017-06-20 13:04:45 +0530 | [diff] [blame] | 279 | : `<span class="text-muted ellipsis"> ${val}</span>` |
| 280 | } |
| 281 | </div>`); |
| 282 | }).join("") |
| 283 | } |
| 284 | </div>`; |
| 285 | |
| 286 | return html; |
| 287 | }, |
| 288 | |
Prateeksha Singh | 9b4f3cf | 2017-09-18 16:41:04 +0530 | [diff] [blame] | 289 | get_sidebar_item: function(item) { |
| 290 | return $(`<li class="strong module-sidebar-item"> |
| 291 | <a class="module-link"> |
| 292 | <span>${ item }</span></a> |
| 293 | </li>`); |
Ayush Shukla | a111f78 | 2017-06-20 13:04:45 +0530 | [diff] [blame] | 294 | } |
| 295 | }); |