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});
|
searchResults.next({ query: '', results: results});
|
||||||
expect(currentAreas).toEqual([
|
expect(currentAreas).toEqual([
|
||||||
|
{ name: 'api', pages: [
|
||||||
|
{ path: 'api/c', title: 'API C', type: 'class', keywords: '', titleWords: '' }
|
||||||
|
] },
|
||||||
{ name: 'guide', pages: [
|
{ name: 'guide', pages: [
|
||||||
{ path: 'guide/a', title: 'Guide A', type: 'content', keywords: '', titleWords: '' },
|
{ path: 'guide/a', title: 'Guide A', type: 'content', keywords: '', titleWords: '' },
|
||||||
{ path: 'guide/b', title: 'Guide B', 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: '' }
|
{ 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 = [
|
const results = [
|
||||||
{path: 'news', title: 'News', type: 'marketing', keywords: '', titleWords: '' }
|
{path: 'news', title: 'News', type: 'marketing', keywords: '', titleWords: '' }
|
||||||
];
|
];
|
||||||
|
|
||||||
searchResults.next({ query: '', results: results });
|
searchResults.next({ query: '', results: results });
|
||||||
expect(currentAreas).toEqual([
|
expect(currentAreas).toEqual([
|
||||||
{ name: 'Other', pages: [
|
{ name: 'other', pages: [
|
||||||
{ path: 'news', title: 'News', type: 'marketing', keywords: '', titleWords: '' }
|
{ 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', () => {
|
it('should emit an "resultSelected" event when a search result anchor is clicked', () => {
|
||||||
let selectedResult: SearchResult;
|
let selectedResult: SearchResult;
|
||||||
component.resultSelected.subscribe((result: SearchResult) => selectedResult = result);
|
component.resultSelected.subscribe((result: SearchResult) => selectedResult = result);
|
||||||
|
|
|
@ -18,7 +18,7 @@ export interface SearchArea {
|
||||||
})
|
})
|
||||||
export class SearchResultsComponent implements OnInit {
|
export class SearchResultsComponent implements OnInit {
|
||||||
|
|
||||||
readonly defaultArea = 'Other';
|
readonly defaultArea = 'other';
|
||||||
|
|
||||||
showResults = false;
|
showResults = false;
|
||||||
|
|
||||||
|
@ -57,11 +57,16 @@ export class SearchResultsComponent implements OnInit {
|
||||||
this.showResults = true;
|
this.showResults = true;
|
||||||
const searchAreaMap = {};
|
const searchAreaMap = {};
|
||||||
search.results.forEach(result => {
|
search.results.forEach(result => {
|
||||||
|
if (!result.title) { return; } // bad data; should fix
|
||||||
const areaName = this.computeAreaName(result) || this.defaultArea;
|
const areaName = this.computeAreaName(result) || this.defaultArea;
|
||||||
const area = searchAreaMap[areaName] = searchAreaMap[areaName] || [];
|
const area = searchAreaMap[areaName] = searchAreaMap[areaName] || [];
|
||||||
area.push(result);
|
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.
|
// 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;
|
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 {
|
h2 {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
margin: 10px 0px 5px;
|
margin: 10px 0px 5px;
|
||||||
|
text-transform: uppercase;
|
||||||
}
|
}
|
||||||
a {
|
a {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
|
@ -56,4 +57,4 @@ aio-search-results {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue