Skip to content

Commit

Permalink
feat: lazy load component sidenav
Browse files Browse the repository at this point in the history
- update a couple services to use `providedIn: 'root'`

Relates to #176
  • Loading branch information
Splaktar committed Jan 14, 2020
1 parent 7a099d4 commit 0d08b11
Show file tree
Hide file tree
Showing 14 changed files with 94 additions and 107 deletions.
44 changes: 1 addition & 43 deletions src/app/app-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,67 +2,25 @@ import {BrowserModule} from '@angular/platform-browser';
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
import {NgModule} from '@angular/core';
import {LocationStrategy, PathLocationStrategy} from '@angular/common';
import {FormsModule} from '@angular/forms';
import {RouterModule} from '@angular/router';
import {ExampleModule} from '@angular/components-examples';

import {MaterialDocsApp} from './material-docs-app';
import {MATERIAL_DOCS_ROUTES} from './routes';
import {ComponentListModule} from './pages/component-list';
import {ComponentViewerModule} from './pages/component-viewer/component-viewer';
import {ComponentCategoryListModule} from './pages/component-category-list/component-category-list';
import {ComponentSidenavModule} from './pages/component-sidenav/component-sidenav';
import {FooterModule} from './shared/footer/footer';
import {ComponentPageTitle} from './pages/page-title/page-title';
import {ComponentHeaderModule} from './pages/component-page-header/component-page-header';
import {StyleManager} from './shared/style-manager';
import {SvgViewerModule} from './shared/svg-viewer/svg-viewer';
import {ThemePickerModule} from './shared/theme-picker';
import {StackBlitzButtonModule} from './shared/stack-blitz';
import {NavBarModule} from './shared/navbar';
import {ThemeStorage} from './shared/theme-picker/theme-storage/theme-storage';
import {GuideItems} from './shared/guide-items/guide-items';
import {DocumentationItems} from './shared/documentation-items/documentation-items';
import {DocViewerModule} from './shared/doc-viewer/doc-viewer-module';
import {CanActivateComponentSidenav} from './pages/component-sidenav/component-sidenav-can-load-guard';
import {HttpClientModule} from '@angular/common/http';
import {GaService} from './shared/ga/ga';

@NgModule({
imports: [
BrowserModule,
BrowserAnimationsModule,
ExampleModule,
FormsModule,
HttpClientModule,
RouterModule.forRoot(MATERIAL_DOCS_ROUTES, {
scrollPositionRestoration: 'enabled',
anchorScrolling: 'enabled',
relativeLinkResolution: 'corrected'
}),
ComponentCategoryListModule,
ComponentHeaderModule,
ComponentListModule,
ComponentSidenavModule,
ComponentViewerModule,
DocViewerModule,
FooterModule,
NavBarModule,
StackBlitzButtonModule,
SvgViewerModule,
ThemePickerModule,
],
declarations: [MaterialDocsApp],
providers: [
ComponentPageTitle,
DocumentationItems,
GaService,
GuideItems,
StyleManager,
ThemeStorage,
CanActivateComponentSidenav,
{provide: LocationStrategy, useClass: PathLocationStrategy},
],
providers: [{provide: LocationStrategy, useClass: PathLocationStrategy}],
bootstrap: [MaterialDocsApp],
})
export class AppModule {}
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@ export class ComponentCategoryList implements OnInit, OnDestroy {
}

@NgModule({
imports: [SvgViewerModule, MatCardModule, CommonModule, RouterModule],
imports: [CommonModule, SvgViewerModule, MatCardModule, RouterModule],
exports: [ComponentCategoryList],
declarations: [ComponentCategoryList],
providers: [DocumentationItems, ComponentPageTitle],
providers: [DocumentationItems],
})
export class ComponentCategoryListModule { }
4 changes: 2 additions & 2 deletions src/app/pages/component-list/component-list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ export class ComponentList {
}

@NgModule({
imports: [SvgViewerModule, RouterModule, CommonModule, MatCardModule],
imports: [CommonModule, SvgViewerModule, MatCardModule, RouterModule],
exports: [ComponentList],
declarations: [ComponentList],
providers: [DocumentationItems, ComponentPageTitle],
providers: [DocumentationItems],
})
export class ComponentListModule { }
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,5 @@ export class ComponentPageHeader {
imports: [MatButtonModule, MatIconModule, NavigationFocusModule],
exports: [ComponentPageHeader],
declarations: [ComponentPageHeader],
providers: [ComponentPageTitle],
})
export class ComponentHeaderModule { }
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,17 @@ import {CanActivate, ActivatedRouteSnapshot, Router, RouterStateSnapshot} from '
import {SECTIONS} from '../../shared/documentation-items/documentation-items';

/**
* Guard to determine if the sidenav can load, based on if the section exists in documentation
* Guard to determine if the sidenav can load, based on whether the section exists in documentation
* items.
*/
@Injectable()
@Injectable({providedIn: 'root'})
export class CanActivateComponentSidenav implements CanActivate {
constructor(private router: Router) {}

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
// Searches if the section defined the base UrlSegment is a valid section from the documentation
// items. If found, returns true to allow activation, otherwise blocks activation and navigates
// to '/'.
// Searches if the section defined in the base UrlSegment is a valid section from the
// documentation items. If found, returns true to allow activation, otherwise blocks activation
// and navigates to '/'.
const sectionFound = Object.keys(SECTIONS).find(
(val => val.toLowerCase() === route.url[0].path.toLowerCase()));
if (sectionFound) { return true; }
Expand Down
80 changes: 68 additions & 12 deletions src/app/pages/component-sidenav/component-sidenav.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,42 @@
import {
Component, Input, NgZone, ViewEncapsulation, ViewChild, OnInit, NgModule, OnDestroy
Component,
Input,
NgModule,
NgZone,
OnDestroy,
OnInit,
ViewChild,
ViewEncapsulation
} from '@angular/core';
import {DocumentationItems} from '../../shared/documentation-items/documentation-items';
import {MatIconModule} from '@angular/material/icon';
import {MatSidenav, MatSidenavModule} from '@angular/material/sidenav';
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
import {ActivatedRoute, Params, Router, RouterModule} from '@angular/router';
import {ActivatedRoute, Params, Router, RouterModule, Routes} from '@angular/router';
import {CommonModule} from '@angular/common';
import {ComponentHeaderModule} from '../component-page-header/component-page-header';
import {FooterModule} from '../../shared/footer/footer';
import {Observable, Subject, combineLatest} from 'rxjs';
import {switchMap, takeUntil, startWith, map} from 'rxjs/operators';
import {trigger, animate, state, style, transition} from '@angular/animations';
import {combineLatest, Observable, Subject} from 'rxjs';
import {map, startWith, switchMap, takeUntil} from 'rxjs/operators';
import {animate, state, style, transition, trigger} from '@angular/animations';
import {CdkAccordionModule} from '@angular/cdk/accordion';
import {BreakpointObserver} from '@angular/cdk/layout';
import {
ComponentCategoryList,
ComponentCategoryListModule
} from '../component-category-list/component-category-list';
import {ComponentList, ComponentListModule} from '../component-list';
import {
ComponentApi,
ComponentExamples,
ComponentOverview,
ComponentViewer, ComponentViewerModule
} from '../component-viewer/component-viewer';
import {DocViewerModule} from '../../shared/doc-viewer/doc-viewer-module';
import {FormsModule} from '@angular/forms';
import {HttpClientModule} from '@angular/common/http';
import {StackBlitzButtonModule} from '../../shared/stack-blitz';
import {SvgViewerModule} from '../../shared/svg-viewer/svg-viewer';
import {ExampleModule} from '@angular/components-examples';

const SMALL_WIDTH_BREAKPOINT = 720;

Expand Down Expand Up @@ -56,7 +79,6 @@ export class ComponentSidenav implements OnInit {
],
})
export class ComponentNav implements OnInit, OnDestroy {

@Input() params: Observable<Params>;
expansions: {[key: string]: boolean} = {};
private _onDestroy = new Subject<void>();
Expand Down Expand Up @@ -113,20 +135,54 @@ export class ComponentNav implements OnInit, OnDestroy {
getExpanded(category: string): boolean {
return this.expansions[category] === undefined ? true : this.expansions[category];
}

}

const routes: Routes = [ {
path : '',
component : ComponentSidenav,
children : [
{path : '', redirectTo : 'categories', pathMatch : 'full'},
{path : 'component/:id', redirectTo : ':id', pathMatch : 'full'},
{path : 'category/:id', redirectTo : '/categories/:id', pathMatch : 'full'},
{
path : 'categories',
children : [
{path : '', component : ComponentCategoryList},
{path : ':id', component : ComponentList},
],
},
{
path : ':id',
component : ComponentViewer,
children : [
{path : '', redirectTo : 'overview', pathMatch : 'full'},
{path : 'overview', component : ComponentOverview, pathMatch : 'full'},
{path : 'api', component : ComponentApi, pathMatch : 'full'},
{path : 'examples', component : ComponentExamples, pathMatch : 'full'},
{path : '**', redirectTo : 'overview'},
],
},
]
} ];

@NgModule({
imports: [
MatSidenavModule,
RouterModule,
CommonModule,
ComponentCategoryListModule,
ComponentHeaderModule,
ComponentListModule,
ComponentViewerModule,
DocViewerModule,
ExampleModule,
FooterModule,
BrowserAnimationsModule,
FormsModule,
HttpClientModule,
CdkAccordionModule,
MatIconModule,
CdkAccordionModule
MatSidenavModule,
StackBlitzButtonModule,
SvgViewerModule,
RouterModule.forChild(routes)
],
exports: [ComponentSidenav],
declarations: [ComponentSidenav, ComponentNav],
Expand Down
2 changes: 1 addition & 1 deletion src/app/pages/component-viewer/component-viewer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,6 @@ export class ComponentExamples extends ComponentBaseView {
],
exports: [ComponentViewer],
declarations: [ComponentViewer, ComponentOverview, ComponentApi, ComponentExamples],
providers: [DocumentationItems, ComponentPageTitle],
providers: [DocumentationItems],
})
export class ComponentViewerModule {}
2 changes: 1 addition & 1 deletion src/app/pages/guide-list/guide-list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,6 @@ const routes: Routes = [ {path : '', component : GuideList} ];
imports: [CommonModule, MatListModule, FooterModule, RouterModule.forChild(routes)],
exports: [GuideList],
declarations: [GuideList],
providers: [GuideItems, ComponentPageTitle],
providers: [GuideItems],
})
export class GuideListModule { }
2 changes: 1 addition & 1 deletion src/app/pages/guide-viewer/guide-viewer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,6 @@ const routes: Routes = [ {path : '', component : GuideViewer} ];
imports: [DocViewerModule, FooterModule, TableOfContentsModule, RouterModule.forChild(routes)],
exports: [GuideViewer],
declarations: [GuideViewer],
providers: [GuideItems, ComponentPageTitle],
providers: [GuideItems],
})
export class GuideViewerModule {}
2 changes: 1 addition & 1 deletion src/app/pages/page-title/page-title.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {Title} from '@angular/platform-browser';
/**
* Service responsible for setting the title that appears above the components and guide pages.
*/
@Injectable()
@Injectable({providedIn: 'root'})
export class ComponentPageTitle {
_title = '';
_originalTitle = 'Angular Material UI component library';
Expand Down
35 changes: 2 additions & 33 deletions src/app/routes.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,4 @@
import {ComponentList} from './pages/component-list';
import {Routes} from '@angular/router';
import {
ComponentApi,
ComponentExamples,
ComponentOverview,
ComponentViewer
} from './pages/component-viewer/component-viewer';
import {ComponentCategoryList} from './pages/component-category-list/component-category-list';
import {ComponentSidenav} from './pages/component-sidenav/component-sidenav';
import {CanActivateComponentSidenav} from './pages/component-sidenav/component-sidenav-can-load-guard';

export const MATERIAL_DOCS_ROUTES: Routes = [
Expand All @@ -30,30 +21,8 @@ export const MATERIAL_DOCS_ROUTES: Routes = [
{
path: ':section',
canActivate: [CanActivateComponentSidenav],
component: ComponentSidenav,
children: [
{path: '', redirectTo: 'categories', pathMatch: 'full'},
{path: 'component/:id', redirectTo: ':id', pathMatch: 'full'},
{path: 'category/:id', redirectTo: '/categories/:id', pathMatch: 'full'},
{
path: 'categories',
children: [
{path: '', component: ComponentCategoryList},
{path: ':id', component: ComponentList},
],
},
{
path: ':id',
component: ComponentViewer,
children: [
{path: '', redirectTo: 'overview', pathMatch: 'full'},
{path: 'overview', component: ComponentOverview, pathMatch: 'full'},
{path: 'api', component: ComponentApi, pathMatch: 'full'},
{path: 'examples', component: ComponentExamples, pathMatch: 'full'},
{path: '**', redirectTo: 'overview'},
],
},
],
loadChildren: () =>
import('./pages/component-sidenav/component-sidenav').then(m => m.ComponentSidenavModule)
},
{path: '**', redirectTo: ''},
];
4 changes: 2 additions & 2 deletions src/app/shared/doc-viewer/doc-viewer-module.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {DocViewer} from './doc-viewer';
import {ExampleViewer} from '../example-viewer/example-viewer';
import {StackBlitzButtonModule} from '../stack-blitz/stack-blitz-button';
import {StackBlitzButtonModule} from '../stack-blitz';
import {MatButtonModule} from '@angular/material/button';
import {MatIconModule} from '@angular/material/icon';
import {MatSnackBarModule} from '@angular/material/snack-bar';
Expand All @@ -16,12 +16,12 @@ import {CopierService} from '../copier/copier.service';
// ExampleViewer is included in the DocViewerModule because they have a circular dependency.
@NgModule({
imports: [
CommonModule,
MatButtonModule,
MatIconModule,
MatTooltipModule,
MatSnackBarModule,
MatTabsModule,
CommonModule,
PortalModule,
StackBlitzButtonModule
],
Expand Down
2 changes: 1 addition & 1 deletion src/app/shared/ga/ga.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ import {Injectable} from '@angular/core';

import {environment} from '../../../environments/environment';

@Injectable()
/**
* Google Analytics Service - captures app behaviors and sends them to Google Analytics (GA).
* Presupposes that GA script has been loaded from a script on the host web page.
* Associates data with a GA "property" from the environment (`gaId`).
*/
@Injectable({providedIn: 'root'})
export class GaService {

private previousUrl: string;
Expand Down
9 changes: 7 additions & 2 deletions src/app/shared/navbar/navbar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@ import {CommonModule} from '@angular/common';
import {MatButtonModule} from '@angular/material/button';
import {MatMenuModule} from '@angular/material/menu';
import {RouterModule} from '@angular/router';
import {ThemePickerModule} from '../theme-picker/theme-picker';
import {ThemePickerModule} from '../theme-picker';
import {VersionPickerModule} from '../version-picker';
import {SECTIONS} from '../documentation-items/documentation-items';
import {ThemeStorage} from '../theme-picker/theme-storage/theme-storage';
import {StyleManager} from '../style-manager';
import {HttpClientModule} from '@angular/common/http';

const SECTIONS_KEYS = Object.keys(SECTIONS);

Expand All @@ -28,14 +31,16 @@ export class NavBar {

@NgModule({
imports: [
CommonModule,
HttpClientModule,
MatButtonModule,
MatMenuModule,
RouterModule,
ThemePickerModule,
VersionPickerModule,
CommonModule
],
exports: [NavBar],
declarations: [NavBar],
providers: [StyleManager, ThemeStorage]
})
export class NavBarModule {}

0 comments on commit 0d08b11

Please sign in to comment.