diff --git a/src/app/app.component.html b/src/app/app.component.html index 92854828..f736e212 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -4,9 +4,15 @@
- + - + {{menu.title}} diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 42f17e39..c25ca087 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -7,6 +7,7 @@ import { } from '@angular/router'; import { filter, map, mergeMap } from 'rxjs/operators'; import { SeoService, SeoData } from './core/services/seo.service'; +import { OperatorMenuService } from './core/services/operator-menu.service'; interface Menu { title: string; @@ -46,7 +47,8 @@ export class AppComponent implements OnInit { constructor( private _router: Router, private _activatedRoute: ActivatedRoute, - private _seo: SeoService + private _seo: SeoService, + private _operatorMenuService: OperatorMenuService ) {} ngOnInit() { @@ -66,4 +68,11 @@ export class AppComponent implements OnInit { ) .subscribe((data: SeoData) => this._seo.setHeaders(data)); } + + shouldOpenChildMenu(title: string) { + // for accessibility we need to ensure child menu is open when clicked + if (title === 'Operators') { + this._operatorMenuService.openOperatorMenu(); + } + } } diff --git a/src/app/core/core.module.ts b/src/app/core/core.module.ts index 5b4767f3..aed5392f 100644 --- a/src/app/core/core.module.ts +++ b/src/app/core/core.module.ts @@ -5,6 +5,7 @@ import { FlexLayoutModule } from '@angular/flex-layout'; import { CopierService } from './services/copier.service'; import { SeoService } from './services/seo.service'; +import { OperatorMenuService } from './services/operator-menu.service'; import { ToolbarComponent } from './components/toolbar/toolbar.component'; import { MaterialModule } from '../material/material.module'; @@ -17,7 +18,7 @@ export class CoreModule { static forRoot() { return { ngModule: CoreModule, - providers: [CopierService, SeoService] + providers: [CopierService, SeoService, OperatorMenuService] }; } } diff --git a/src/app/core/services/operator-menu.service.ts b/src/app/core/services/operator-menu.service.ts new file mode 100644 index 00000000..74c8399d --- /dev/null +++ b/src/app/core/services/operator-menu.service.ts @@ -0,0 +1,19 @@ +import { Injectable } from '@angular/core'; +import { Subject } from 'rxjs/Subject'; + +@Injectable() +export class OperatorMenuService { + private _operatorMenuStatus = new Subject(); + + openOperatorMenu() { + this._operatorMenuStatus.next(true); + } + + closeOperatorMenu() { + this._operatorMenuStatus.next(false); + } + + menuStatus() { + return this._operatorMenuStatus.asObservable(); + } +} diff --git a/src/app/operators/operators.component.html b/src/app/operators/operators.component.html index 91046a0e..98470d77 100644 --- a/src/app/operators/operators.component.html +++ b/src/app/operators/operators.component.html @@ -1,31 +1,29 @@ - - - -

{{ category }}

+ + + +

{{ category }}

+ *ngFor="let operator of groupedOperators[category]" + [routerLink]="['/operators', operator.name]" + routerLinkActive="active"> {{ operator.name }}
- - diff --git a/src/app/operators/operators.component.ts b/src/app/operators/operators.component.ts index 8e3da660..2b590937 100644 --- a/src/app/operators/operators.component.ts +++ b/src/app/operators/operators.component.ts @@ -3,7 +3,10 @@ import { Inject, InjectionToken, OnInit, - ChangeDetectionStrategy + OnDestroy, + AfterContentInit, + ChangeDetectionStrategy, + ViewChild } from '@angular/core'; import { trigger, @@ -14,9 +17,13 @@ import { } from '@angular/animations'; import { Router, ActivatedRoute } from '@angular/router'; import { BreakpointObserver } from '@angular/cdk/layout'; +import { MatSidenav } from '@angular/material'; import { Subscription } from 'rxjs/Subscription'; +import { Subject } from 'rxjs/Subject'; import { Observable } from 'rxjs/Observable'; +import { filter, takeUntil } from 'rxjs/operators'; import { OperatorDoc } from '../../operator-docs/operator.model'; +import { OperatorMenuService } from '../core/services/operator-menu.service'; const OPERATOR_MENU_GAP_LARGE = 64; const OPERATOR_MENU_GAP_SMALL = 54; @@ -53,12 +60,15 @@ interface OperatorDocMap { ]) ] }) -export class OperatorsComponent implements OnInit { +export class OperatorsComponent implements OnInit, AfterContentInit, OnDestroy { + @ViewChild(MatSidenav) _sidenav: MatSidenav; public groupedOperators: OperatorDocMap; public categories: string[]; + private _onDestroy = new Subject(); constructor( private _breakpointObserver: BreakpointObserver, + private _operatorMenuService: OperatorMenuService, @Inject(OPERATORS_TOKEN) public operators: OperatorDoc[] ) {} @@ -67,6 +77,13 @@ export class OperatorsComponent implements OnInit { this.categories = Object.keys(this.groupedOperators); } + ngAfterContentInit() { + this._operatorMenuService + .menuStatus() + .pipe(filter(s => !!s), takeUntil(this._onDestroy)) + .subscribe(_ => this._sidenav.open()); + } + get extraSmallScreen() { return this._breakpointObserver.isMatched('(max-width: 601px)'); } @@ -84,6 +101,10 @@ export class OperatorsComponent implements OnInit { get sidenavMode() { return this.smallScreen ? 'over' : 'side'; } + + ngOnDestroy() { + this._onDestroy.next(); + } } export function groupOperatorsByType(operators: OperatorDoc[]): OperatorDocMap { diff --git a/src/app/operators/specs/operators.spec.ts b/src/app/operators/specs/operators.spec.ts index fcf0629a..0cac9d81 100644 --- a/src/app/operators/specs/operators.spec.ts +++ b/src/app/operators/specs/operators.spec.ts @@ -10,6 +10,7 @@ import { groupOperatorsByType } from '../operators.component'; import { OperatorDoc } from '../../../operator-docs'; +import { OperatorMenuService } from '../../core/services/operator-menu.service'; const mockActivatedRoute = { snapshot: {}, @@ -41,6 +42,7 @@ describe('Operators', () => { imports: [RouterTestingModule, LayoutModule], declarations: [OperatorsComponent], providers: [ + OperatorMenuService, { provide: OPERATORS_TOKEN, useValue: mockOperators }, { provide: ActivatedRoute, useValue: mockActivatedRoute } ],