diff --git a/package.json b/package.json index 5ce12ff1..e9435e0c 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,6 @@ "@types/jasmine": "2.5.53", "@types/jasminewd2": "2.0.2", "@types/lodash": "4.14.77", - "@types/node": "6.0.60", "angular2-template-loader": "0.6.2", "codelyzer": "4.0.2", "commitizen": "^2.9.6", diff --git a/src/app/material/material.module.ts b/src/app/material/material.module.ts index 20fbe321..dfdfa991 100644 --- a/src/app/material/material.module.ts +++ b/src/app/material/material.module.ts @@ -12,7 +12,8 @@ import { MatInputModule, MatMenuModule, MatTooltipModule, - MatSnackBarModule + MatSnackBarModule, + MatTabsModule } from '@angular/material'; @NgModule({ @@ -28,6 +29,7 @@ import { MatInputModule, MatMenuModule, MatTooltipModule, + MatTabsModule, FlexLayoutModule, MatSnackBarModule ], @@ -42,6 +44,7 @@ import { MatInputModule, MatMenuModule, MatTooltipModule, + MatTabsModule, FlexLayoutModule, MatSnackBarModule ] diff --git a/src/app/operators/_operator-theme.scss b/src/app/operators/_operator-theme.scss index 91ed59cc..99f54f1f 100644 --- a/src/app/operators/_operator-theme.scss +++ b/src/app/operators/_operator-theme.scss @@ -19,13 +19,53 @@ $link-color: #0a6fc2; } } - app-operator a { - text-decoration: none; - color: $link-color; + app-operator-general, + app-operator-vendor-examples { + .main-operator-container { + padding: 5px; + display: flex; + flex-direction: column; + padding: 0 16px; + margin-bottom: 32px; + } + + .short-description { + margin: 16px 0 32px; + } + + a { + text-decoration: none; + color: $link-color; + + &:hover { + text-decoration: underline; + } + } + + .extra-tip { + display: flex; + } + + h3 { + display: inline-block; + vertical-align: middle; + padding-left: 10px; + } + + .tip-warning { + color: rgb(244, 67, 54); + } + + .tip-info { + color: rgb(33, 150, 243); + } } - app-operator a:hover { - text-decoration: underline; + .operator-section-tabs { + .mat-ink-bar { + background-color: $accent !important; + height: 3px; + } } .operator-list { @@ -56,4 +96,21 @@ $link-color: #0a6fc2; } } } + + .code-block { + position: relative; + + pre { + margin-top: 0; + padding-top: 0; + } + } + + .frame-wrapper { + iframe { + border: none; + width: 100%; + height: 350px; + } + } } diff --git a/src/app/operators/components/operator-examples/operator-examples.component.html b/src/app/operators/components/operator-examples/operator-examples.component.html index 021b9499..5abf053b 100644 --- a/src/app/operators/components/operator-examples/operator-examples.component.html +++ b/src/app/operators/components/operator-examples/operator-examples.component.html @@ -1,14 +1,22 @@

Examples

-
+
-
-
-
- +
+
diff --git a/src/app/operators/components/operator-examples/operator-examples.component.scss b/src/app/operators/components/operator-examples/operator-examples.component.scss index ae9fda53..c3312554 100644 --- a/src/app/operators/components/operator-examples/operator-examples.component.scss +++ b/src/app/operators/components/operator-examples/operator-examples.component.scss @@ -1,12 +1,3 @@ -.code-block { - position: relative; - - pre { - margin-top: 0; - padding-top: 0; - } -} - .menu-button { position: absolute; right: 0; @@ -36,11 +27,3 @@ .code-example { margin-bottom: 16px; } - -.bin-wrapper { - iframe { - border: none; - width: 100%; - height: 350px; - } -} diff --git a/src/app/operators/components/operator-extras/operator-extras.component.scss b/src/app/operators/components/operator-extras/operator-extras.component.scss index 100097d3..8b137891 100644 --- a/src/app/operators/components/operator-extras/operator-extras.component.scss +++ b/src/app/operators/components/operator-extras/operator-extras.component.scss @@ -1,17 +1 @@ -.extra-tip { - display: flex; -} -h3 { - display: inline-block; - vertical-align: middle; - padding-left: 10px; -} - -.tip-warning { - color: rgb(244, 67, 54); -} - -.tip-info { - color: rgb(33, 150, 243); -} diff --git a/src/app/operators/components/operator-general/operator-general.component.html b/src/app/operators/components/operator-general/operator-general.component.html new file mode 100644 index 00000000..4ff2a914 --- /dev/null +++ b/src/app/operators/components/operator-general/operator-general.component.html @@ -0,0 +1,34 @@ +
+

+

+ + + + + + + + + + + + + + + + +
diff --git a/src/app/operators/components/operator-general/operator-general.component.scss b/src/app/operators/components/operator-general/operator-general.component.scss new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/src/app/operators/components/operator-general/operator-general.component.scss @@ -0,0 +1 @@ + diff --git a/src/app/operators/components/operator-general/operator-general.component.ts b/src/app/operators/components/operator-general/operator-general.component.ts new file mode 100644 index 00000000..3b5530d3 --- /dev/null +++ b/src/app/operators/components/operator-general/operator-general.component.ts @@ -0,0 +1,61 @@ +import { + Component, + Input, + OnInit, + OnDestroy, + ViewEncapsulation +} from '@angular/core'; +import { OperatorDoc, ALL_OPERATORS } from '../../../../operator-docs'; +import { CopierService } from '../../../core/services/copier.service'; +import { MatSnackBar } from '@angular/material'; +import { OperatorComponent } from '../operator/operator.component'; +import { ActivatedRoute } from '@angular/router'; +import { takeUntil } from 'rxjs/operators/takeUntil'; +import { Subject } from 'rxjs/Subject'; + +@Component({ + selector: 'app-operator-general', + templateUrl: './operator-general.component.html', + styleUrls: ['./operator-general.component.scss'], + encapsulation: ViewEncapsulation.None +}) +export class OperatorGeneralComponent implements OnInit, OnDestroy { + public operator: OperatorDoc; + private _onDestroy = new Subject(); + 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 _operatorComponent: OperatorComponent, + private _activateRoute: ActivatedRoute, + private _copierService: CopierService, + private _snackBar: MatSnackBar + ) {} + + ngOnInit() { + this._activateRoute.params.pipe(takeUntil(this._onDestroy)).subscribe(_ => { + this.operator = this._operatorComponent.operator; + }); + } + + copyToClipboard(code: string) { + this._copierService.copyText(code); + this._snackBar.open( + 'The example has been copied to your clipboard!', + null, + { duration: 3000 } + ); + } + + get sourceUrl() { + return `${this.baseSourceUrl}/${this.operator.name}.ts`; + } + + get specsUrl() { + return `${this.baseSpecUrl}/${this.operator.name}-spec.js.html`; + } + + ngOnDestroy() { + this._onDestroy.next(); + } +} diff --git a/src/app/operators/components/operator-header/operator-header.component.scss b/src/app/operators/components/operator-header/operator-header.component.scss index 4b2b1153..338fa708 100644 --- a/src/app/operators/components/operator-header/operator-header.component.scss +++ b/src/app/operators/components/operator-header/operator-header.component.scss @@ -1,11 +1,7 @@ @import '../../operator-theme'; .operator-name { - font-size:30px; -} - -.signature { - margin-bottom: 24px; + font-size: 30px; } mat-toolbar { diff --git a/src/app/operators/components/operator-vendor-examples/operator-vendor-examples.component.html b/src/app/operators/components/operator-vendor-examples/operator-vendor-examples.component.html new file mode 100644 index 00000000..e5ab7a37 --- /dev/null +++ b/src/app/operators/components/operator-vendor-examples/operator-vendor-examples.component.html @@ -0,0 +1,13 @@ +
+
+

{{ example.name }}

+

{{ example.description }}

+
+
+ +
+
+
+
diff --git a/src/app/operators/components/operator-vendor-examples/operator-vendor-examples.component.scss b/src/app/operators/components/operator-vendor-examples/operator-vendor-examples.component.scss new file mode 100644 index 00000000..eaabd511 --- /dev/null +++ b/src/app/operators/components/operator-vendor-examples/operator-vendor-examples.component.scss @@ -0,0 +1,6 @@ +$stackblitz-blue: #0077cf; +$stackblitz-grey: #353535; + +.frame-wrapper { + background-color: $stackblitz-blue; +} diff --git a/src/app/operators/components/operator-vendor-examples/operator-vendor-examples.component.ts b/src/app/operators/components/operator-vendor-examples/operator-vendor-examples.component.ts new file mode 100644 index 00000000..9710bb91 --- /dev/null +++ b/src/app/operators/components/operator-vendor-examples/operator-vendor-examples.component.ts @@ -0,0 +1,35 @@ +import { Component, OnInit, OnDestroy, Input } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; +import { OperatorComponent } from '../operator/operator.component'; +import { Subject } from 'rxjs/Subject'; +import { takeUntil } from 'rxjs/operators/takeUntil'; +import { VendorExample } from '../../../../operator-docs'; + +@Component({ + selector: 'app-operator-vendor-examples', + templateUrl: './operator-vendor-examples.component.html', + styleUrls: ['./operator-vendor-examples.component.scss'] +}) +export class OperatorVendorExamplesComponent implements OnInit, OnDestroy { + public examples: VendorExample[] = []; + private _onDestroy = new Subject(); + + constructor( + private _operatorComponent: OperatorComponent, + private _activedRoute: ActivatedRoute + ) {} + + ngOnInit() { + this._activedRoute.params.pipe(takeUntil(this._onDestroy)).subscribe(p => { + this.examples = this._operatorComponent.operator.vendorExamples.filter( + e => { + return e.vendorName === p['vendor']; + } + ); + }); + } + + ngOnDestroy() { + this._onDestroy.next(); + } +} diff --git a/src/app/operators/components/operator/operator.component.html b/src/app/operators/components/operator/operator.component.html index 6bb46994..dc57973b 100644 --- a/src/app/operators/components/operator/operator.component.html +++ b/src/app/operators/components/operator/operator.component.html @@ -1,39 +1,25 @@ - -
-

-

- - - - - - - - - - - - - - - - -
+ + diff --git a/src/app/operators/components/operator/operator.component.scss b/src/app/operators/components/operator/operator.component.scss index 621798a0..8b137891 100644 --- a/src/app/operators/components/operator/operator.component.scss +++ b/src/app/operators/components/operator/operator.component.scss @@ -1,19 +1 @@ -.main-operator-container { - padding: 5px; - display: flex; - flex-direction: column; - padding: 0 16px; - margin-bottom: 32px; -} -.short-description { - margin: 16px 0 32px; -} - -.margin-bottom-32 { - margin-bottom: 32px; -} - -.margin-bottom-16 { - margin-bottom: 16px; -} diff --git a/src/app/operators/components/operator/operator.component.ts b/src/app/operators/components/operator/operator.component.ts index 9b3e9a6d..fced9f20 100644 --- a/src/app/operators/components/operator/operator.component.ts +++ b/src/app/operators/components/operator/operator.component.ts @@ -11,7 +11,7 @@ import { MatSnackBar } from '@angular/material'; import { pluck } from 'rxjs/operators'; import { CopierService } from '../../../core/services/copier.service'; import { SeoService } from '../../../core/services/seo.service'; -import { OperatorDoc } from '../../../../operator-docs/operator.model'; +import { OperatorDoc, VendorExample } from '../../../../operator-docs'; export const OPERATOR_TOKEN = new InjectionToken('operators'); @@ -23,9 +23,8 @@ export const OPERATOR_TOKEN = new InjectionToken('operators'); export class OperatorComponent implements OnInit { public operator: OperatorDoc; public operatorsMap = new Map(); - - private readonly baseSourceUrl = 'https://github.com/ReactiveX/rxjs/blob/master/src/operators/'; - private readonly baseSpecUrl = 'http://reactivex.io/rxjs/test-file/spec-js/operators'; + public vendorExamples: string[]; + public isVendor: boolean; constructor( private _router: Router, @@ -45,6 +44,8 @@ export class OperatorComponent implements OnInit { .subscribe((name: string) => { if (this.operatorsMap.has(name)) { this.operator = this.operatorsMap.get(name); + this.vendorExamples = this.compileVendorTabs(this.operator); + this.isVendor = this.isVendorRoute(this._router.url); this.scrollToTop(); } else { this.notfound(); @@ -67,74 +68,26 @@ export class OperatorComponent implements OnInit { } } - copyToClipboard(code: string) { - this._copierService.copyText(code); - this._snackBar.open( - 'The example has been copied to your clipboard!', - null, - { duration: 3000 } - ); - } - - get operatorName() { - return this.operator.name; - } - - get signature() { - return this.operator.signature || 'Signature Placeholder'; - } - - get marbleUrl() { - return this.operator.marbleUrl; - } - - get useInteractiveMarbles() { - return this.operator.useInteractiveMarbles; - } - - get shortDescription() { - return ( - this.operator.shortDescription && - this.operator.shortDescription.description - ); + compileVendorTabs(operator: OperatorDoc) { + return operator.vendorExamples + ? operator.vendorExamples.reduce((acc: string[], curr: VendorExample) => { + if (!acc.includes(curr.vendorName)) { + return [...acc, curr.vendorName]; + } + return acc; + }, []) + : []; } - get shortDescriptionExtras() { + isVendorRoute(url: string) { + // make this dynamic in future return ( - this.operator.shortDescription && this.operator.shortDescription.extras + this._router.url.includes('Angular') || this._router.url.includes('React') ); } - get walkthrough() { - return this.operator.walkthrough && this.operator.walkthrough.description; - } - - get walkthroughExtras() { - return this.operator.walkthrough && this.operator.walkthrough.extras; - } - - get parameters() { - return this.operator.parameters || []; - } - - get examples() { - return this.operator.examples || []; - } - - get relatedOperators() { - return this.operator.relatedOperators || []; - } - - get sourceUrl() { - return `${this.baseSourceUrl}/${this.operatorName}.ts`; - } - - get specsUrl() { - return `${this.baseSpecUrl}/${this.operatorName}-spec.js.html`; - } - - get additionalResources() { - return this.operator.additionalResources || []; + get signature() { + return this.operator.signature || 'Signature Placeholder'; } private notfound() { diff --git a/src/app/operators/operators-routing.module.ts b/src/app/operators/operators-routing.module.ts index 7f349125..30f24f19 100644 --- a/src/app/operators/operators-routing.module.ts +++ b/src/app/operators/operators-routing.module.ts @@ -3,7 +3,9 @@ import { Routes, RouterModule } from '@angular/router'; import { OperatorsComponent } from './operators.component'; import { OperatorComponent } from './components/operator/operator.component'; +import { OperatorGeneralComponent } from './components/operator-general/operator-general.component'; import { ALL_OPERATORS } from '../../operator-docs'; +import { OperatorVendorExamplesComponent } from './components/operator-vendor-examples/operator-vendor-examples.component'; const routes: Routes = [ { @@ -13,7 +15,17 @@ const routes: Routes = [ children: [ { path: ':operator', - component: OperatorComponent + component: OperatorComponent, + children: [ + { + path: '', + component: OperatorGeneralComponent + }, + { + path: ':vendor', + component: OperatorVendorExamplesComponent + } + ] }, { path: '', diff --git a/src/app/operators/operators.module.ts b/src/app/operators/operators.module.ts index c1ff69c0..6906e8c9 100644 --- a/src/app/operators/operators.module.ts +++ b/src/app/operators/operators.module.ts @@ -21,6 +21,8 @@ import { OperatorExtrasComponent } from './components/operator-extras/operator-e import { AdditionalResourcesComponent } from './components/additional-resources/additional-resources.component'; import { MarbleDiagramComponent } from './components/marble-diagram/marble-diagram.component'; import { WalkthroughComponent } from './components/walkthrough/walkthrough.component'; +import { OperatorGeneralComponent } from './components/operator-general/operator-general.component'; +import { OperatorVendorExamplesComponent } from './components/operator-vendor-examples/operator-vendor-examples.component'; import { HighlightJsDirective } from './directives/highlight-js.directive'; import { SafeUrlPipe } from './pipes/safe-url.pipe'; import { MaterialModule } from '../material/material.module'; @@ -32,6 +34,8 @@ import { MaterialModule } from '../material/material.module'; OperatorHeaderComponent, OperatorParametersComponent, OperatorExamplesComponent, + OperatorGeneralComponent, + OperatorVendorExamplesComponent, RelatedOperatorsComponent, OperatorExtrasComponent, AdditionalResourcesComponent, diff --git a/src/operator-docs/operator.model.ts b/src/operator-docs/operator.model.ts index 51b95b55..ac53aa15 100644 --- a/src/operator-docs/operator.model.ts +++ b/src/operator-docs/operator.model.ts @@ -1,4 +1,5 @@ -export type OperatorType = 'combination' +export type OperatorType = + | 'combination' | 'conditional' | 'creation' | 'error handling' @@ -14,7 +15,7 @@ export interface OperatorReference { } export interface ExternalLink { - platform: 'JSBin' | 'JSFiddle'; + platform: 'JSBin' | 'JSFiddle' | 'Stackblitz'; url: string; } @@ -27,10 +28,15 @@ export interface OperatorParameters { export interface OperatorExample { name: string; - code: string; + code?: string; externalLink: ExternalLink; } +export interface VendorExample extends OperatorExample { + vendorName: 'Angular' | 'React'; + description: string; +} + export interface OperatorExtra { type: 'Tip' | 'Warning'; text: string; @@ -45,13 +51,14 @@ export interface OperatorDoc { readonly parameters?: OperatorParameters[]; readonly shortDescription?: { description: string; - extras?: OperatorExtra[] + extras?: OperatorExtra[]; }; readonly walkthrough?: { description: string; - extras?: OperatorExtra[] + extras?: OperatorExtra[]; }; readonly examples?: OperatorExample[]; + readonly vendorExamples?: VendorExample[]; readonly additionalResources?: OperatorReference[]; readonly relatedOperators?: string[]; } diff --git a/src/styles.scss b/src/styles.scss index 507f884f..779e98b9 100644 --- a/src/styles.scss +++ b/src/styles.scss @@ -1,6 +1,7 @@ @import '~@angular/material/theming'; @import './app/operators/operator-theme'; @import './styles/code-helpers'; +@import './styles/general'; @import './styles/icons'; @include mat-core(); diff --git a/src/styles/_general.scss b/src/styles/_general.scss new file mode 100644 index 00000000..501c61ce --- /dev/null +++ b/src/styles/_general.scss @@ -0,0 +1,15 @@ +.margin-bottom-32 { + margin-bottom: 32px; +} + +.margin-top-32 { + margin-top: 32px; +} + +.margin-top-16 { + margin-bottom: 16px; +} + +.margin-bottom-16 { + margin-bottom: 16px; +} diff --git a/tsconfig.json b/tsconfig.json index a6c016bf..affc9fc8 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -8,12 +8,7 @@ "emitDecoratorMetadata": true, "experimentalDecorators": true, "target": "es5", - "typeRoots": [ - "node_modules/@types" - ], - "lib": [ - "es2017", - "dom" - ] + "typeRoots": ["node_modules/@types"], + "lib": ["es2017", "dom"] } }