Skip to content
This repository was archived by the owner on Oct 1, 2018. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
f560418
refactor(operators): Separate operators in multiple pages
feloy Nov 19, 2017
5b3ad9b
refactor(operators): Adapt links for operators in different pages
feloy Nov 19, 2017
6e41260
fix(operators): Show active menu entry
feloy Nov 19, 2017
802953f
fix(operators): Redirect for not found operator
feloy Nov 19, 2017
8c9fef3
feat(search): Add title and meta description to pages
feloy Nov 19, 2017
2305d9d
fix(tests): Add SeoService provider for OperatorsComponent tests
feloy Nov 19, 2017
a78587c
Merge remote-tracking branch 'origin/master' into multipages
feloy Nov 20, 2017
e725a59
fix(rxjs): Use lettable operators
feloy Nov 20, 2017
3774515
fix(operators): Remove unused subscription
feloy Nov 20, 2017
ac8a90e
fix(operators): Debug lettable operators and remove dead code
feloy Nov 20, 2017
0cf78b3
fix(seo): Set SEO data in route config
feloy Nov 20, 2017
7842697
fix(seo): Add a type for SEO data
feloy Nov 20, 2017
4f49c3f
fix(operator): Compute a map of operators
feloy Nov 24, 2017
5a231bb
fix(operators): Use Map for operators map
feloy Nov 24, 2017
c66aadf
refactor(operators): Separate operators in multiple pages
feloy Nov 19, 2017
e01b233
refactor(operators): Adapt links for operators in different pages
feloy Nov 19, 2017
b4c3d7c
fix(operators): Show active menu entry
feloy Nov 19, 2017
23930c8
fix(operators): Redirect for not found operator
feloy Nov 19, 2017
e970438
feat(search): Add title and meta description to pages
feloy Nov 19, 2017
f25e238
fix(tests): Add SeoService provider for OperatorsComponent tests
feloy Nov 19, 2017
c64a5cc
fix(rxjs): Use lettable operators
feloy Nov 20, 2017
f7d2dc3
fix(operators): Remove unused subscription
feloy Nov 20, 2017
267457e
fix(operators): Debug lettable operators and remove dead code
feloy Nov 20, 2017
4130dcd
fix(seo): Set SEO data in route config
feloy Nov 20, 2017
2d369a9
fix(seo): Add a type for SEO data
feloy Nov 20, 2017
a7f4182
fix(operator): Compute a map of operators
feloy Nov 24, 2017
29198f5
fix(operators): Use Map for operators map
feloy Nov 24, 2017
8a2386f
Merge branch 'multipages' of https://github.com/feloy/rxjs-docs into …
feloy Nov 24, 2017
f2b3ee8
Merge remote-tracking branch 'upstream/master' into multipages
feloy Nov 24, 2017
2dd4ab7
Merge branch 'master' into multipages
sumitarora Nov 27, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/app/app.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { AppComponent } from './app.component';
import { ToolbarModule } from './toolbar/toolbar.module';
import { MatSidenavModule, MatListModule } from '@angular/material';
import { SeoService } from './services/seo.service';

describe('AppComponent', () => {
let component: AppComponent;
Expand All @@ -19,7 +20,8 @@ describe('AppComponent', () => {
MatSidenavModule,
MatListModule
],
declarations: [AppComponent]
declarations: [AppComponent],
providers: [SeoService]
}).compileComponents();
})
);
Expand Down
58 changes: 45 additions & 13 deletions src/app/app.component.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
import { Component } from "@angular/core";
import { Component, OnInit } from '@angular/core';
import {
Router,
ActivatedRoute,
NavigationEnd,
RouterEvent
} from '@angular/router';
import { filter, map, mergeMap } from 'rxjs/operators';
import { SeoService, SeoData } from './services/seo.service';

interface Menu {
title: string;
Expand All @@ -7,31 +15,55 @@ interface Menu {
}

@Component({
selector: "app-root",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.scss"]
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
export class AppComponent implements OnInit {
menus: Menu[] = [
{
title: "Home",
link: "/",
title: 'Home',
link: '/',
options: { exact: true }
},
{
title: "Operators",
link: "/operators",
title: 'Operators',
link: '/operators',
options: { exact: false }
},
{
title: "Companies",
link: "/companies",
title: 'Companies',
link: '/companies',
options: { exact: false }
},
{
title: "Team",
link: "/team",
title: 'Team',
link: '/team',
options: { exact: false }
}
];

constructor(
private _router: Router,
private _activatedRoute: ActivatedRoute,
private _seo: SeoService
) {}

ngOnInit() {
this._router.events
.pipe(
filter((e: RouterEvent) => e instanceof NavigationEnd),
map(() => {
let route = this._activatedRoute;
while (route.firstChild) {
route = route.firstChild;
}
return route;
}),
filter(route => route.outlet === 'primary'),
mergeMap(route => route.data),
filter((data: SeoData) => data.title !== undefined)
)
.subscribe((data: SeoData) => this._seo.setHeaders(data));
}
}
3 changes: 2 additions & 1 deletion src/app/app.module.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { SeoService } from './services/seo.service';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { NgModule } from '@angular/core';
Expand All @@ -17,7 +18,7 @@ import { AppRoutingModule } from './app-routing.module';
MatSidenavModule,
AppRoutingModule
],
providers: [],
providers: [SeoService],
bootstrap: [AppComponent]
})
export class AppModule {}
8 changes: 7 additions & 1 deletion src/app/companies/companies-routing.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,13 @@ import { Routes, RouterModule } from '@angular/router';

import { CompaniesComponent } from './companies.component';

const routes: Routes = [{ path: '', component: CompaniesComponent }];
const routes: Routes = [
{
path: '',
component: CompaniesComponent,
data: { title: ['Companies'], description: 'Companies that use RxJS...' }
}
];

@NgModule({
imports: [RouterModule.forChild(routes)],
Expand Down
12 changes: 5 additions & 7 deletions src/app/companies/companies.component.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
import { Component, OnInit } from "@angular/core";
import { Component } from '@angular/core';

@Component({
selector: "app-companies",
templateUrl: "./companies.component.html",
styleUrls: ["./companies.component.scss"]
selector: 'app-companies',
templateUrl: './companies.component.html',
styleUrls: ['./companies.component.scss']
})
export class CompaniesComponent implements OnInit {
export class CompaniesComponent {
constructor() {}

ngOnInit() {}
}
67 changes: 54 additions & 13 deletions src/app/operators/components/operator/operator.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,64 @@ import {
Component,
Input,
OnInit,
ChangeDetectionStrategy
} from "@angular/core";
import { OperatorDoc } from "../../../../operator-docs/operator.model";
ChangeDetectionStrategy,
Inject,
InjectionToken
} from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
import { SeoService } from '../../../services/seo.service';
import { OperatorDoc } from '../../../../operator-docs/operator.model';
import { pluck } from 'rxjs/operators';

export const OPERATOR_TOKEN = new InjectionToken<string>('operators');

@Component({
selector: "app-operator",
templateUrl: "./operator.component.html",
styleUrls: ["./operator.component.scss"],
changeDetection: ChangeDetectionStrategy.OnPush
selector: 'app-operator',
templateUrl: './operator.component.html',
styleUrls: ['./operator.component.scss']
})
export class OperatorComponent {
@Input() operator: OperatorDoc;

private readonly baseSourceUrl = "https://github.com/ReactiveX/rxjs/blob/master/src/operators/";
private readonly baseSpecUrl = "http://reactivex.io/rxjs/test-file/spec-js/operators";
export class OperatorComponent implements OnInit {
public operator: OperatorDoc;
public operatorsMap = new Map<string, OperatorDoc>();

private readonly baseSourceUrl = 'https://github.com/ReactiveX/rxjs/blob/master/src/operators/';
private readonly baseSpecUrl = 'http://reactivex.io/rxjs/test-file/spec-js/operators';

constructor(
private _router: Router,
private _activatedRoute: ActivatedRoute,
@Inject(OPERATOR_TOKEN) public operators: OperatorDoc[],
private _seo: SeoService

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is an Angular project I believe it's worth sticking to their official style guide that discourages from prefixing private variables with _. See https://angular.io/guide/styleguide#style-03-04

Copy link
Collaborator

@btroncone btroncone Nov 20, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is debatable, in the material docs project _ is being used for private. I prefer this convention.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer to stick to the existing code in the project and use _

) {}

ngOnInit() {
this.operators.forEach((op: OperatorDoc) => {
this.operatorsMap.set(op.name, op);
});
this._activatedRoute.params
.pipe(pluck('operator'))
.subscribe((name: string) => {
if (this.operatorsMap.has(name)) {
this.operator = this.operatorsMap.get(name);
} else {
this.notfound();
return;
}
this._seo.setHeaders({
title: [this.operator.name, this.operator.operatorType],
description: this.operator.shortDescription
? this.operator.shortDescription.description
: ''
});
});
}

get operatorName() {
return this.operator.name;
}

get signature() {
return this.operator.signature || "Signature Placeholder";
return this.operator.signature || 'Signature Placeholder';
}

get marbleUrl() {
Expand Down Expand Up @@ -78,4 +114,9 @@ export class OperatorComponent {
get additionalResources() {
return this.operator.additionalResources || [];
}

private notfound() {
this._router.navigate(['/operators']);
return {};
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<h2 class="related-operators"> Related Operators </h2>
<ul class="section-list">
<li *ngFor="let related of relatedOperators">
<a [href]="'/operators#' + related"> {{ related }} </a>
<a [routerLink]="['/operators', related]"> {{ related }} </a>
</li>
</ul>
10 changes: 9 additions & 1 deletion src/app/operators/operators-routing.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,16 @@ import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

import { OperatorsComponent } from './operators.component';
import { OperatorComponent } from './components/operator/operator.component';

const routes: Routes = [{ path: '', component: OperatorsComponent }];
const routes: Routes = [
{
path: '',
component: OperatorsComponent,
data: { title: ['Operators'], description: 'All the RxJS operators...' },
children: [{ path: ':operator', component: OperatorComponent }]
}
];

@NgModule({
imports: [RouterModule.forChild(routes)],
Expand Down
8 changes: 3 additions & 5 deletions src/app/operators/operators.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,13 @@
<h3 mat-subheader class="category-subheader">{{ category }}</h3>
<a mat-list-item
*ngFor="let operator of groupedOperators[category]"
[href]="'/operators#' + operator.name">
[routerLink]="['/operators', operator.name]"
routerLinkActive="active">
{{ operator.name }}
</a>
</mat-nav-list>
</mat-sidenav>
<app-operator
*ngFor="let operator of operators"
[operator]="operator">
</app-operator>
<router-outlet></router-outlet>
</mat-sidenav-container>
<button
*ngIf="smallScreen"
Expand Down
71 changes: 29 additions & 42 deletions src/app/operators/operators.component.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
import { Component, Inject, InjectionToken, OnInit, AfterViewInit, ChangeDetectionStrategy } from '@angular/core';
import { trigger, state, style, animate, transition } from '@angular/animations';
import {
Component,
Inject,
InjectionToken,
OnInit,
ChangeDetectionStrategy
} from '@angular/core';
import {
trigger,
state,
style,
animate,
transition
} from '@angular/animations';
import { Router, ActivatedRoute } from '@angular/router';
import { BreakpointObserver } from '@angular/cdk/layout';
import { Subscription } from 'rxjs/Subscription';
Expand All @@ -21,7 +33,7 @@ interface OperatorDocMap {
styleUrls: ['./operators.component.scss'],
animations: [
trigger('growInOut', [
state('in', style({opacity: 1})),
state('in', style({ opacity: 1 })),
transition('void => *', [
style({
opacity: 0,
Expand All @@ -30,55 +42,29 @@ interface OperatorDocMap {
animate(`150ms ease-in`)
]),
transition('* => void', [
animate(`150ms ease-out`, style({
opacity: 0,
transform: 'scale3d(.3, .3, .3)'
}))
animate(
`150ms ease-out`,
style({
opacity: 0,
transform: 'scale3d(.3, .3, .3)'
})
)
])
])
]
})
export class OperatorsComponent implements OnInit, AfterViewInit {
export class OperatorsComponent implements OnInit {
public groupedOperators: OperatorDocMap;
public categories: string[];

private _subscription: Subscription;

constructor(
private _breakpointObserver: BreakpointObserver,
private _router: Router,
private _activatedRoute: ActivatedRoute,
@Inject(OPERATORS_TOKEN) public operators: OperatorDoc[]
) { }
) {}

ngOnInit() {
this.groupedOperators = groupOperatorsByType(this.operators);
this.categories = Object.keys(this.groupedOperators);
this._subscription = this._activatedRoute
.fragment
.subscribe(name => this.scrollToOperator(name));
}

ngAfterViewInit() {
// scroll initial param when applicable
const name = this._activatedRoute.snapshot.fragment;

if (name) {
// slight delay for scroll to be accurate
setTimeout(() => this.scrollToOperator(name), 100);
}
}

updateUrl(name: string) {
this._router.navigate([ '/operators' ], { fragment: name });
}

scrollToOperator(name: string) {
const element = document.getElementById(name);

if (element) {
element.scrollIntoView();
}
}

get extraSmallScreen() {
Expand All @@ -90,20 +76,21 @@ export class OperatorsComponent implements OnInit, AfterViewInit {
}

get operatorMenuGap() {
return this.extraSmallScreen ? OPERATOR_MENU_GAP_SMALL : OPERATOR_MENU_GAP_LARGE;
return this.extraSmallScreen
? OPERATOR_MENU_GAP_SMALL
: OPERATOR_MENU_GAP_LARGE;
}

get sidenavMode() {
return this.smallScreen ? 'over' : 'side';
}

}

export function groupOperatorsByType(operators: OperatorDoc[]): OperatorDocMap {
return operators.reduce((acc: OperatorDocMap, curr: OperatorDoc) => {
if (acc[curr.operatorType]) {
return { ...acc, [ curr.operatorType ] : [ ...acc[ curr.operatorType ], curr ] };
return { ...acc, [curr.operatorType]: [...acc[curr.operatorType], curr] };
}
return { ...acc, [ curr.operatorType ]: [ curr ] };
return { ...acc, [curr.operatorType]: [curr] };
}, {});
}
Loading