src/app/components/page/page.component.ts
Calls page renderer with data from yaml files
selector | page |
styleUrls | ./page.component.scss |
templateUrl | ./page.component.html |
Properties |
|
constructor(router: Router, route: ActivatedRoute, errorHandler: ErrorHandler, contentService: ContentService)
|
|||||||||||||||
Defined in src/app/components/page/page.component.ts:19
|
|||||||||||||||
Creates instance of Router, ActivatedRoute, ErrorHandler, ContentService and invokes addScrollToTopListener
Parameters :
|
Readonly data$ |
Default value : this.resolveData()
|
Defined in src/app/components/page/page.component.ts:16
|
Observable of file content |
import { HttpErrorResponse } from '@angular/common/http';
import { Component, ErrorHandler, isDevMode } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { catchError, distinctUntilChanged, map, Observable, switchMap } from 'rxjs';
import { ContentService } from '../../services/content/content.service';
import { PageDef } from '../page-element/page-def';
/** Calls page renderer with data from yaml files*/
@Component({
selector: 'page',
templateUrl: './page.component.html',
styleUrls: ['./page.component.scss'],
})
export class PageComponent {
/** Observable of file content */
readonly data$ = this.resolveData();
/** Landing page file name */
private readonly LANDING_PAGE_FILE = 'landing-page';
/** Creates instance of Router, ActivatedRoute, ErrorHandler,
* ContentService and invokes addScrollToTopListener */
constructor(
private readonly router: Router,
private readonly route: ActivatedRoute,
private readonly errorHandler: ErrorHandler,
private readonly contentService: ContentService,
) {
this.addScrollToTopListener();
}
/** Returns an observable of page content */
private resolveData(): Observable<PageDef[]> {
const loadData = (file: string) =>
this.contentService.getContent(file).pipe(
catchError((error) => {
if (isDevMode() && (!(error instanceof HttpErrorResponse) || error.status !== 404)) {
this.errorHandler.handleError(error);
}
this.router.navigateByUrl('');
return this.contentService.getContent(this.LANDING_PAGE_FILE);
}),
);
return this.route.url.pipe(
map(() => this.router.routerState.snapshot.url),
map((url) => this.getFileName(url)),
switchMap(loadData),
);
}
/** Scrolls to the top of the page when the URL is changed */
private addScrollToTopListener(): void {
this.route.url.pipe(distinctUntilChanged()).subscribe(() => {
setTimeout(() => {
this.router.navigate([], {
relativeTo: this.route,
preserveFragment: true,
queryParamsHandling: 'preserve',
});
}, 100);
window.scroll({
top: 0,
left: 0,
behavior: 'smooth',
});
});
}
/** Returns a valid file name */
private getFileName(url: string): string {
return url.slice(1).split('#')[0].split('?')[0] || this.LANDING_PAGE_FILE;
}
}
<ccf-page-renderer [defs]="(data$ | async) ?? []"></ccf-page-renderer>
./page.component.scss
:host {
max-width: 77rem;
@media (max-width: 80rem) {
padding: 0rem 1rem;
max-width: 100vw;
}
}
::ng-deep .cell-link:hover {
color: #444c65;
text-decoration: underline;
text-decoration-thickness: 2px;
}