fix(aio): remove `...` separator from search results

An ellipsis was used to separate the most relevant search
results from the alphabetic list. The separator was confusing
because it was not clear what it represented.

This has been removed and the most relevant results are now
indicated by styling with a more bold font and a bit of whitespace
between them and the rest of the results.

To keep things consistent, if there are fewer than 5 results all the
results are now displayed as priorityPages.

Closes #17233
This commit is contained in:
Peter Bacon Darwin 2017-06-07 11:43:48 +01:00 committed by Alex Rickabaugh
parent bb46f54ad7
commit a4a2901294
4 changed files with 45 additions and 52 deletions

View File

@ -5,7 +5,7 @@
<ng-template #searchResults>
<h2 class="visually-hidden">Search Results</h2>
<div class="search-area" *ngFor="let area of searchAreas">
<h3>{{area.name}} ({{area.pages.length}})</h3>
<h3>{{area.name}} ({{area.pages.length + area.priorityPages.length}})</h3>
<ul class="priority-pages" >
<li class="search-page" *ngFor="let page of area.priorityPages">
<a class="search-result-item" href="{{ page.path }}" (click)="onResultSelected(page)">
@ -13,7 +13,6 @@
</a>
</li>
</ul>
<div class="more-items material-icons" *ngIf="area.priorityPages.length > 0">more_horiz</div>
<ul>
<li class="search-page" *ngFor="let page of area.pages">
<a class="search-result-item" href="{{ page.path }}" (click)="onResultSelected(page)">

View File

@ -33,6 +33,11 @@ describe('SearchResultsComponent', () => {
return take === undefined ? results : results.slice(0, take);
}
function compareTitle(l: {title: string}, r: {title: string}) {
return l.title.toUpperCase() > r.title.toUpperCase() ? 1 : -1;
}
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [ SearchResultsComponent ],
@ -54,13 +59,13 @@ describe('SearchResultsComponent', () => {
searchResults.next({ query: '', results: results});
expect(component.searchAreas).toEqual([
{ name: 'api', pages: [
{ name: 'api', priorityPages: [
{ path: 'api/d', title: 'API D', type: '', keywords: '', titleWords: '' }
], priorityPages: [] },
{ name: 'guide', pages: [
], pages: [] },
{ name: 'guide', priorityPages: [
{ path: 'guide/a', title: 'Guide A', type: '', keywords: '', titleWords: '' },
{ path: 'guide/b', title: 'Guide B', type: '', keywords: '', titleWords: '' },
], priorityPages: [] }
], pages: [] }
]);
});
@ -70,48 +75,35 @@ describe('SearchResultsComponent', () => {
{ path: 'tutorial/toh-pt1', title: 'Tutorial - part 1', type: '', keywords: '', titleWords: '' },
]});
expect(component.searchAreas).toEqual([
{ name: 'tutorial', pages: [
{ path: 'tutorial/toh-pt1', title: 'Tutorial - part 1', type: '', keywords: '', titleWords: '' },
{ name: 'tutorial', priorityPages: [
{ path: 'tutorial', title: 'Tutorial index', type: '', keywords: '', titleWords: '' },
], priorityPages: [] }
{ path: 'tutorial/toh-pt1', title: 'Tutorial - part 1', type: '', keywords: '', titleWords: '' },
], pages: [] }
]);
});
it('should sort by title within sorted area', () => {
const results = getTestResults(5);
searchResults.next({ query: '', results: results });
expect(component.searchAreas).toEqual([
{ name: 'api', pages: [
{ path: 'api/c', title: 'API C', type: '', keywords: '', titleWords: '' },
{ path: 'api/d', title: 'API D', type: '', keywords: '', titleWords: '' },
], priorityPages: [] },
{ name: 'guide', pages: [
{ path: 'guide/a', title: 'Guide A', type: '', keywords: '', titleWords: '' },
{ path: 'guide/a/c', title: 'Guide A - C', type: '', keywords: '', titleWords: '' },
{ path: 'guide/b', title: 'Guide B', type: '', keywords: '', titleWords: '' },
], priorityPages: [] }
]);
});
it('should put first 5 area results into priorityPages when more than 10 pages', () => {
it('should put first 5 results for each area into priorityPages', () => {
const results = getTestResults();
const sorted = results.slice().sort((l, r) => l.title > r.title ? 1 : -1);
const expected = [
{
name: 'api',
pages: sorted.filter(p => p.path.startsWith('api')),
priorityPages: []
},
{
name: 'guide',
pages: sorted.filter(p => p.path.startsWith('guide')),
priorityPages: results.filter(p => p.path.startsWith('guide')).slice(0, 5)
}
];
searchResults.next({ query: '', results: results });
expect(component.searchAreas).toEqual(expected);
expect(component.searchAreas[0].priorityPages).toEqual(results.filter(p => p.path.startsWith('api')).slice(0, 5));
expect(component.searchAreas[1].priorityPages).toEqual(results.filter(p => p.path.startsWith('guide')).slice(0, 5));
});
it('should put the nonPriorityPages into the pages array, sorted by title', () => {
const results = getTestResults();
searchResults.next({ query: '', results: results });
expect(component.searchAreas[0].pages).toEqual([]);
expect(component.searchAreas[1].pages).toEqual(results.filter(p => p.path.startsWith('guide')).slice(5).sort(compareTitle));
});
it('should put a total count in the header of each area of search results', () => {
const results = getTestResults();
searchResults.next({ query: '', results: results });
fixture.detectChanges();
const headers = fixture.debugElement.queryAll(By.css('h3'));
expect(headers.length).toEqual(2);
expect(headers[0].nativeElement.textContent).toContain('(2)');
expect(headers[1].nativeElement.textContent).toContain('(13)');
});
it('should put search results with no containing folder into the default area (other)', () => {
@ -121,9 +113,9 @@ describe('SearchResultsComponent', () => {
searchResults.next({ query: '', results: results });
expect(component.searchAreas).toEqual([
{ name: 'other', pages: [
{ name: 'other', priorityPages: [
{ path: 'news', title: 'News', type: 'marketing', keywords: '', titleWords: '' }
], priorityPages: [] }
], pages: [] }
]);
});

View File

@ -60,8 +60,10 @@ export class SearchResultsComponent implements OnInit, OnDestroy {
});
const keys = Object.keys(searchAreaMap).sort((l, r) => l > r ? 1 : -1);
return keys.map(name => {
let pages = searchAreaMap[name];
const priorityPages = pages.length > 10 ? searchAreaMap[name].slice(0, 5) : [];
let pages: SearchResult[] = searchAreaMap[name];
// Extract the top 5 most relevant results as priorityPages
const priorityPages = pages.splice(0, 5);
pages = pages.sort(compareResults);
return { name, pages, priorityPages };
});

View File

@ -55,7 +55,7 @@ aio-search-results {
font-size: 14px;
color: $lightgray;
text-decoration: none;
font-weight: 300;
font-weight: normal;
&:hover {
color: $white;
}
@ -68,11 +68,11 @@ aio-search-results {
}
}
.more-items {
content: 'more_horiz';
font-size: 20px;
color: $mediumgray;
padding: 0;
.priority-pages {
padding: 0.5rem 0;
a {
font-weight: bold;
}
}
@include bp(tiny) {