diff --git a/app/assets/javascripts/discourse/lib/search.js.es6 b/app/assets/javascripts/discourse/lib/search.js.es6 index 32c226228d4d45..28380ddc93d26d 100644 --- a/app/assets/javascripts/discourse/lib/search.js.es6 +++ b/app/assets/javascripts/discourse/lib/search.js.es6 @@ -46,11 +46,26 @@ export function translateResults(results, opts) { results.groups = results.groups .map(group => { - const groupName = Handlebars.Utils.escapeExpression(group.name); + const name = Handlebars.Utils.escapeExpression(group.name); + const fullName = Handlebars.Utils.escapeExpression( + group.full_name || group.display_name + ); + const flairUrl = Ember.isEmpty(group.flair_url) + ? null + : Handlebars.Utils.escapeExpression(group.flair_url); + const flairColor = Handlebars.Utils.escapeExpression(group.flair_color); + const flairBgColor = Handlebars.Utils.escapeExpression( + group.flair_bg_color + ); + return { id: group.id, - name: groupName, - url: Discourse.getURL(`/g/${groupName}`) + flairUrl, + flairColor, + flairBgColor, + fullName, + name, + url: Discourse.getURL(`/g/${name}`) }; }) .compact(); @@ -72,10 +87,10 @@ export function translateResults(results, opts) { if (groupedSearchResult) { [ ["topic", "posts"], - ["category", "categories"], - ["tag", "tags"], ["user", "users"], - ["group", "groups"] + ["group", "groups"], + ["category", "categories"], + ["tag", "tags"] ].forEach(function(pair) { const type = pair[0]; const name = pair[1]; diff --git a/app/assets/javascripts/discourse/widgets/search-menu-results.js.es6 b/app/assets/javascripts/discourse/widgets/search-menu-results.js.es6 index 69ecf7ace58a08..b6acdf858733e6 100644 --- a/app/assets/javascripts/discourse/widgets/search-menu-results.js.es6 +++ b/app/assets/javascripts/discourse/widgets/search-menu-results.js.es6 @@ -90,16 +90,48 @@ createSearchResult({ } }); +createSearchResult({ + type: "group", + linkField: "url", + builder(group) { + const fullName = escapeExpression(group.fullName); + const name = escapeExpression(group.name); + const groupNames = [h("span.name", fullName || name)]; + + if (fullName) { + groupNames.push(h("span.slug", name)); + } + + let avatarFlair; + if (group.flairUrl) { + avatarFlair = this.attach("avatar-flair", { + primary_group_flair_url: group.flairUrl, + primary_group_flair_bg_color: group.flairBgColor, + primary_group_flair_color: group.flairColor, + primary_group_name: name + }); + } else { + avatarFlair = iconNode("users"); + } + + const groupResultContents = [avatarFlair, h("div.group-names", groupNames)]; + + return h("div.group-result", groupResultContents); + } +}); + createSearchResult({ type: "user", linkField: "path", builder(u) { - const userTitles = [h("span.username", formatUsername(u.username))]; + const userTitles = []; if (u.name) { userTitles.push(h("span.name", u.name)); } + userTitles.push(h("span.username", formatUsername(u.username))); + const userResultContents = [ avatarImg("small", { template: u.avatar_template, @@ -112,21 +144,6 @@ createSearchResult({ } }); -createSearchResult({ - type: "group", - linkField: "url", - builder(group) { - const groupName = escapeExpression(group.name); - return h( - "span", - { - className: `group-${groupName} discourse-group` - }, - [iconNode("users"), h("span", groupName)] - ); - } -}); - createSearchResult({ type: "topic", linkField: "url", @@ -174,19 +191,12 @@ createWidget("search-menu-results", { const resultTypes = results.resultTypes || []; const mainResultsContent = []; - const classificationContents = []; - const otherContents = []; - const assignContainer = (type, node) => { - if (["topic"].includes(type)) { - mainResultsContent.push(node); - } else if (["category", "tag"].includes(type)) { - classificationContents.push(node); - } else { - otherContents.push(node); - } - }; + const usersAndGroups = []; + const categoriesAndTags = []; + const usersAndGroupsMore = []; + const categoriesAndTagsMore = []; - resultTypes.forEach(rt => { + const buildMoreNode = result => { const more = []; const moreArgs = { @@ -194,23 +204,45 @@ createWidget("search-menu-results", { contents: () => [I18n.t("more"), "..."] }; - if (rt.moreUrl) { + if (result.moreUrl) { more.push( - this.attach("link", $.extend(moreArgs, { href: rt.moreUrl })) + this.attach("link", $.extend(moreArgs, { href: result.moreUrl })) ); - } else if (rt.more) { + } else if (result.more) { more.push( this.attach( "link", $.extend(moreArgs, { action: "moreOfType", - actionParam: rt.type, + actionParam: result.type, className: "filter filter-type" }) ) ); } + if (more.length) { + return more; + } + }; + + const assignContainer = (result, node) => { + if (["topic"].includes(result.type)) { + mainResultsContent.push(node); + } + + if (["user", "group"].includes(result.type)) { + usersAndGroups.push(node); + usersAndGroupsMore.push(buildMoreNode(result)); + } + + if (["category", "tag"].includes(result.type)) { + categoriesAndTags.push(node); + categoriesAndTagsMore.push(buildMoreNode(result)); + } + }; + + resultTypes.forEach(rt => { const resultNodeContents = [ this.attach(rt.componentName, { searchContextEnabled: attrs.searchContextEnabled, @@ -220,14 +252,14 @@ createWidget("search-menu-results", { }) ]; - if (more.length) { - resultNodeContents.push(h("div.show-more", more)); + if (["topic"].includes(rt.type)) { + const more = buildMoreNode(rt); + if (more) { + resultNodeContents.push(h("div.show-more", more)); + } } - assignContainer( - rt.type, - h(`div.${rt.componentName}`, resultNodeContents) - ); + assignContainer(rt, h(`div.${rt.componentName}`, resultNodeContents)); }); const content = []; @@ -236,27 +268,25 @@ createWidget("search-menu-results", { content.push(h("div.main-results", mainResultsContent)); } - if (classificationContents.length || otherContents.length) { - const secondaryResultsContent = []; + if (usersAndGroups.length || categoriesAndTags.length) { + const secondaryResultsContents = []; - if (classificationContents.length) { - secondaryResultsContent.push( - h("div.classification-results", classificationContents) - ); - } + secondaryResultsContents.push(usersAndGroups); + secondaryResultsContents.push(usersAndGroupsMore); - if (otherContents.length) { - secondaryResultsContent.push(h("div.other-results", otherContents)); + if (usersAndGroups.length && categoriesAndTags.length) { + secondaryResultsContents.push(h("div.separator")); } - content.push( - h( - `div.secondary-results${ - mainResultsContent.length ? "" : ".no-main-results" - }`, - secondaryResultsContent - ) + secondaryResultsContents.push(categoriesAndTags); + secondaryResultsContents.push(categoriesAndTagsMore); + + const secondaryResults = h( + "div.secondary-results", + secondaryResultsContents ); + + content.push(secondaryResults); } return content; diff --git a/app/assets/stylesheets/common/base/search-menu.scss b/app/assets/stylesheets/common/base/search-menu.scss index a38e5b168ecda3..6da0cdf298c4f3 100644 --- a/app/assets/stylesheets/common/base/search-menu.scss +++ b/app/assets/stylesheets/common/base/search-menu.scss @@ -76,26 +76,22 @@ flex-direction: column; flex: 1 1 auto; - .classification-results { - border-bottom: 1px solid $primary-low; + .separator { margin-bottom: 1em; - padding-bottom: 1em; - } - - .search-result-category { + margin-top: 1em; + height: 1px; + background: $primary-low; } .search-result-tag { - .list { - .item { - display: inline-flex; + .discourse-tag { + font-size: $font-down-1; + } + } - .widget-link.search-link { - display: inline; - font-size: $font-0; - padding: 5px; - } - } + .search-result-category { + .widget-link { + margin-bottom: 0; } } @@ -108,12 +104,71 @@ } } - .discourse-group { - display: inline-block; - word-break: break-all; + .group-result { + display: flex; + align-items: center; + + .d-icon, + .avatar-flair { + min-width: 25px; + margin-right: 0.5em; + + .d-icon { + margin-right: 0; + } + } - .d-icon { - margin-right: s(1); + .avatar-flair-image { + background-repeat: no-repeat; + background-size: 100% 100%; + min-height: 25px; + } + + .group-names { + display: flex; + flex-direction: column; + overflow: auto; + line-height: $line-height-medium; + + &:hover { + .name, + .slug { + color: $primary-high; + } + } + + .name, + .slug { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + + .name { + font-weight: 700; + } + + .slug { + font-size: $font-down-1; + color: $primary-high; + } + } + } + } + + .search-result-category, + .search-result-user, + .search-result-group, + .search-result-tag { + .list { + display: block; + + .item { + .widget-link.search-link { + flex: 1; + font-size: $font-0; + padding: 5px; + } } } } @@ -145,29 +200,17 @@ .username { color: dark-light-choose($primary-high, $secondary-low); - font-size: $font-0; - font-weight: 700; + font-size: $font-down-1; } .name { color: dark-light-choose($primary-high, $secondary-low); - font-size: $font-down-1; + font-size: $font-0; + font-weight: 700; } } } } - - &.no-main-results .search-result-user { - .user-titles { - flex-direction: row; - align-items: center; - - .name { - margin: 0 0 0 0.25em; - font-size: $font-0; - } - } - } } .show-more { diff --git a/lib/search.rb b/lib/search.rb index 56ebc31a431ead..3ffbda872fb1b1 100644 --- a/lib/search.rb +++ b/lib/search.rb @@ -687,7 +687,7 @@ def user_search def groups_search groups = Group .visible_groups(@guardian.user, "name ASC", include_everyone: false) - .where("groups.name ILIKE ?", "%#{@term}%") + .where("name ILIKE :term OR full_name ILIKE :term", term: "%#{@term}%") groups.each { |group| @results.add(group) } end