",
"license": "MIT",
+ "engines": {
+ "node": ">=6.9.0",
+ "npm": ">=3.10.3"
+ },
+ "optionalDependencies": {
+ "@bahmutov/add-typescript-to-cypress": "^2.0.0",
+ "@types/jasmine": "^3.0.0",
+ "cypress": "^3.1.0",
+ "jasmine-core": "^3.1.0",
+ "jasmine-spec-reporter": "^4.2.1",
+ "karma": "~3.1.0",
+ "karma-chrome-launcher": "~2.2.0",
+ "karma-coverage": "^1.1.1",
+ "karma-jasmine": "^2.0.1",
+ "karma-mocha-reporter": "^2.2.5",
+ "karma-remap-istanbul": "^0.6.0"
+ },
"devDependencies": {
- "@angular/compiler-cli": "~2.2.3",
- "@angular/platform-server": "~2.2.3",
- "@types/async": "^2.0.32",
- "@types/browser-sync": "^0.0.34",
- "@types/core-js": "^0.9.34",
- "@types/express": "^4.0.33",
- "@types/gulp": "^3.8.32",
- "@types/gulp-filter": "^3.0.29",
- "@types/gulp-load-plugins": "^0.0.28",
- "@types/gulp-protractor": "^1.0.29",
- "@types/gulp-sass": "^0.0.29",
- "@types/gulp-util": "^3.0.29",
- "@types/jasmine": "^2.5.35",
- "@types/node": "^6.0.45",
- "@types/protractor": "^1.5.20",
- "@types/rimraf": "0.0.28",
- "@types/run-sequence": "^0.0.28",
- "@types/selenium-webdriver": "2.44.*",
- "@types/systemjs": "^0.19.31",
- "@types/yargs": "^0.0.34",
- "@types/zone.js": "^0.0.27",
- "async": "^2.1.1",
- "autoprefixer": "^6.5.1",
- "browser-sync": "^2.17.3",
- "codelyzer": "~1.0.0-beta.4",
- "compodoc": "^0.0.15",
- "connect-history-api-fallback": "^1.3.0",
- "cssnano": "^3.7.7",
- "deep-extend": "^0.4.1",
- "event-stream": "^3.3.4",
- "express": "~4.14.0",
- "express-history-api-fallback": "^2.0.0",
+ "@angular/compiler-cli": "^7.0.0",
+ "@angular/language-service": "^7.0.0",
+ "@angular/platform-server": "^7.0.0",
+ "@compodoc/compodoc": "^1.1.1",
+ "@types/async": "^2.0.48",
+ "@types/browser-sync": "^0.0.42",
+ "@types/express": "^4.11.1",
+ "@types/gulp": "^4.0.5",
+ "@types/gulp-filter": "^3.0.32",
+ "@types/gulp-htmlmin": "^1.3.32",
+ "@types/gulp-load-plugins": "^0.0.31",
+ "@types/gulp-sass": "^0.0.31",
+ "@types/gulp-util": "^3.0.34",
+ "@types/node": "^11.9.0",
+ "@types/rimraf": "2.0.2",
+ "@types/run-sequence": "^0.0.30",
+ "@types/systemjs": "^0.20.6",
+ "@types/through2": "^2.0.34",
+ "@types/yargs": "12.0.2",
+ "ansi-colors": "^3.0.6",
+ "async": "^2.6.1",
+ "autoprefixer": "^9.4.2",
+ "browser-sync": "^2.24.6",
+ "browserslist": "^4.0.2",
+ "codelyzer": "^4.4.4",
+ "connect-history-api-fallback": "^1.5.0",
+ "cssnano": "4.1.10",
+ "deep-extend": "^0.6.0",
+ "event-stream": "^4.0.0",
+ "express": "~4.16.3",
+ "express-history-api-fallback": "^2.2.1",
+ "fancy-log": "^1.3.2",
"gulp": "^3.9.1",
- "gulp-cached": "^1.1.0",
- "gulp-concat": "^2.6.0",
- "gulp-concat-css": "^2.3.0",
- "gulp-filter": "^4.0.0",
- "gulp-inject": "^4.1.0",
- "gulp-inline-ng2-template": "^4.0.0",
- "gulp-load-plugins": "^1.3.0",
- "gulp-plumber": "~1.1.0",
- "gulp-postcss": "^6.2.0",
- "gulp-progeny": "^0.3.1",
- "gulp-protractor": "^3.0.0",
- "gulp-replace": "^0.5.4",
- "gulp-sass": "^2.3.2",
- "gulp-sourcemaps": "2.2.0",
- "gulp-template": "^4.0.0",
- "gulp-tslint": "^6.1.2",
- "gulp-typescript": "^3.0.2",
- "gulp-uglify": "^2.0.0",
- "gulp-util": "^3.0.7",
- "gulp-watch": "^4.3.10",
- "is-ci": "^1.0.9",
+ "gulp-cached": "^1.1.1",
+ "gulp-cheerio": "^0.6.3",
+ "gulp-concat": "^2.6.1",
+ "gulp-concat-css": "^3.1.0",
+ "gulp-filter": "^5.1.0",
+ "gulp-htmlmin": "^5.0.0",
+ "gulp-inject": "^5.0.0",
+ "gulp-load-plugins": "^1.5.0",
+ "gulp-plumber": "~1.2.0",
+ "gulp-postcss": "^8.0.0",
+ "gulp-progeny": "^0.4.1",
+ "gulp-rename": "^1.4.0",
+ "gulp-replace": "^1.0.0",
+ "gulp-sass": "^4.0.1",
+ "gulp-sourcemaps": "2.6.4",
+ "gulp-template": "^5.0.0",
+ "gulp-tslint": "^8.1.3",
+ "gulp-typescript": "^4.0.2",
+ "gulp-uglify": "3.0.1",
+ "gulp-watch": "^5.0.1",
+ "is-ci": "^2.0.0",
"isstream": "^0.1.2",
- "jasmine-core": "~2.5.2",
- "jasmine-spec-reporter": "^2.7.0",
- "karma": "~1.3.0",
- "karma-chrome-launcher": "~2.0.0",
- "karma-coverage": "^1.1.1",
- "karma-jasmine": "~1.0.2",
- "karma-mocha-reporter": "^2.2.0",
- "karma-remap-istanbul": "^0.2.1",
- "merge-stream": "^1.0.0",
+ "merge-stream": "^1.0.1",
+ "minimatch": "^3.0.4",
+ "node-sass-magic-importer": "^5.2.0",
"open": "0.0.5",
- "protractor": "^4.0.9",
- "remap-istanbul": "^0.7.0",
- "rimraf": "^2.5.4",
- "run-sequence": "^1.2.2",
- "semver": "^5.3.0",
- "serve-static": "^1.11.1",
- "slash": "~1.0.0",
- "supports-color": "^3.1.2",
- "systemjs-builder": "0.15.33",
+ "remap-istanbul": "^0.13.0",
+ "rimraf": "^2.6.2",
+ "rollup": "~0.68.0",
+ "rollup-plugin-commonjs": "^9.1.5",
+ "rollup-plugin-includepaths": "0.2.3",
+ "rollup-plugin-node-resolve": "^4.0.0",
+ "run-sequence": "^2.2.1",
+ "semver": "^5.5.0",
+ "serve-static": "^1.13.2",
+ "slash": "~2.0.0",
+ "source-map-explorer": "^1.6.0",
+ "supports-color": "^6.0.0",
+ "systemjs-builder": "0.16.13",
+ "temp": "^0.9.0",
+ "through2": "^3.0.0",
"tildify": "^1.2.0",
"traceur": "^0.0.111",
- "ts-node": "^1.4.3",
- "tslint": "^3.15.1",
- "typescript": "^2.0.3",
- "walk": "^2.3.9",
- "yargs": "^6.0.0",
- "minimatch": "^3.0.3"
+ "ts-node": "^6.0.0",
+ "tslint": "^5.11.0",
+ "typescript": "3.1.x",
+ "walk": "^2.3.14",
+ "yargs": "^13.1.0"
},
"dependencies": {
- "@angular/common": "~2.2.3",
- "@angular/compiler": "~2.2.3",
- "@angular/core": "~2.2.3",
- "@angular/forms": "~2.2.3",
- "@angular/http": "~2.2.3",
- "@angular/platform-browser": "~2.2.3",
- "@angular/platform-browser-dynamic": "~2.2.3",
- "@angular/router": "~3.2.0",
+ "@angular-devkit/build-optimizer": "0.13.1",
+ "@angular/animations": "^7.0.0",
+ "@angular/common": "^7.0.0",
+ "@angular/compiler": "^7.0.0",
+ "@angular/core": "^7.0.0",
+ "@angular/forms": "^7.0.0",
+ "@angular/platform-browser": "^7.0.0",
+ "@angular/platform-browser-dynamic": "^7.0.0",
+ "@angular/router": "^7.0.0",
+ "@angular/service-worker": "^7.0.0",
+ "core-js": "2.6.4",
"intl": "^1.2.5",
- "core-js": "^2.4.1",
- "reflect-metadata": "^0.1.8",
- "rxjs": "5.0.0-beta.12",
- "systemjs": "0.19.40",
- "zone.js": "0.6.25"
+ "rxjs": "^6.2.2",
+ "systemjs": "0.21.5",
+ "zone.js": "~0.8.26"
}
}
diff --git a/protractor.conf.js b/protractor.conf.js
deleted file mode 100644
index ce43384bf..000000000
--- a/protractor.conf.js
+++ /dev/null
@@ -1,49 +0,0 @@
-const config = {
- baseUrl: 'http://localhost:5555/',
-
- specs: [
- './dist/e2e/**/*.e2e-spec.js'
- ],
-
- exclude: [],
-
- // 'jasmine' by default will use the latest jasmine framework
- framework: 'jasmine',
-
- // allScriptsTimeout: 110000,
-
- jasmineNodeOpts: {
- // showTiming: true,
- showColors: true,
- isVerbose: false,
- includeStackTrace: false,
- // defaultTimeoutInterval: 400000
- },
-
- directConnect: true,
-
- capabilities: {
- browserName: 'chrome'
- },
-
- onPrepare: function() {
- browser.ignoreSynchronization = false;
- },
-
-
- /**
- * Angular 2 configuration
- *
- * useAllAngular2AppRoots: tells Protractor to wait for any angular2 apps on the page instead of just the one matching
- * `rootEl`
- */
- useAllAngular2AppRoots: true
-};
-
-if (process.env.TRAVIS) {
- config.capabilities = {
- browserName: 'firefox'
- };
-}
-
-exports.config = config;
diff --git a/src/client/app/about/about.component.html b/src/client/app/about/about.component.html
index 0d9e2d4f2..70db18ec7 100644
--- a/src/client/app/about/about.component.html
+++ b/src/client/app/about/about.component.html
@@ -1,11 +1,11 @@
-Angular 2 Seed is a starter project that implements best practices in coding, building and testing Angular 2 apps.
+Angular Seed is a starter project that implements best practices in coding, building and testing Angular apps.
-Features
+Features
- Ready to go, statically typed build system using Gulp for working with TypeScript.
- Production and development builds.
- Sample unit tests with Jasmine and Karma including code coverage via Istanbul.
- - End-to-end tests with Protractor.
+ - End-to-end tests with Cypress.
- Development server with live reload.
- TypeScript definition management using Types.
- Basic Service Worker, which implements "Cache then network strategy".
diff --git a/src/client/app/about/about.component.spec.ts b/src/client/app/about/about.component.spec.ts
index 98fdbe474..490157919 100644
--- a/src/client/app/about/about.component.spec.ts
+++ b/src/client/app/about/about.component.spec.ts
@@ -1,13 +1,10 @@
import { Component } from '@angular/core';
-import {
- async,
- TestBed
-} from '@angular/core/testing';
+import { async, TestBed } from '@angular/core/testing';
import { AboutModule } from './about.module';
export function main() {
- describe('About component', () => {
+ describe('About component', () => {
// Setting module for testing
// Disable old forms
@@ -18,18 +15,20 @@ export function main() {
});
});
- it('should work',
+ it(
+ 'should work',
async(() => {
- TestBed
- .compileComponents()
- .then(() => {
- let fixture = TestBed.createComponent(TestComponent);
- let aboutDOMEl = fixture.debugElement.children[0].nativeElement;
+ TestBed.compileComponents().then(() => {
+ const fixture = TestBed.createComponent(TestComponent);
+ const aboutDOMEl = fixture.debugElement.children[0].nativeElement;
- expect(aboutDOMEl.querySelectorAll('h2')[0].textContent).toEqual('Features');
- });
- }));
- });
+ expect(aboutDOMEl.querySelectorAll('h2')[0].textContent).toEqual(
+ 'Features'
+ );
+ });
+ })
+ );
+ });
}
@Component({
diff --git a/src/client/app/about/index.ts b/src/client/app/about/index.ts
deleted file mode 100644
index 4e0179d0e..000000000
--- a/src/client/app/about/index.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-/**
- * This barrel file provides the export for the lazy loaded AboutComponent.
- */
-export * from './about.component';
diff --git a/src/client/app/app.component.css b/src/client/app/app.component.css
new file mode 100644
index 000000000..a12143e8c
--- /dev/null
+++ b/src/client/app/app.component.css
@@ -0,0 +1,5 @@
+:host {
+ flex: 1 1 100%;
+ display: flex;
+ flex-flow: column;
+}
diff --git a/src/client/app/app.component.spec.ts b/src/client/app/app.component.spec.ts
index 336ec9fb1..81833b4d3 100644
--- a/src/client/app/app.component.spec.ts
+++ b/src/client/app/app.component.spec.ts
@@ -15,14 +15,14 @@ import {
import { AppComponent } from './app.component';
import { HomeComponent } from './home/home.component';
import { AboutComponent } from './about/about.component';
-import { ToolbarComponent } from './shared/toolbar/toolbar.component';
-import { NavbarComponent } from './shared/navbar/navbar.component';
+import { ToolbarComponent } from './core/toolbar/toolbar.component';
+import { NavbarComponent } from './core/navbar/navbar.component';
export function main() {
describe('App component', () => {
- let config: Route[] = [
+ const config: Route[] = [
{ path: '', component: HomeComponent },
{ path: 'about', component: AboutComponent }
];
@@ -43,8 +43,8 @@ export function main() {
TestBed
.compileComponents()
.then(() => {
- let fixture = TestBed.createComponent(TestComponent);
- let compiled = fixture.nativeElement;
+ const fixture = TestBed.createComponent(TestComponent);
+ const compiled = fixture.nativeElement;
expect(compiled).toBeTruthy();
});
diff --git a/src/client/app/app.component.ts b/src/client/app/app.component.ts
index e7c6fe833..d271e4e56 100644
--- a/src/client/app/app.component.ts
+++ b/src/client/app/app.component.ts
@@ -1,6 +1,5 @@
import { Component } from '@angular/core';
-import { Config } from './shared/index';
-import './operators';
+import { Config } from './shared/config/env.config';
/**
* This class represents the main application component.
@@ -9,6 +8,7 @@ import './operators';
moduleId: module.id,
selector: 'sd-app',
templateUrl: 'app.component.html',
+ styleUrls: ['app.component.css'],
})
export class AppComponent {
constructor() {
diff --git a/src/client/app/app.module.ts b/src/client/app/app.module.ts
index 2b28e4ee9..ef00c3a1a 100644
--- a/src/client/app/app.module.ts
+++ b/src/client/app/app.module.ts
@@ -1,16 +1,29 @@
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { APP_BASE_HREF } from '@angular/common';
-import { HttpModule } from '@angular/http';
+import { HttpClientModule } from '@angular/common/http';
+import { ServiceWorkerModule } from '@angular/service-worker';
import { AppComponent } from './app.component';
import { AppRoutingModule } from './app-routing.module';
import { AboutModule } from './about/about.module';
import { HomeModule } from './home/home.module';
import { SharedModule } from './shared/shared.module';
+import { CoreModule } from './core/core.module';
+
@NgModule({
- imports: [BrowserModule, HttpModule, AppRoutingModule, AboutModule, HomeModule, SharedModule.forRoot()],
+ imports: [BrowserModule, CoreModule,
+ HttpClientModule, AppRoutingModule,
+ AboutModule, HomeModule,
+ SharedModule.forRoot(),
+ /**
+ * In order to start the Service Worker in Production located at "/ngsw-worker.js"
+ * uncomment this line. More about Service Workers here
+ * https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API/Using_Service_Workers
+ */
+ // ServiceWorkerModule.register('ngsw-worker.js', { enabled: String('<%= BUILD_TYPE %>') === 'prod' })
+ ],
declarations: [AppComponent],
providers: [{
provide: APP_BASE_HREF,
diff --git a/src/client/app/core/core.module.ts b/src/client/app/core/core.module.ts
new file mode 100644
index 000000000..e3dc67c66
--- /dev/null
+++ b/src/client/app/core/core.module.ts
@@ -0,0 +1,19 @@
+import { NgModule, Optional, SkipSelf } from '@angular/core';
+import { RouterModule } from '@angular/router';
+
+import { NavbarComponent } from './navbar/navbar.component';
+import { throwIfAlreadyLoaded } from './module-import-guard';
+import { ToolbarComponent } from './toolbar/toolbar.component';
+
+@NgModule({
+ imports: [RouterModule],
+ declarations: [NavbarComponent, ToolbarComponent],
+ exports: [RouterModule,
+ NavbarComponent, ToolbarComponent]
+})
+export class CoreModule {
+
+ constructor( @Optional() @SkipSelf() parentModule: CoreModule) {
+ throwIfAlreadyLoaded(parentModule, 'CoreModule');
+ }
+}
diff --git a/src/client/app/core/module-import-guard.ts b/src/client/app/core/module-import-guard.ts
new file mode 100644
index 000000000..ad8d1cd0e
--- /dev/null
+++ b/src/client/app/core/module-import-guard.ts
@@ -0,0 +1,14 @@
+/**
+ * Module Import Guard
+ *
+ * @name throwIfAlreadyLoaded
+ * @param {any} parentModule Parent module.
+ * @param {string} moduleName - Module name.
+ *
+ * @returns {any}
+ */
+export function throwIfAlreadyLoaded(parentModule: any, moduleName: string): any {
+ if (parentModule) {
+ throw new Error(`${moduleName} has already been loaded. Import Core modules in the AppModule only.`);
+ }
+}
diff --git a/src/client/app/shared/navbar/navbar.component.css b/src/client/app/core/navbar/navbar.component.css
similarity index 80%
rename from src/client/app/shared/navbar/navbar.component.css
rename to src/client/app/core/navbar/navbar.component.css
index 2e71ed6ca..b9bc0e6dc 100644
--- a/src/client/app/shared/navbar/navbar.component.css
+++ b/src/client/app/core/navbar/navbar.component.css
@@ -1,7 +1,6 @@
:host {
- border-color: #e1e1e1;
- border-style: solid;
- border-width: 0 0 1px;
+ border: 0 solid #e1e1e1;
+ border-bottom-width: 1px;
display: block;
height: 48px;
padding: 0 16px;
diff --git a/src/client/app/shared/navbar/navbar.component.html b/src/client/app/core/navbar/navbar.component.html
similarity index 100%
rename from src/client/app/shared/navbar/navbar.component.html
rename to src/client/app/core/navbar/navbar.component.html
diff --git a/src/client/app/shared/navbar/navbar.component.ts b/src/client/app/core/navbar/navbar.component.ts
similarity index 100%
rename from src/client/app/shared/navbar/navbar.component.ts
rename to src/client/app/core/navbar/navbar.component.ts
diff --git a/src/client/app/shared/toolbar/toolbar.component.css b/src/client/app/core/toolbar/toolbar.component.css
similarity index 100%
rename from src/client/app/shared/toolbar/toolbar.component.css
rename to src/client/app/core/toolbar/toolbar.component.css
diff --git a/src/client/app/shared/toolbar/toolbar.component.html b/src/client/app/core/toolbar/toolbar.component.html
similarity index 51%
rename from src/client/app/shared/toolbar/toolbar.component.html
rename to src/client/app/core/toolbar/toolbar.component.html
index 34965b4f2..116af1c7c 100644
--- a/src/client/app/shared/toolbar/toolbar.component.html
+++ b/src/client/app/core/toolbar/toolbar.component.html
@@ -1,2 +1,2 @@
-Angular 2 Seed
+Angular Seed
diff --git a/src/client/app/shared/toolbar/toolbar.component.ts b/src/client/app/core/toolbar/toolbar.component.ts
similarity index 100%
rename from src/client/app/shared/toolbar/toolbar.component.ts
rename to src/client/app/core/toolbar/toolbar.component.ts
diff --git a/src/client/app/home/home.component.html b/src/client/app/home/home.component.html
index e629269f1..b23dbb6ce 100644
--- a/src/client/app/home/home.component.html
+++ b/src/client/app/home/home.component.html
@@ -6,5 +6,5 @@
diff --git a/src/client/app/home/home.component.spec.ts b/src/client/app/home/home.component.spec.ts
index 10143b790..4fdbd3fd9 100644
--- a/src/client/app/home/home.component.spec.ts
+++ b/src/client/app/home/home.component.spec.ts
@@ -1,39 +1,27 @@
-import { Component } from '@angular/core';
-import { TestBed } from '@angular/core/testing';
import { FormsModule } from '@angular/forms';
-import { RouterModule } from '@angular/router';
import {
- async
-} from '@angular/core/testing';
-import {
- BaseRequestOptions,
- ConnectionBackend,
- Http, HttpModule
-} from '@angular/http';
-import { MockBackend } from '@angular/http/testing';
+ async,
+ TestBed
+ } from '@angular/core/testing';
+
+import { Observable } from 'rxjs';
-import { NameListService } from '../shared/index';
-import { HomeModule } from './home.module';
+import { HomeComponent } from './home.component';
+import { NameListService } from '../shared/name-list/name-list.service';
export function main() {
describe('Home component', () => {
- // setting module for testing
- // Disable old forms
+
beforeEach(() => {
+
TestBed.configureTestingModule({
- imports: [FormsModule, RouterModule, HttpModule, HomeModule],
- declarations: [TestComponent],
+ imports: [FormsModule],
+ declarations: [HomeComponent],
providers: [
- NameListService,
- BaseRequestOptions,
- MockBackend,
- {provide: Http, useFactory: function (backend: ConnectionBackend, defaultOptions: BaseRequestOptions) {
- return new Http(backend, defaultOptions);
- },
- deps: [MockBackend, BaseRequestOptions]
- },
+ { provide: NameListService, useValue: new MockNameListService() }
]
});
+
});
it('should work',
@@ -41,30 +29,42 @@ export function main() {
TestBed
.compileComponents()
.then(() => {
- let fixture = TestBed.createComponent(TestComponent);
- fixture.detectChanges();
+ const fixture = TestBed.createComponent(HomeComponent);
+ const homeInstance = fixture.debugElement.componentInstance;
+ const homeDOMEl = fixture.debugElement.nativeElement;
+ const mockNameListService =
+ fixture.debugElement.injector.get(NameListService) as MockNameListService;
+ const nameListServiceSpy = spyOn(mockNameListService, 'get').and.callThrough();
- let homeInstance = fixture.debugElement.children[0].componentInstance;
- let homeDOMEl = fixture.debugElement.children[0].nativeElement;
+ mockNameListService.returnValue = ['1', '2', '3'];
- expect(homeInstance.nameListService).toEqual(jasmine.any(NameListService));
- expect(homeDOMEl.querySelectorAll('li').length).toEqual(0);
+ fixture.detectChanges();
+
+ expect(homeInstance.nameListService).toEqual(jasmine.any(MockNameListService));
+ expect(homeDOMEl.querySelectorAll('li').length).toEqual(3);
+ expect(nameListServiceSpy.calls.count()).toBe(1);
homeInstance.newName = 'Minko';
homeInstance.addName();
fixture.detectChanges();
- expect(homeDOMEl.querySelectorAll('li').length).toEqual(1);
- expect(homeDOMEl.querySelectorAll('li')[0].textContent).toEqual('Minko');
+ expect(homeDOMEl.querySelectorAll('li').length).toEqual(4);
+ expect(homeDOMEl.querySelectorAll('li')[3].textContent).toEqual('Minko');
});
}));
});
}
-@Component({
- selector: 'test-cmp',
- template: ''
-})
-class TestComponent { }
+class MockNameListService {
+
+ returnValue: string[];
+
+ get(): Observable {
+ return Observable.create((observer: any) => {
+ observer.next(this.returnValue);
+ observer.complete();
+ });
+ }
+}
diff --git a/src/client/app/home/home.component.ts b/src/client/app/home/home.component.ts
index 06880210a..1be2ceb2d 100644
--- a/src/client/app/home/home.component.ts
+++ b/src/client/app/home/home.component.ts
@@ -1,5 +1,5 @@
import { Component, OnInit } from '@angular/core';
-import { NameListService } from '../shared/index';
+import { NameListService } from '../shared/name-list/name-list.service';
/**
* This class represents the lazy loaded HomeComponent.
@@ -12,7 +12,7 @@ import { NameListService } from '../shared/index';
})
export class HomeComponent implements OnInit {
- newName: string = '';
+ newName = '';
errorMessage: string;
names: any[] = [];
diff --git a/src/client/app/home/home.module.ts b/src/client/app/home/home.module.ts
index 24575eb47..f0dbe411f 100644
--- a/src/client/app/home/home.module.ts
+++ b/src/client/app/home/home.module.ts
@@ -1,14 +1,11 @@
import { NgModule } from '@angular/core';
-import { CommonModule } from '@angular/common';
import { HomeComponent } from './home.component';
import { HomeRoutingModule } from './home-routing.module';
import { SharedModule } from '../shared/shared.module';
-import { NameListService } from '../shared/name-list/index';
@NgModule({
- imports: [CommonModule, HomeRoutingModule, SharedModule],
+ imports: [HomeRoutingModule, SharedModule],
declarations: [HomeComponent],
- exports: [HomeComponent],
- providers: [NameListService]
+ exports: [HomeComponent]
})
export class HomeModule { }
diff --git a/src/client/app/home/index.ts b/src/client/app/home/index.ts
deleted file mode 100644
index 89b7cc8d7..000000000
--- a/src/client/app/home/index.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-/**
- * This barrel file provides the export for the lazy loaded HomeComponent.
- */
-export * from './home.component';
diff --git a/src/client/app/i18n.providers.ts b/src/client/app/i18n.providers.ts
index cca616364..d6a0b004a 100644
--- a/src/client/app/i18n.providers.ts
+++ b/src/client/app/i18n.providers.ts
@@ -3,18 +3,18 @@
// export class TranslationProviders {
//
// public getTranslationFile = (): Promise => {
-// let noProviders: Object[] = [];
+// const noProviders: Object[] = [];
//
// // Define a way to retrieve the local information
-// let locale: string = 'en-US';
+// const locale: string = 'en-US';
//
// // Set the directory to the translation files
-// let file: string = `../assets/locale/messages.${locale}.xlf`;
+// const file: string = `../assets/locale/messages.${locale}.xlf`;
//
-// if(!locale || locale === 'en-US') return Promise.resolve(noProviders);
+// if (!locale || locale === 'en-US') return Promise.resolve(noProviders);
//
// return new Promise(function (resolve, reject) {
-// let xhr = new XMLHttpRequest;
+// const xhr = new XMLHttpRequest;
// xhr.open('GET', file);
// xhr.onload = (data: any) => resolve(
// [
@@ -27,5 +27,4 @@
// xhr.send();
// });
// }
-// };
-//
+// }
diff --git a/src/client/app/main-prod.ts b/src/client/app/main-prod.ts
index 428e22959..ceb45f9a9 100644
--- a/src/client/app/main-prod.ts
+++ b/src/client/app/main-prod.ts
@@ -11,13 +11,3 @@ enableProdMode();
platformBrowser().bootstrapModuleFactory(AppModuleNgFactory);
-// In order to start the Service Worker located at "./worker.js"
-// uncomment this line. More about Service Workers here
-// https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API/Using_Service_Workers
-//
-// if ('serviceWorker' in navigator) {
-// (navigator).serviceWorker.register('./worker.js').then((registration: any) =>
-// console.log('ServiceWorker registration successful with scope: ', registration.scope))
-// .catch((err: any) =>
-// console.log('ServiceWorker registration failed: ', err));
-// }
diff --git a/src/client/app/main.ts b/src/client/app/main.ts
index f470074a5..5df04d8f8 100644
--- a/src/client/app/main.ts
+++ b/src/client/app/main.ts
@@ -11,11 +11,13 @@ import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
// The app module
import { AppModule } from './app.module';
-if (String('<%= BUILD_TYPE %>') === 'prod') { enableProdMode(); }
+if (String('<%= BUILD_TYPE %>') === 'prod') {
+ enableProdMode();
+}
// Compile and launch the module with i18n providers
// let TP = new TranslationProviders();
// TP.getTranslationFile().then((providers: any) => {
- // const options: any = { providers };
- platformBrowserDynamic().bootstrapModule(AppModule/*, options*/);
+// const options: any = { providers };
+platformBrowserDynamic().bootstrapModule(AppModule /*, options*/);
// });
diff --git a/src/client/app/operators.ts b/src/client/app/operators.ts
deleted file mode 100644
index ef1690da9..000000000
--- a/src/client/app/operators.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-// rxjs
-import 'rxjs/add/observable/throw';
-import 'rxjs/add/operator/map';
-import 'rxjs/add/operator/catch';
-
-// ngrx
-//import '@ngrx/core/add/operator/select';
diff --git a/src/client/app/shared/config/env.config.ts b/src/client/app/shared/config/env.config.ts
index 81e5aeda2..cdd1ff1d8 100644
--- a/src/client/app/shared/config/env.config.ts
+++ b/src/client/app/shared/config/env.config.ts
@@ -1,9 +1,4 @@
-// Feel free to extend this interface
-// depending on your app specific config.
-export interface EnvConfig {
- API?: string;
- ENV?: string;
-}
+import { EnvConfig } from '../../../../../tools/env/env-config.interface';
export const Config: EnvConfig = JSON.parse('<%= ENV_CONFIG %>');
diff --git a/src/client/app/shared/index.ts b/src/client/app/shared/index.ts
deleted file mode 100644
index 266e30c3e..000000000
--- a/src/client/app/shared/index.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-/**
- * This barrel file provides the exports for the shared resources (services, components).
- */
-export * from './name-list/index';
-export * from './navbar/index';
-export * from './toolbar/index';
-export * from './config/env.config';
diff --git a/src/client/app/shared/name-list/index.ts b/src/client/app/shared/name-list/index.ts
deleted file mode 100644
index d28631a15..000000000
--- a/src/client/app/shared/name-list/index.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-/**
- * This barrel file provides the export for the shared NameListService.
- */
-export * from './name-list.service';
diff --git a/src/client/app/shared/name-list/name-list.service.spec.ts b/src/client/app/shared/name-list/name-list.service.spec.ts
index fd68cde67..49cbba41c 100644
--- a/src/client/app/shared/name-list/name-list.service.spec.ts
+++ b/src/client/app/shared/name-list/name-list.service.spec.ts
@@ -1,46 +1,47 @@
-import { ReflectiveInjector } from '@angular/core';
-import { BaseRequestOptions, ConnectionBackend, Http, Response, ResponseOptions } from '@angular/http';
-import { MockBackend } from '@angular/http/testing';
-import { Observable } from 'rxjs/Observable';
-
+import { TestBed, async } from '@angular/core/testing';
+import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
import { NameListService } from './name-list.service';
+import { Observable } from 'rxjs';
+
export function main() {
describe('NameList Service', () => {
+
let nameListService: NameListService;
- let mockBackend: MockBackend;
- let initialResponse: any;
+ let httpMock: HttpTestingController;
beforeEach(() => {
- let injector = ReflectiveInjector.resolveAndCreate([
- NameListService,
- BaseRequestOptions,
- MockBackend,
- {provide: Http,
- useFactory: function(backend: ConnectionBackend, defaultOptions: BaseRequestOptions) {
- return new Http(backend, defaultOptions);
- },
- deps: [MockBackend, BaseRequestOptions]
- },
- ]);
- nameListService = injector.get(NameListService);
- mockBackend = injector.get(MockBackend);
-
- let connection: any;
- mockBackend.connections.subscribe((c: any) => connection = c);
- initialResponse = nameListService.get();
- connection.mockRespond(new Response(new ResponseOptions({ body: '["Dijkstra", "Hopper"]' })));
- });
+ TestBed.configureTestingModule({
+ imports: [HttpClientTestingModule],
+ providers: [NameListService]
+ });
- it('should return an Observable when get called', () => {
- expect(initialResponse).toEqual(jasmine.any(Observable));
+ nameListService = TestBed.get(NameListService);
+ httpMock = TestBed.get(HttpTestingController);
});
- it('should resolve to list of names when get called', () => {
- let names: any;
- initialResponse.subscribe((data: any) => names = data);
- expect(names).toEqual(['Dijkstra', 'Hopper']);
- });
+ it('should return an Observable when get called', async(() => {
+ expect(TestBed.get(NameListService).get()).toEqual(jasmine.any(Observable));
+ }));
+
+ it('should resolve to list of names when get called', async(() => {
+
+ const expectedUsers = [
+ 'Edsger Dijkstra',
+ 'Donald Knuth',
+ 'Alan Turing',
+ 'Grace Hopper'
+ ];
+
+ let actualUsers: string[] = [];
+ nameListService.get().subscribe((users: string[]) => {
+ actualUsers = users;
+ });
+
+ httpMock.expectOne('assets/data.json').flush(expectedUsers);
+
+ expect(actualUsers).toEqual(expectedUsers);
+ }));
});
}
diff --git a/src/client/app/shared/name-list/name-list.service.ts b/src/client/app/shared/name-list/name-list.service.ts
index e5914cd9d..e9b8694fb 100644
--- a/src/client/app/shared/name-list/name-list.service.ts
+++ b/src/client/app/shared/name-list/name-list.service.ts
@@ -1,30 +1,31 @@
import { Injectable } from '@angular/core';
-import { Http, Response } from '@angular/http';
-import { Observable } from 'rxjs/Observable';
-// import 'rxjs/add/operator/do'; // for debugging
+import { HttpClient } from '@angular/common/http';
+
+import { Observable, of } from 'rxjs';
+import { catchError, tap } from 'rxjs/operators';
/**
* This class provides the NameList service with methods to read names and add names.
*/
-@Injectable()
+@Injectable({ providedIn: 'root' })
export class NameListService {
/**
- * Creates a new NameListService with the injected Http.
- * @param {Http} http - The injected Http.
+ * Creates a new NameListService with the injected HttpClient.
+ * @param {HttpClient} http - The injected HttpClient.
* @constructor
*/
- constructor(private http: Http) {}
+ constructor(private http: HttpClient) {}
/**
* Returns an Observable for the HTTP GET request for the JSON resource.
* @return {string[]} The Observable for the HTTP request.
*/
get(): Observable {
- return this.http.get('/assets/data.json')
- .map((res: Response) => res.json())
- // .do(data => console.log('server data:', data)) // debug
- .catch(this.handleError);
+ return this.http.get('assets/data.json')
+ .pipe(
+ // tap((data: string[]) => console.log('server data:', data)), // debug
+ catchError(this.handleError));
}
/**
@@ -33,10 +34,11 @@ export class NameListService {
private handleError (error: any) {
// In a real world app, we might use a remote logging infrastructure
// We'd also dig deeper into the error to get a better message
- let errMsg = (error.message) ? error.message :
+ const errMsg = (error.message) ? error.message :
error.status ? `${error.status} - ${error.statusText}` : 'Server error';
console.error(errMsg); // log to console instead
- return Observable.throw(errMsg);
+
+ return of(errMsg);
}
}
diff --git a/src/client/app/shared/navbar/index.ts b/src/client/app/shared/navbar/index.ts
deleted file mode 100644
index 0a090cb0d..000000000
--- a/src/client/app/shared/navbar/index.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-/**
- * This barrel file provides the export for the shared NavbarComponent.
- */
-export * from './navbar.component';
diff --git a/src/client/app/shared/shared.module.ts b/src/client/app/shared/shared.module.ts
index f1565a644..69249abe3 100644
--- a/src/client/app/shared/shared.module.ts
+++ b/src/client/app/shared/shared.module.ts
@@ -1,21 +1,15 @@
import { NgModule, ModuleWithProviders } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
-import { RouterModule } from '@angular/router';
-import { ToolbarComponent } from './toolbar/index';
-import { NavbarComponent } from './navbar/index';
-import { NameListService } from './name-list/index';
+import { NameListService } from './name-list/name-list.service';
/**
* Do not specify providers for modules that might be imported by a lazy loaded module.
*/
-
@NgModule({
- imports: [CommonModule, RouterModule],
- declarations: [ToolbarComponent, NavbarComponent],
- exports: [ToolbarComponent, NavbarComponent,
- CommonModule, FormsModule, RouterModule]
+ imports: [CommonModule],
+ exports: [CommonModule, FormsModule]
})
export class SharedModule {
static forRoot(): ModuleWithProviders {
diff --git a/src/client/app/shared/toolbar/index.ts b/src/client/app/shared/toolbar/index.ts
deleted file mode 100644
index 9c9b084b3..000000000
--- a/src/client/app/shared/toolbar/index.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-/**
- * This barrel file provides the export for the shared ToolbarComponent.
- */
-export * from './toolbar.component';
diff --git a/src/client/css/main.css b/src/client/css/main.css
index 7adcfd5d0..dfd9408f4 100644
--- a/src/client/css/main.css
+++ b/src/client/css/main.css
@@ -1,14 +1,22 @@
/* Reset */
-html,
-body,
-div {
+html, body, div {
border: 0;
margin: 0;
padding: 0;
}
+html, body {
+ height: 100%;
+ width: 100%;
+}
+
+body {
+ display: flex;
+ flex-direction: column;
+}
+
/* Box-sizing border-box */
-* {
+*, *:before, *:after {
box-sizing: border-box;
}
diff --git a/src/client/index.html b/src/client/index.html
index ebf61e48b..e9a1b875a 100644
--- a/src/client/index.html
+++ b/src/client/index.html
@@ -7,7 +7,7 @@
<%= APP_TITLE %>
-
+
@@ -16,6 +16,15 @@
Loading...
+
+
+
<% } %>
@@ -38,7 +47,8 @@
diff --git a/src/client/ngsw-config.json b/src/client/ngsw-config.json
new file mode 100644
index 000000000..2d66e4df7
--- /dev/null
+++ b/src/client/ngsw-config.json
@@ -0,0 +1,38 @@
+{
+ "index": "/index.html",
+ "appData": {
+ "test": true
+ },
+ "assetGroups": [
+ {
+ "name": "appshell",
+ "resources": {
+ "files": ["/assets/**/*", "!/ngsw-worker.js"],
+ "versionedFiles": ["/**/*.html", "/**/*.js", "/**/*.css"],
+ "urls": []
+ }
+ }
+ ],
+ "dataGroups": [
+ {
+ "name": "api-freshness",
+ "urls": ["/timeline"],
+ "cacheConfig": {
+ "maxSize": 100,
+ "maxAge": "3d",
+ "timeout": "1m",
+ "strategy": "freshness"
+ }
+ },
+ {
+ "name": "api-performance",
+ "urls": ["/favorites"],
+ "cacheConfig": {
+ "maxSize": 100,
+ "maxAge": "3d",
+ "timeout": "1m",
+ "strategy": "performance"
+ }
+ }
+ ]
+}
diff --git a/src/client/app/system-config.ts b/src/client/system-config.ts
similarity index 54%
rename from src/client/app/system-config.ts
rename to src/client/system-config.ts
index 338199f53..452b8bbf8 100644
--- a/src/client/app/system-config.ts
+++ b/src/client/system-config.ts
@@ -1,3 +1,3 @@
-declare var System: SystemJSLoader.System;
+// declare var System: SystemJSLoader.System;
System.config(JSON.parse('<%= SYSTEM_CONFIG_DEV %>'));
diff --git a/src/client/tsconfig.json b/src/client/tsconfig.json
index 3b080f016..7b2c91c09 100644
--- a/src/client/tsconfig.json
+++ b/src/client/tsconfig.json
@@ -5,6 +5,7 @@
"declaration": false,
"removeComments": true,
"noLib": false,
+ "lib": ["es2016", "dom"],
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"sourceMap": true,
@@ -15,23 +16,10 @@
"noImplicitReturns": true,
"noImplicitUseStrict": false,
"noFallthroughCasesInSwitch": true,
- "typeRoots": [
- "../../node_modules/@types",
- "../../node_modules"
- ],
- "types": [
- "core-js",
- "express",
- "jasmine",
- "node",
- "protractor",
- "systemjs"
- ]
+ "allowSyntheticDefaultImports": true,
+ "typeRoots": ["../../node_modules/@types", "../../node_modules"],
+ "types": ["node", "jasmine", "systemjs"]
},
- "exclude": [
- "node_modules",
- "dist",
- "src"
- ],
- "compileOnSave": false
+ "compileOnSave": false,
+ "exclude": ["app/main-prod.ts"]
}
diff --git a/src/e2e/specs/about.component.e2e-spec.ts b/src/e2e/specs/about.component.e2e-spec.ts
deleted file mode 100644
index c0a3f15c2..000000000
--- a/src/e2e/specs/about.component.e2e-spec.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-describe('About', () => {
-
- beforeEach(async () => {
- return await browser.get('/about');
- });
-
- it('should have correct feature heading', () => {
- expect(element(by.css('sd-about h2')).getText()).toEqual('Features');
- });
-
-});
diff --git a/src/e2e/specs/app.component.e2e-spec.ts b/src/e2e/specs/app.component.e2e-spec.ts
deleted file mode 100644
index ae5507b0d..000000000
--- a/src/e2e/specs/app.component.e2e-spec.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-describe('App', () => {
-
- beforeEach(async () => {
- return await browser.get('/');
- });
-
- it('should have a title', () => {
- expect(browser.getTitle()).toEqual('Welcome to angular2-seed!');
- });
-
- it('should have