feat(aio): sort search results by area/title
Display area names in all caps Exclude results with no title because they don’t show & can’t be clicked. Should find these and give their docs a title.
This commit is contained in:
parent
6649743a2d
commit
dfc81c3dab
|
@ -42,30 +42,63 @@ describe('SearchResultsComponent', () => {
|
|||
|
||||
searchResults.next({ query: '', results: results});
|
||||
expect(currentAreas).toEqual([
|
||||
{ name: 'api', pages: [
|
||||
{ path: 'api/c', title: 'API C', type: 'class', keywords: '', titleWords: '' }
|
||||
] },
|
||||
{ name: 'guide', pages: [
|
||||
{ path: 'guide/a', title: 'Guide A', type: 'content', keywords: '', titleWords: '' },
|
||||
{ path: 'guide/b', title: 'Guide B', type: 'content', keywords: '', titleWords: '' },
|
||||
{ path: 'guide/b/c', title: 'Guide B - C', type: 'content', keywords: '', titleWords: '' }
|
||||
] },
|
||||
{ name: 'api', pages: [
|
||||
{ path: 'api/c', title: 'API C', type: 'class', keywords: '', titleWords: '' }
|
||||
] }
|
||||
]);
|
||||
});
|
||||
|
||||
it('should put search results with no containing folder into the default area (Other)', () => {
|
||||
it('should sort by title within sorted area', () => {
|
||||
const results = [
|
||||
{path: 'guide/b', title: 'Guide B', type: 'content', keywords: '', titleWords: '' },
|
||||
{path: 'guide/a', title: 'Guide A', type: 'content', keywords: '', titleWords: '' },
|
||||
{path: 'api/d', title: 'API D', type: 'class', keywords: '', titleWords: '' },
|
||||
{path: 'guide/a/c', title: 'Guide A - C', type: 'content', keywords: '', titleWords: '' },
|
||||
{path: 'api/c', title: 'API C', type: 'class', keywords: '', titleWords: '' },
|
||||
];
|
||||
|
||||
searchResults.next({ query: '', results: results });
|
||||
|
||||
expect(currentAreas).toEqual([
|
||||
{ name: 'api', pages: [
|
||||
{path: 'api/c', title: 'API C', type: 'class', keywords: '', titleWords: '' },
|
||||
{path: 'api/d', title: 'API D', type: 'class', keywords: '', titleWords: '' },
|
||||
] },
|
||||
{ name: 'guide', pages: [
|
||||
{path: 'guide/a', title: 'Guide A', type: 'content', keywords: '', titleWords: '' },
|
||||
{path: 'guide/a/c', title: 'Guide A - C', type: 'content', keywords: '', titleWords: '' },
|
||||
{path: 'guide/b', title: 'Guide B', type: 'content', keywords: '', titleWords: '' },
|
||||
] }
|
||||
]);
|
||||
});
|
||||
|
||||
it('should put search results with no containing folder into the default area (other)', () => {
|
||||
const results = [
|
||||
{path: 'news', title: 'News', type: 'marketing', keywords: '', titleWords: '' }
|
||||
];
|
||||
|
||||
searchResults.next({ query: '', results: results });
|
||||
expect(currentAreas).toEqual([
|
||||
{ name: 'Other', pages: [
|
||||
{ name: 'other', pages: [
|
||||
{ path: 'news', title: 'News', type: 'marketing', keywords: '', titleWords: '' }
|
||||
] }
|
||||
]);
|
||||
});
|
||||
|
||||
it('should omit search results with no title', () => {
|
||||
const results = [
|
||||
{path: 'news', title: undefined, type: 'marketing', keywords: '', titleWords: '' }
|
||||
];
|
||||
|
||||
searchResults.next({ query: '', results: results });
|
||||
expect(currentAreas).toEqual([]);
|
||||
});
|
||||
|
||||
it('should emit an "resultSelected" event when a search result anchor is clicked', () => {
|
||||
let selectedResult: SearchResult;
|
||||
component.resultSelected.subscribe((result: SearchResult) => selectedResult = result);
|
||||
|
|
|
@ -18,7 +18,7 @@ export interface SearchArea {
|
|||
})
|
||||
export class SearchResultsComponent implements OnInit {
|
||||
|
||||
readonly defaultArea = 'Other';
|
||||
readonly defaultArea = 'other';
|
||||
|
||||
showResults = false;
|
||||
|
||||
|
@ -57,11 +57,16 @@ export class SearchResultsComponent implements OnInit {
|
|||
this.showResults = true;
|
||||
const searchAreaMap = {};
|
||||
search.results.forEach(result => {
|
||||
if (!result.title) { return; } // bad data; should fix
|
||||
const areaName = this.computeAreaName(result) || this.defaultArea;
|
||||
const area = searchAreaMap[areaName] = searchAreaMap[areaName] || [];
|
||||
area.push(result);
|
||||
});
|
||||
return Object.keys(searchAreaMap).map(name => ({ name, pages: searchAreaMap[name] }));
|
||||
const keys = Object.keys(searchAreaMap).sort((l, r) => l > r ? 1 : -1);
|
||||
return keys.map(name => ({
|
||||
name,
|
||||
pages: searchAreaMap[name].sort(compareResults)
|
||||
}));
|
||||
}
|
||||
|
||||
// Split the search result path and use the top level folder, if there is one, as the area name.
|
||||
|
@ -70,3 +75,7 @@ export class SearchResultsComponent implements OnInit {
|
|||
return rest && areaName;
|
||||
}
|
||||
}
|
||||
|
||||
function compareResults(l: {title: string}, r: {title: string}) {
|
||||
return l.title.toUpperCase() > r.title.toUpperCase() ? 1 : -1;
|
||||
}
|
||||
|
|
|
@ -37,6 +37,7 @@ aio-search-results {
|
|||
h2 {
|
||||
font-size: 16px;
|
||||
margin: 10px 0px 5px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
a {
|
||||
font-size: 14px;
|
||||
|
@ -56,4 +57,4 @@ aio-search-results {
|
|||
width: 100%;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue