From e9f2aadd386311f0ec39956cda89aa39d4e9ba1d Mon Sep 17 00:00:00 2001 From: Prateeksha Singh Date: Wed, 22 Feb 2017 11:08:36 +0530 Subject: [PATCH] Search fixes (#2746) * GS in awesome bar, UI fixes: scroll nav,lists * awesome bar specificity * Add fuzzy search in awesome bar * Add fuzzy specific boldening * List subtype buttons * Update global_search.py --- .../doctype/communication/communication.json | 6 +- frappe/email/doctype/contact/contact.json | 5 +- frappe/public/css/desk.css | 30 +- .../js/frappe/ui/toolbar/awesome_bar.js | 305 ++++++++++++------ .../public/js/frappe/ui/toolbar/search.html | 2 + frappe/public/js/frappe/ui/toolbar/search.js | 189 ++++++++--- frappe/public/less/desk.less | 46 ++- frappe/utils/global_search.py | 3 +- 8 files changed, 415 insertions(+), 171 deletions(-) diff --git a/frappe/core/doctype/communication/communication.json b/frappe/core/doctype/communication/communication.json index 49142f0b73..0a170eb5a9 100644 --- a/frappe/core/doctype/communication/communication.json +++ b/frappe/core/doctype/communication/communication.json @@ -408,7 +408,7 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, - "in_global_search": 0, + "in_global_search": 1, "in_list_view": 0, "in_standard_filter": 0, "label": "Communication Type", @@ -759,7 +759,7 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, - "in_global_search": 1, + "in_global_search": 0, "in_list_view": 0, "in_standard_filter": 0, "label": "Reference Name", @@ -1379,7 +1379,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2017-02-17 16:41:05.429760", + "modified": "2017-02-21 04:57:33.141998", "modified_by": "Administrator", "module": "Core", "name": "Communication", diff --git a/frappe/email/doctype/contact/contact.json b/frappe/email/doctype/contact/contact.json index 94b70b88db..a7f7bc873a 100644 --- a/frappe/email/doctype/contact/contact.json +++ b/frappe/email/doctype/contact/contact.json @@ -81,7 +81,7 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, - "in_global_search": 1, + "in_global_search": 0, "in_list_view": 0, "in_standard_filter": 0, "label": "Last Name", @@ -554,7 +554,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2017-01-31 00:15:30.298287", + "modified": "2017-02-20 14:54:33.723052", "modified_by": "Administrator", "module": "Email", "name": "Contact", @@ -805,6 +805,7 @@ "quick_entry": 0, "read_only": 0, "read_only_onload": 0, + "show_name_in_global_search": 0, "sort_order": "ASC", "track_changes": 0, "track_seen": 0 diff --git a/frappe/public/css/desk.css b/frappe/public/css/desk.css index b5efcff616..2d3c8b42fb 100644 --- a/frappe/public/css/desk.css +++ b/frappe/public/css/desk.css @@ -687,8 +687,18 @@ fieldset[disabled] .form-control { padding: 0px; overflow-y: auto; } -.search-dialog .layout-side-section { - padding-left: 15px; +.search-dialog .layout-side-section .help-link { + padding-top: 20px; + text-transform: uppercase; +} +.search-dialog .layout-side-section .nav > li > a { + padding-left: 20px; +} +.search-dialog .results-area a { + color: #5E64FF; +} +.search-dialog .results-area .single-link a { + color: #36414c; } .search-dialog .module-section .back-link { margin-bottom: 20px; @@ -698,11 +708,19 @@ fieldset[disabled] .form-control { font-family: 'Octicons'; content: '\f0a4'; } -.search-dialog .dual-section .result a { - color: black; +.search-dialog .full-list .result { + border-bottom: 1px solid #d1d8dd; + margin-top: 10px; +} +.search-dialog .full-list .result .result-subtype{ + float: right; + margin-left: 10px; } -.search-dialog .dual-section .result a b { - color: #4e6161; +.search-dialog .full-list .section-head { + margin-bottom: 25px; +} +.search-dialog .dual-section .result-subtype { + display: none; } .search-dialog .result-status { margin-top: 30px; diff --git a/frappe/public/js/frappe/ui/toolbar/awesome_bar.js b/frappe/public/js/frappe/ui/toolbar/awesome_bar.js index 27212b3bed..2f4daf6946 100644 --- a/frappe/public/js/frappe/ui/toolbar/awesome_bar.js +++ b/frappe/public/js/frappe/ui/toolbar/awesome_bar.js @@ -12,17 +12,21 @@ frappe.search.AwesomeBar = Class.extend({ this.nav = new frappe.search.NavSearch(); this.help = new frappe.search.HelpSearch(); + this.options = []; + this.global_results = []; + var awesomplete = new Awesomplete(input, { minChars: 0, maxItems: 99, autoFirst: true, list: [], - filter: function (text, term) { - return true; + filter: function (text, term) { + return true; }, data: function (item, input) { - var label = item.label + "%%%" + item.value + "%%%" + - (item.description || "") + "%%%" + (item.index || ""); + var label = item.label + "%%%" + item.value + "%%%" + + (item.description || "") + "%%%" + (item.index || "") + + "%%%" + (item.type || "") + "%%%" + (item.prefix || ""); return { label: label, value: item.value @@ -31,9 +35,16 @@ frappe.search.AwesomeBar = Class.extend({ item: function(item, term) { var d = item; var parts = item.split("%%%"), - d = { label: parts[0], value: parts[1], description: parts[2] }; + d = { label: parts[0], value: parts[1], description: parts[2], + type: parts[4], prefix: parts[5]}; - var html = "" + __(d.label || d.value) + ""; + if(d.prefix) { + var html = "" + __((d.prefix + ' ' + d.label)) + ""; + } else if(d.type) { + var html = "" + __((d.label + ' ' + d.type)) + ""; + } else { + var html = "" + __(d.label || d.value) + ""; + } if(d.description && d.value!==d.description) { html += '
' + __(d.description) + ''; } @@ -42,29 +53,37 @@ frappe.search.AwesomeBar = Class.extend({ .html('

' + html + '

') .get(0); }, - sort: function(a, b) { + sort: function(a, b) { var a_index = a.split("%%%")[3]; var b_index = b.split("%%%")[3]; - return (a_index - b_index); + return (a_index - b_index); } }); $input.on("input", function(e) { + var value = e.target.value; + var txt = value.trim().replace(/\s\s+/g, ' '); + var last_space = txt.lastIndexOf(' '); + + if(txt && txt.length > 2) { + me.global.get_awesome_bar_options(txt.toLowerCase(), me); + } + var $this = $(this); clearTimeout($this.data('timeout')); $this.data('timeout', setTimeout(function(){ - var value = e.target.value; - var txt = strip(value); me.options = []; - if(txt) { - var keywords = strip(txt.toLowerCase()); - me.build_options(keywords); - if(me.options.length < 2) { - me.global.get_awesome_bar_options(keywords, me); + if(txt && txt.length > 2) { + if(last_space !== -1) { + me.set_specifics(txt.slice(0,last_space), txt.slice(last_space+1)); } + me.options = me.options.concat(me.build_options(txt)); + me.build_defaults(txt); + me.options = me.options.concat(me.global_results); } + me.make_calculator(txt); me.add_recent(txt || ""); me.add_help(); @@ -112,6 +131,7 @@ frappe.search.AwesomeBar = Class.extend({ } if(item.onclick) { + // frappe.new_doc(item.match, true); item.onclick(item.match); } else { var previous_hash = window.location.hash; @@ -135,7 +155,8 @@ frappe.search.AwesomeBar = Class.extend({ this.options.push({ label: __("Help on Search"), value: "Help on Search", - index: 20, + index: 50, + default: "Help", onclick: function() { var txt = '\
'+__("Make a new record")+''+ @@ -194,7 +215,8 @@ frappe.search.AwesomeBar = Class.extend({ out.label = match[0].bold(); out.value = match[0]; } - out.index = 10 + out.index = 29; + out.default = "Recent"; return out; }, true); }, @@ -231,45 +253,106 @@ frappe.search.AwesomeBar = Class.extend({ setup_recent: function() { this.recent = JSON.parse(frappe.boot.user.recent || "[]") || []; }, - - is_present: function(txt, item) { - ($.isArray(item)) ? _item = item[0] : _item = item; - _item = __(_item || '').toLowerCase().replace(/-/g, " "); - if(txt===_item || _item.indexOf(txt) !== -1) { - return item; + + fuzzy_search: function(txt, _item, index) { + item = __(_item || '').toLowerCase().replace(/-/g, " "); + + txt = txt.toLowerCase(); + + var ilen = item.length; + var tlen = txt.length; + var match_level1 = 0.5; + var match_level2 = 0.8; + var index = ((tlen/ilen) > match_level1) ? 24 : index; + var rendered_label = ""; + var i, j, skips = 0, mismatches = 0; + + if (tlen > ilen) { + return []; + } + if (item.indexOf(txt) !== -1) { + // prefer single words + index = (item.indexOf(' ') === -1) ? index-1 : index; + index = ((tlen/ilen) > match_level2) ? 21 : index; + + var regEx = new RegExp("("+ txt +")", "ig"); + rendered_label = _item.replace(regEx, '$1'); + + return [_item, index, rendered_label]; + } + outer: for (i = 0, j = 0; i < tlen; i++) { + var t_ch = txt.charCodeAt(i); + if(mismatches !== 0) skips++; + if(skips > 3) return []; + mismatches = 0; + while (j < ilen) { + var i_ch = item.charCodeAt(j); + if (i_ch === t_ch) { + var item_char = _item.charAt(j); + if(item_char === item_char.toLowerCase()){ + rendered_label += '' + txt.charAt(i) + ''; + } else { + rendered_label += '' + txt.charAt(i).toUpperCase() + ''; + } + j++; + continue outer; + } + mismatches++; + if(mismatches > 2) return []; + rendered_label += _item.charAt(j); + j++; + } + return []; } + rendered_label += _item.slice(j); + return [_item, index + 10, rendered_label]; + }, + + set_specifics: function(txt, end_txt) { + var me = this; + var results = this.build_options(txt); + results.forEach(function(r) { + if((r.type).toLowerCase().indexOf(end_txt.toLowerCase()) === 0) { + if(r.index < 25) { + r.index = 21; + } + me.options.push(r); + } + }); + }, + + build_defaults: function(txt) { + this.make_global_search(txt); + this.make_search_in_current(txt); + this.options = this.options.concat(this.make_search_in_list(txt)); }, - set_global_results: function(global_results){ - this.options = this.options.concat(global_results); + build_options: function(txt) { + return this.make_new_doc(txt).concat( + this.get_doctypes(txt), + this.get_reports(txt), + this.get_pages(txt), + this.get_modules(txt) + ); }, - build_options: function(txt) { - this.options = - this.make_global_search(txt).concat( - this.make_search_in_current(txt), - this.make_calculator(txt), - this.make_new_doc(txt), - this.make_search_in_list(txt), - this.get_doctypes(txt), - this.get_reports(txt), - this.get_pages(txt), - this.get_modules(txt) - ); + set_global_results: function(global_results, txt){ + this.global_results = this.global_results.concat(global_results); }, make_global_search: function(txt) { var me = this; - return [{ + this.options.push({ label: __("Search for '" + txt.bold() + "'"), value: __("Search for '" + txt + "'"), match: txt, - index: 5, + index: 22, + default: "Search", onclick: function() { me.search.search_dialog.show(); me.search.setup_search(txt, [me.global, me.nav, me.help]); } - }]; + }); }, make_search_in_current: function(txt) { @@ -280,17 +363,18 @@ frappe.search.AwesomeBar = Class.extend({ var search_field = meta.title_field || "name"; var options = {}; options[search_field] = ["like", "%" + txt + "%"]; - return [{ + this.options.push({ label: __('Find {0} in {1}', [txt.bold(), route[1].bold()]), value: __('Find {0} in {1}', [txt, route[1]]), route_options: options, - index: 10, + index: 23, onclick: function() { cur_list.refresh(); }, + default: "Current", match: txt - }]; - } else { return []; } + }); + } }, make_calculator: function(txt) { @@ -302,34 +386,37 @@ frappe.search.AwesomeBar = Class.extend({ try { var val = eval(txt); var formatted_value = __('{0} = {1}', [txt, (val + '').bold()]); - return [{ + this.options.push({ label: formatted_value, value: __('{0} = {1}', [txt, val]), match: val, - index: 10, + index: 24, + default: "Calculator", onclick: function() { msgprint(formatted_value, "Result"); } - }]; + }); } catch(e) { // pass } - } else { return []; } + } }, - make_new_doc: function(txt) { + make_search_in_list: function(txt) { var me = this; var out = []; - if(txt.split(" ")[0]==="new") { - frappe.boot.user.can_create.forEach(function (item) { - var target = me.is_present(txt.substr(4), item); + if(in_list(txt.split(" "), "in") && (txt.slice(-2) !== "in")) { + parts = txt.split(" in "); + frappe.boot.user.can_read.forEach(function (item) { + var target = me.fuzzy_search(parts[1], item, 21)[0]; if(target) { out.push({ - label: __("New {0}", [target.bold()]), - value: __("New {0}", [target]), - index: 10, - match: target, - onclick: function() { frappe.new_doc(target, true); } + label: __('Find {0} in {1}', [__(parts[0]).bold(), __(target).bold()]), + value: __('Find {0} in {1}', [__(parts[0]), __(target)]), + route_options: {"name": ["like", "%" + parts[0] + "%"]}, + index: 21, + default: "In List", + route: ["List", target] }); } }); @@ -337,20 +424,23 @@ frappe.search.AwesomeBar = Class.extend({ return out; }, - make_search_in_list: function(txt) { + make_new_doc: function(txt) { var me = this; var out = []; - if(in_list(txt.split(" "), "in")) { - parts = txt.split(" in "); - frappe.boot.user.can_read.forEach(function (item) { - target = me.is_present(parts[1], item); + if(txt.split(" ")[0]==="new") { + frappe.boot.user.can_create.forEach(function (item) { + var result = me.fuzzy_search(txt.substr(4), item, 21); + var target = result[0]; + var rendered_label = result[2]; if(target) { out.push({ - label: __('Find {0} in {1}', [__(parts[0]).bold(), __(target).bold()]), - value: __('Find {0} in {1}', [__(parts[0]), __(target)]), - route_options: {"name": ["like", "%" + parts[0] + "%"]}, - index: 10, - route: ["List", target] + label: rendered_label, + value: __("New {0}", [target]), + index: 21, + type: "New", + prefix: "New", + match: target, + onclick: function() { frappe.new_doc(target, true); } }); } }); @@ -358,36 +448,38 @@ frappe.search.AwesomeBar = Class.extend({ return out; }, - get_doctypes: function(txt) { + get_doctypes: function(txt) { var me = this; var out = []; - var target, index; + var result, target, index, rendered_label; var option = function(type, route) { return { - label: __("{0} " + type, [__(target).bold()]), + label: rendered_label, value: __(target), route: route, index: index, - match: target + match: target, + type: type } }; frappe.boot.user.can_read.forEach(function (item) { - target = me.is_present(txt, item); + result = me.fuzzy_search(txt, item, 25); + target = result[0]; + index = result[1]; + rendered_label = result[2]; if(target) { - var match_ratio = txt.length / item.length; - index = (match_ratio > 0.7) ? 10 : 12; - - // include 'making new' option - if(in_list(frappe.boot.user.can_create, target)) { - out.push({ - label: __("New {0}", [target.bold()]), - value: __("New {0}", [target]), - match: target, - index: 12, - onclick: function() { frappe.new_doc(target, true); } - }); - } + // include 'making new' option (not working) + // if(in_list(frappe.boot.user.can_create, target)) { + // out.push({ + // label: rendered_label, + // value: __("New {0}", [target]), + // index: index, + // type: "New", + // prefix: "New", + // onclick: function() { frappe.new_doc(target, true); } + // }); + // } if(in_list(frappe.boot.single_types, target)) { out.push(option("", ["Form", target, target])); @@ -395,7 +487,7 @@ frappe.search.AwesomeBar = Class.extend({ out.push(option("Tree", ["Tree", target])); } else { - out.push(option("List", ["List", target])); + out.push(option("List", ["List", target])); if(frappe.model.can_get_report(target)) { out.push(option("Report", ["Report", target])); } @@ -414,11 +506,12 @@ frappe.search.AwesomeBar = Class.extend({ var me = this; var out = []; Object.keys(frappe.boot.user.all_reports).forEach(function(item) { - var target = me.is_present(txt, item); + var result = me.fuzzy_search(txt, item, 26); + var target = result[0]; + var index = result[1]; + var rendered_label = result[2]; if(target) { var report = frappe.boot.user.all_reports[target]; - var match_ratio = txt.length / item.length; - var index = (match_ratio > 0.7) ? 10 : 13; var route = []; if(report.report_type == "Report Builder") route = ["Report", report.ref_doctype, target]; @@ -426,10 +519,12 @@ frappe.search.AwesomeBar = Class.extend({ route = ["query-report", target]; out.push({ - label: __("Report {0}", [__(target).bold()]), + label: rendered_label, value: __("Report {0}" , [__(target)]), match: txt, index: index, + type: "Report", + prefix: "Report", route: route }); } @@ -446,16 +541,19 @@ frappe.search.AwesomeBar = Class.extend({ p.name = name; }); Object.keys(this.pages).forEach(function(item) { - var target = me.is_present(txt, item); + var result = me.fuzzy_search(txt, item, 27); + var target = result[0]; + var index = result[1]; + var rendered_label = result[2]; if(target) { - var match_ratio = txt.length / item.length; - var index = (match_ratio > 0.7) ? 10 : 14; var page = me.pages[target]; out.push({ - label: __("Open {0}", [__(target).bold()]), + label: rendered_label, value: __("Open {0}", [__(target)]), match: txt, index: index, + type: "Page", + prefix: "Open", route: [page.route || page.name] }); } @@ -464,10 +562,12 @@ frappe.search.AwesomeBar = Class.extend({ var target = 'Calendar'; if(__('calendar').indexOf(txt.toLowerCase()) === 0) { out.push({ - label: __("Open {0}", [__(target).bold()]), + label: rendered_label, value: __("Open {0}", [__(target)]), route: [target, 'Event'], - index: 14, + index: 27, + type: "Calendar", + prefix: "Open", match: target }); } @@ -478,17 +578,20 @@ frappe.search.AwesomeBar = Class.extend({ var me = this; var out = []; Object.keys(frappe.modules).forEach(function(item) { - var target = me.is_present(txt, item); + var result = me.fuzzy_search(txt, item, 28); + var target = result[0]; + var index = result[1]; + var rendered_label = result[2]; if(target) { - var match_ratio = txt.length / item.length; - var index = (match_ratio > 0.7) ? 10 : 15; var module = frappe.modules[target]; if(module._doctype) return; ret = { - label: __("Open {0}", [__(target).bold()]), + label: rendered_label, value: __("Open {0}", [__(target)]), match: txt, - index: index + index: index, + type: "Module", + prefix: "Open" } if(module.link) { ret.route = [module.link]; diff --git a/frappe/public/js/frappe/ui/toolbar/search.html b/frappe/public/js/frappe/ui/toolbar/search.html index 9b7fddb7a7..b964b1c5f5 100644 --- a/frappe/public/js/frappe/ui/toolbar/search.html +++ b/frappe/public/js/frappe/ui/toolbar/search.html @@ -1,5 +1,7 @@
diff --git a/frappe/public/js/frappe/ui/toolbar/search.js b/frappe/public/js/frappe/ui/toolbar/search.js index b8d0b64866..44e2f62550 100644 --- a/frappe/public/js/frappe/ui/toolbar/search.js +++ b/frappe/public/js/frappe/ui/toolbar/search.js @@ -12,7 +12,7 @@ frappe.search.UnifiedSearch = Class.extend({ this.search_modal.addClass('search-dialog'); this.input = this.search_modal.find(".search-input"); - this.sidebar = this.search_modal.find(".search-sidebar"); + this.sidelist = this.search_modal.find(".search-sidelist"); this.results_area = this.search_modal.find(".results-area"); }, @@ -32,19 +32,19 @@ frappe.search.UnifiedSearch = Class.extend({ $this.data('timeout', setTimeout(function(){ var keywords = me.input.val(); me.reset(); - if(keywords.length > 1) { + if(keywords.length > 2) { me.build_results(keywords); } else { me.current_type = ''; } - }, 250)); + }, 600)); }); this.build_results(keywords); setTimeout(function() { me.input.select(); }, 500); }, reset: function() { - this.sidebar.empty(); + this.sidelist.empty(); this.results_area.empty(); }, @@ -59,7 +59,9 @@ frappe.search.UnifiedSearch = Class.extend({ render_results: function(results_obj, keywords){ var me = this; if(this.current === 0) { this.reset() } - this.sidebar.append(results_obj.sidelist); + results_obj.sidelist.forEach(function(list_item) { + me.sidelist.append(list_item); + }) this.results_area.find('.results-status').remove(); results_obj.sections.forEach(function(section) { me.summary.append(section); @@ -70,18 +72,35 @@ frappe.search.UnifiedSearch = Class.extend({ bind_events: function() { var me = this; - this.sidebar.find('.list-link').on('click', function() { - me.set_sidebar_link_action($(this)); + this.results_area.on('scroll', function() { + if(me.results_area.find('.all-results-link').length !== 0) { + return; + } + var r = me.results_area.find('.module-section')[1]; + me.results_area.find('.module-section').each(function() { + if(($(this).position().top < 120) && ($(this).position().top + $(this).height() > 120)) { + var types = $(this).attr('data-type').split(','); + me.sidelist.find('.list-link').removeClass('active'); + types.forEach(function(type) { + me.sidelist.find('*[data-category="'+ type +'"]').addClass('active'); + }); + } + }); + }); + this.sidelist.find('.list-link').on('click', function() { + me.set_sidelist_link_action($(this)); }); this.results_area.find('.section-more').on('click', function() { var type = $(this).attr('data-category'); - me.sidebar.find('*[data-category="'+ type +'"]').trigger('click'); + me.sidelist.find('*[data-category="'+ type +'"]').trigger('click'); }); }, - set_sidebar_link_action: function(link) { - this.sidebar.find(".list-link a").removeClass("disabled"); - link.find('a').addClass("disabled"); + set_sidelist_link_action: function(link) { + this.sidelist.find(".list-link").removeClass("active"); + this.sidelist.find(".list-link i").addClass("hide"); + link.addClass("active"); + link.find("i").removeClass("hide"); var type = link.attr('data-category'); this.results_area.empty().html(this.full_lists[type]); @@ -101,6 +120,9 @@ frappe.search.UnifiedSearch = Class.extend({ show_summary: function() { this.current_type = ''; + this.sidelist.find(".list-link i").addClass("hide"); + this.sidelist.find(".list-link").removeClass("active"); + this.sidelist.find(".list-link").first().addClass("active"); this.results_area.empty().html(this.summary); this.bind_events(); }, @@ -125,7 +147,7 @@ frappe.search.UnifiedSearch = Class.extend({ var no_of_results = this.results_area.find('.result').length; var no_of_results_cue = $('

'+ no_of_results +' results found

'); - this.results_area.find(".result:last").append(no_of_results_cue); + this.results_area.find(".more-results:last").append(no_of_results_cue); } this.results_area.find('.more-results.last').slideDown(200, function() { var height = me.results_area.find('.module-body').height() - 750; @@ -144,20 +166,20 @@ frappe.search.UnifiedSearch = Class.extend({ // More searches to go this.search_objects[this.current].build_results_object(this, keywords); } else { - // If there's only one link in sidebar, there's no summary (show its full list) - if(this.sidebar.find('.list-link').length === 1) { + // If there's only one link in sidelist, there's no summary (show its full list) + if(this.sidelist.find('.list-link').length === 1) { this.bind_events(); - this.sidebar.find('.list-link').trigger('click'); + this.sidelist.find('.list-link').trigger('click'); this.results_area.find('.all-results-link').hide(); - } else if (this.sidebar.find('.list-link').length === 0) { + } else if (this.sidelist.find('.list-link').length === 0) { this.results_area.html('

'+ 'No results found for: '+ "'"+ keywords +"'" +'

'); } else { var list_types = this.get_all_list_types(); if(list_types.indexOf(this.current_type) >= 0) { this.bind_events(); - this.sidebar.find('*[data-category="'+ this.current_type +'"]').trigger('click'); + this.sidelist.find('*[data-category="'+ this.current_type +'"]').trigger('click'); } else { this.show_summary(); } @@ -167,7 +189,7 @@ frappe.search.UnifiedSearch = Class.extend({ get_all_list_types: function() { var types = []; - this.sidebar.find('.list-link').each(function() { + this.sidelist.find('.list-link').each(function() { types.push($(this).attr('data-category')); }); return types; @@ -214,18 +236,16 @@ frappe.search.GlobalSearch = Class.extend({ make_sidelist: function() { var me = this; - var sidelist = $(''); - sidelist.append('
  • '+ me.search_type +'
  • '); + var sidelist = []; this.types.forEach(function(type) { - sidelist.append(me.make_sidelist_item(type)); + sidelist.push(me.make_sidelist_item(type)); }); - sidelist.append('
  • '); return sidelist; }, make_sidelist_item: function(type) { - var sidelist_item = ''; + var sidelist_item = ''; return $(__(sidelist_item, [this.search_type, type])); }, @@ -319,7 +339,7 @@ frappe.search.GlobalSearch = Class.extend({ make_section: function(type, results) { var me = this; - var results_section = $('
    '+ + var results_section = $('
    '+ '
    ' + '
    '+type+'
    ' + '
    '+ @@ -329,27 +349,53 @@ frappe.search.GlobalSearch = Class.extend({ results_col.append(me.make_result_item(type, result)); }); if(results.length > this.section_length) { - results_col.append('More...'); + results_col.append(''); + } return results_section; }, + make_result_subtypes_property: function(results) { + var compressed_results = []; + var labels = []; + results.forEach(function(r) { + if(labels.indexOf(r.label) === -1) { + labels.push(r.label); + } + }); + labels.forEach(function(l) { + var item_group = { + title: l, + subtypes: [] + }; + results.forEach(function(r) { + if (r.label === l) { + item_group.subtypes.push(r); + } + }); + compressed_results.push(item_group); + }); + return compressed_results; + }, + make_full_list: function(type, results, more) { var me = this; - var results_list = $('
    '+'
    ' + '' + '
    '+type+'
    ' + - '
    '+ - '
    '); + '
    '); + if(type === "Lists") { + results = this.make_result_subtypes_property(results); + } var results_col = results_list.find('.module-section-column'); results.forEach(function(result) { results_col.append(me.make_result_item(type, result)); }); if(more) { - results_col.append('More...'); + results_col.append(''); } return results_list; }, @@ -386,7 +432,6 @@ frappe.search.GlobalSearch = Class.extend({ }, get_awesome_bar_options: function(keywords, ref) { - var me = this; var doctypes = []; var current = 0; @@ -426,7 +471,7 @@ frappe.search.GlobalSearch = Class.extend({ if(current < doctypes.length) { get_results(); } else { - ref.set_global_results(results); + ref.set_global_results(results, keywords); } } } @@ -434,13 +479,13 @@ frappe.search.GlobalSearch = Class.extend({ }; var make_option = function(data) { - console.log("GS search", me.get_finds(data.content, keywords).slice(0,86) + '...'); return { label: __("{0}: {1}", [__(data.doctype).bold(), data.name]), value: __("{0}: {1}", [__(data.doctype), data.name]), route: ["Form", data.doctype, data.name], match: data.doctype, - index: 5, + index: 41, + default: "Global", description: me.get_finds(data.content, keywords).slice(0,86) + '...' } }; @@ -455,7 +500,6 @@ frappe.search.NavSearch = frappe.search.GlobalSearch.extend({ init: function() { this.search_type = 'Navigation'; }, - set_types: function() { var me = this; this.section_length = 4; @@ -520,9 +564,47 @@ frappe.search.NavSearch = frappe.search.GlobalSearch.extend({ }, make_result_item: function(type, result) { - var link_html = ''; + if(!result.subtypes) { + var link_html = ''; + return this.make_result_link(type, result, link_html); + + } else { + var result_div = $(''); + var button_html = '' + result.subtypes.forEach(function(s) { + if(["Gantt", "Report", "Calendar"].indexOf(s.type) !== -1) { + var button = $(__(button_html, [s.type])); + button.on('click', function() { + if(s.route_options) { + frappe.route_options = s.route_options; + } + frappe.set_route(s.route); + return false; + }); + result_div.append(button); + } else { + title_link_html = '{1}'; + var link = $(__(title_link_html, ['#', result.title + ' ' + s.type])); + link.on('click', function() { + if(s.route_options) { + frappe.route_options = s.route_options; + } + frappe.set_route(s.route); + return false; + }); + result_div.append(link); + } + }) + result_div.append($('

    ')); + return result_div; + } + + }, + + make_result_link: function(type, result, link_html) { if(!result.onclick) { var link = $(__(link_html, ['#', result.label])); link.on('click', function() { @@ -545,9 +627,14 @@ frappe.search.NavSearch = frappe.search.GlobalSearch.extend({ make_dual_sections: function() { this.dual_sections = []; - var section_html = '
    '; for(var i = 0; i < this.sections.length; i++) { - var results_section = $(section_html); + var types; + if(i+1 < this.types.length) { + types = this.types[i] + ',' + this.types[i+1]; + } else { + types = this.types[i]; + } + var results_section = $('
    '); for(var j = 0; j < 2 && i < this.sections.length; j++, i++){ results_section.append(this.sections[i]); } @@ -574,12 +661,15 @@ frappe.search.NavSearch = frappe.search.GlobalSearch.extend({ '
    '+type+'
    ' + '
    '+ '
    '); + if(type === "Lists") { + results = this.make_result_subtypes_property(results); + } results.slice(0, this.section_length).forEach(function(result) { results_column.append(me.make_result_item(type, result)); }); if(results.length > this.section_length) { - results_column.append('More...'); + results_column.append(''); } return results_column; } @@ -597,12 +687,11 @@ frappe.search.HelpSearch = frappe.search.GlobalSearch.extend({ }, make_sidelist: function() { - var sidelist = $(''); - var sidelist_item = ''; - sidelist.append(sidelist_item); - sidelist.append('
  • '); + var sidelist = []; + var sidelist_item = ''; + sidelist.push(sidelist_item); return sidelist; }, diff --git a/frappe/public/less/desk.less b/frappe/public/less/desk.less index bde269bf07..300120c7e2 100644 --- a/frappe/public/less/desk.less +++ b/frappe/public/less/desk.less @@ -563,12 +563,26 @@ textarea.form-control { } .layout-side-section { - padding-left: 15px; + .help-link { + padding-top: 20px; + text-transform: uppercase; + } + + .nav > li > a { + padding-left: 20px; + } + } + + .results-area { + a { + color: #5E64FF; + } + + .single-link a { + color: #36414c; + } } - // .results-area a { - // color: #5E64FF; - // } .module-section { .back-link { margin-bottom: 20px; @@ -580,13 +594,29 @@ textarea.form-control { content: '\f0a4'; } } - .dual-section .result a { - color: black; + + .full-list { + .result { + border-bottom: 1px solid #d1d8dd; + margin-top: 10px; + + .result-subtype{ + float: right; + margin-left: 10px; + } + } + + .section-head { + margin-bottom: 25px; + } } - .dual-section .result a b{ - color: #4e6161; + .dual-section { + .result-subtype{ + display: none; + } } + .result-status { margin-top: 30px; text-align: center; diff --git a/frappe/utils/global_search.py b/frappe/utils/global_search.py index 6226f3ad48..26637df799 100644 --- a/frappe/utils/global_search.py +++ b/frappe/utils/global_search.py @@ -148,4 +148,5 @@ def search_in_doctype(doctype, text, start, limit): doctype = %s AND match(content) against (%s IN BOOLEAN MODE) limit {start}, {limit}'''.format(start=start, limit=limit), (doctype, text), as_dict=True) - return results \ No newline at end of file + + return results