blob: 0d16ab0ad0a55bbef1fcb88c9e436be4f8aa839d [file] [log] [blame]
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +05301frappe.pages["leaderboard"].on_page_load = function (wrapper) {
2 frappe.leaderboard = new frappe.Leaderboard(wrapper);
3}
Ayush Shuklaa111f782017-06-20 13:04:45 +05304
5frappe.Leaderboard = Class.extend({
6
7 init: function (parent) {
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +05308 frappe.ui.make_app_page({
Ayush Shuklaa111f782017-06-20 13:04:45 +05309 parent: parent,
10 title: "Leaderboard",
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +053011 single_column: false
Ayush Shuklaa111f782017-06-20 13:04:45 +053012 });
13
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +053014 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 Shuklaa111f782017-06-20 13:04:45 +053019 // const list of doctypes
20 this.doctypes = ["Customer", "Item", "Supplier", "Sales Partner"];
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +053021 this.timespans = ["Week", "Month", "Quarter", "Year"];
Ayush Shuklaa111f782017-06-20 13:04:45 +053022 this.desc_fields = ["total_amount", "total_request", "annual_billing", "commission_rate"];
23 this.filters = {
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +053024 "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 Shuklaa111f782017-06-20 13:04:45 +053028 };
29
30 // for saving current selected filters
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +053031 // 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 Shuklaa111f782017-06-20 13:04:45 +053036 this.options = {
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +053037 selected_doctype: _initial_doctype,
38 selected_filter: _initial_filter,
39 selected_filter_item: _initial_filter[0],
40 selected_timespan: _initial_timespan,
Ayush Shuklaa111f782017-06-20 13:04:45 +053041 };
42
43 this.message = null;
44 this.make();
45 },
46
Ayush Shuklaa111f782017-06-20 13:04:45 +053047 make: function () {
48 var me = this;
49
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +053050 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 Shuklaa111f782017-06-20 13:04:45 +053054
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +053055 this.$graph_area = $container.find('.leaderboard-graph');
Ayush Shuklaa111f782017-06-20 13:04:45 +053056
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +053057 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 Shuklaa111f782017-06-20 13:04:45 +0530104
105 // now get leaderboard
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530106 this.$sidebar_list.find('li:first').trigger('click');
Ayush Shuklaa111f782017-06-20 13:04:45 +0530107 },
108
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530109 make_request: function ($container) {
Ayush Shuklaa111f782017-06-20 13:04:45 +0530110 var me = this;
111
112 frappe.model.with_doctype(me.options.selected_doctype, function () {
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530113 me.get_leaderboard(me.get_leaderboard_data, $container);
Ayush Shuklaa111f782017-06-20 13:04:45 +0530114 });
115 },
116
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530117 get_leaderboard: function (notify, $container, start=0) {
Ayush Shuklaa111f782017-06-20 13:04:45 +0530118 var me = this;
119
120 frappe.call({
121 method: "erpnext.utilities.page.leaderboard.leaderboard.get_leaderboard",
122 args: {
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530123 doctype: me.options.selected_doctype,
124 timespan: me.options.selected_timespan,
125 field: me.options.selected_filter_item,
126 start: start
Ayush Shuklaa111f782017-06-20 13:04:45 +0530127 },
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530128 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 Shuklaa111f782017-06-20 13:04:45 +0530152 }
153 });
154 },
155
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530156 get_leaderboard_data: function (me, res, $container) {
Ayush Shuklaa111f782017-06-20 13:04:45 +0530157 if (res && res.message) {
158 me.message = null;
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530159 $container.find(".leaderboard-list").html(me.render_list_view(res.message));
Ayush Shuklaa111f782017-06-20 13:04:45 +0530160 } else {
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530161 me.$graph_area.hide();
Ayush Shuklaa111f782017-06-20 13:04:45 +0530162 me.message = "No items found.";
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530163 $container.find(".leaderboard-list").html(me.render_list_view());
Ayush Shuklaa111f782017-06-20 13:04:45 +0530164 }
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 Singh9b4f3cf2017-09-18 16:41:04 +0530184 ${me.render_list_result(items)}`;
Ayush Shuklaa111f782017-06-20 13:04:45 +0530185
186 return html;
187 },
188
189 render_list_header: function () {
190 var me = this;
191 const _selected_filter = me.options.selected_filter
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530192 .map(i => frappe.model.unscrub(i));
193 const fields = ['name', me.options.selected_filter_item];
Ayush Shuklaa111f782017-06-20 13:04:45 +0530194
195 const html =
196 `<div class="list-headers">
197 <div class="list-item list-item--head" data-list-renderer="${"List"}">
198 ${
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530199 fields.map(filter => {
200 const col = frappe.model.unscrub(filter);
Ayush Shuklaa111f782017-06-20 13:04:45 +0530201 return (
202 `<div class="leaderboard-item list-item_content ellipsis text-muted list-item__content--flex-2
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530203 header-btn-base
Ayush Shuklaa111f782017-06-20 13:04:45 +0530204 ${(col && _selected_filter.indexOf(col) !== -1) ? "text-right" : ""}">
205 <span class="list-col-title ellipsis">
206 ${col}
Ayush Shuklaa111f782017-06-20 13:04:45 +0530207 </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 Singh9b4f3cf2017-09-18 16:41:04 +0530219 let _html = items.map((item, index) => {
Ayush Shuklaa111f782017-06-20 13:04:45 +0530220 const $value = $(me.get_item_html(item));
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530221
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 Shuklaa111f782017-06-20 13:04:45 +0530231 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 Singh9b4f3cf2017-09-18 16:41:04 +0530248 `<div class="no-result text-center" style="${me.message ? "" : "display:none;"}">
Ayush Shuklaa111f782017-06-20 13:04:45 +0530249 <div class="msg-box no-border">
250 <p>No Item found</p>
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530251 </div>
Ayush Shuklaa111f782017-06-20 13:04:45 +0530252 </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 Singh9b4f3cf2017-09-18 16:41:04 +0530260 .map(i => frappe.model.unscrub(i));
261 const fields = ['name', me.options.selected_filter_item];
Ayush Shuklaa111f782017-06-20 13:04:45 +0530262
263 const html =
264 `<div class="list-item">
265 ${
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530266 fields.map(filter => {
267 const col = frappe.model.unscrub(filter);
268 let val = item[filter];
Ayush Shuklaa111f782017-06-20 13:04:45 +0530269 if (col === "Modified") {
270 val = comment_when(val);
271 }
272 return (
273 `<div class="list-item_content ellipsis list-item__content--flex-2
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530274 ${(col !== "Name" && col !== "Modified") ? "hidden-xs" : ""}
Ayush Shuklaa111f782017-06-20 13:04:45 +0530275 ${(col && _selected_filter.indexOf(col) !== -1) ? "text-right" : ""}">
276 ${
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530277 col === "Name"
278 ? `<a class="grey list-id ellipsis" href="${item["href"]}"> ${val} </a>`
Ayush Shuklaa111f782017-06-20 13:04:45 +0530279 : `<span class="text-muted ellipsis"> ${val}</span>`
280 }
281 </div>`);
282 }).join("")
283 }
284 </div>`;
285
286 return html;
287 },
288
Prateeksha Singh9b4f3cf2017-09-18 16:41:04 +0530289 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 Shuklaa111f782017-06-20 13:04:45 +0530294 }
295});