fix(docs-infra): merge `docs` with `guide` and `start` with `tutorial` in search-results (#40881)

Previously, the `docs.md` guide was appearing under "OTHER" in search
results and the results for the `/start*` tutorial pages were appearing
under "START".

This commit changes this so that `docs.md` appears under "GUIDES" and
`/start*` appear under "TUTORIALS", since that is where they belong
conceptually.

It also changes the header of the guides search-area from "GUIDE" to
"GUIDES" and that of tutorials from "TUTORIAL" to "TUTORIALS".

Before: ![search-results areas before][1]
After: ![search-results areas after][2]

[1]: https://user-images.githubusercontent.com/8604205/107811568-0ce80480-6d77-11eb-8652-e7a947c36e63.png
[2]: https://user-images.githubusercontent.com/8604205/107811569-0eb1c800-6d77-11eb-9a69-0000a3703c8a.png

PR Close #40881
This commit is contained in:
George Kalpakas 2021-02-18 18:42:46 +02:00 committed by atscott
parent 4fac4a8880
commit 64efe38d66
2 changed files with 28 additions and 13 deletions

View File

@ -71,23 +71,33 @@ describe('SearchResultsComponent', () => {
}); });
it('should map the search results into groups based on their containing folder', () => { it('should map the search results into groups based on their containing folder', () => {
setSearchResults('', [guideA, apiD, guideB]); const startA = { path: 'start/a', title: 'Start A', deprecated: false, keywords: '', titleWords: '', type: '', topics: '' };
const tutorialA = { path: 'tutorial/a', title: 'Tutorial A', deprecated: false, keywords: '', titleWords: '', type: '', topics: '' };
setSearchResults('', [guideA, apiD, guideB, startA, tutorialA]);
expect(component.searchAreas).toEqual([ expect(component.searchAreas).toEqual([
{ name: 'api', priorityPages: [apiD], pages: [] }, { name: 'api', priorityPages: [apiD], pages: [] },
{ name: 'guide', priorityPages: [guideA, guideB], pages: [] } { name: 'guides', priorityPages: [guideA, guideB], pages: [] },
{ name: 'tutorials', priorityPages: [startA, tutorialA], pages: [] },
]); ]);
}); });
it('should special case results that are top level folders', () => { it('should special case results that are top level folders', () => {
setSearchResults('', [ setSearchResults('', [
{ path: 'docs', title: 'Docs introduction', type: '', keywords: '', titleWords: '', deprecated: false, topics: '' },
{ path: 'start', title: 'Getting started', type: '', keywords: '', titleWords: '', deprecated: false, topics: '' },
{ path: 'tutorial', title: 'Tutorial index', type: '', keywords: '', titleWords: '', deprecated: false, topics: '' }, { path: 'tutorial', title: 'Tutorial index', type: '', keywords: '', titleWords: '', deprecated: false, topics: '' },
{ path: 'tutorial/toh-pt1', title: 'Tutorial - part 1', type: '', keywords: '', titleWords: '', deprecated: false, topics: '' }, { path: 'tutorial/toh-pt1', title: 'Tutorial - part 1', type: '', keywords: '', titleWords: '', deprecated: false, topics: '' },
]); ]);
expect(component.searchAreas).toEqual([ expect(component.searchAreas).toEqual([
{ name: 'tutorial', priorityPages: [ { name: 'guides', priorityPages: [
{ path: 'docs', title: 'Docs introduction', type: '', keywords: '', titleWords: '', deprecated: false, topics: '' },
], pages: [] },
{ name: 'tutorials', priorityPages: [
{ path: 'start', title: 'Getting started', type: '', keywords: '', titleWords: '', deprecated: false, topics: '' },
{ path: 'tutorial', title: 'Tutorial index', type: '', keywords: '', titleWords: '', deprecated: false, topics: '' }, { path: 'tutorial', title: 'Tutorial index', type: '', keywords: '', titleWords: '', deprecated: false, topics: '' },
{ path: 'tutorial/toh-pt1', title: 'Tutorial - part 1', type: '', keywords: '', titleWords: '', deprecated: false, topics: '' }, { path: 'tutorial/toh-pt1', title: 'Tutorial - part 1', type: '', keywords: '', titleWords: '', deprecated: false, topics: '' },
], pages: [] } ], pages: [] },
]); ]);
}); });

View File

@ -28,9 +28,17 @@ export class SearchResultsComponent implements OnChanges {
@Output() @Output()
resultSelected = new EventEmitter<SearchResult>(); resultSelected = new EventEmitter<SearchResult>();
readonly defaultArea = 'other';
searchState: SearchState = SearchState.InProgress; searchState: SearchState = SearchState.InProgress;
readonly topLevelFolders = ['api', 'cli', 'errors', 'guide', 'start', 'tutorial']; readonly defaultArea = 'other';
readonly folderToAreaMap: Record<string, string> = {
api: 'api',
cli: 'cli',
docs: 'guides',
errors: 'errors',
guide: 'guides',
start: 'tutorials',
tutorial: 'tutorials',
};
searchAreas: SearchArea[] = []; searchAreas: SearchArea[] = [];
ngOnChanges() { ngOnChanges() {
@ -59,7 +67,7 @@ export class SearchResultsComponent implements OnChanges {
const searchAreaMap: { [key: string]: SearchResult[] } = {}; const searchAreaMap: { [key: string]: SearchResult[] } = {};
search.results.forEach(result => { search.results.forEach(result => {
if (!result.title) { return; } // bad data; should fix if (!result.title) { return; } // bad data; should fix
const areaName = this.computeAreaName(result) || this.defaultArea; const areaName = this.computeAreaName(result);
const area = searchAreaMap[areaName] = searchAreaMap[areaName] || []; const area = searchAreaMap[areaName] = searchAreaMap[areaName] || [];
area.push(result); area.push(result);
}); });
@ -75,12 +83,9 @@ export class SearchResultsComponent implements OnChanges {
} }
// 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.
private computeAreaName(result: SearchResult) { private computeAreaName(result: SearchResult): string {
if (this.topLevelFolders.indexOf(result.path) !== -1) { const [folder] = result.path.split('/', 1);
return result.path; return this.folderToAreaMap[folder] ?? this.defaultArea;
}
const [areaName, rest] = result.path.split('/', 2);
return rest && areaName;
} }
} }