diff --git a/dashboard/.angular-cli.json b/dashboard/.angular-cli.json
new file mode 100644
index 0000000..588d53d
--- /dev/null
+++ b/dashboard/.angular-cli.json
@@ -0,0 +1,61 @@
+{
+ "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
+ "project": {
+ "name": "dashboard"
+ },
+ "apps": [
+ {
+ "root": "src",
+ "outDir": "dist",
+ "assets": [
+ "assets",
+ "favicon.ico"
+ ],
+ "index": "index.html",
+ "main": "main.ts",
+ "polyfills": "polyfills.ts",
+ "test": "test.ts",
+ "tsconfig": "tsconfig.app.json",
+ "testTsconfig": "tsconfig.spec.json",
+ "prefix": "app",
+ "styles": [
+ "styles.css",
+ "../node_modules/bootstrap/dist/css/bootstrap.min.css"
+ ],
+ "scripts": [],
+ "environmentSource": "environments/environment.ts",
+ "environments": {
+ "dev": "environments/environment.ts",
+ "prod": "environments/environment.prod.ts"
+ }
+ }
+ ],
+ "e2e": {
+ "protractor": {
+ "config": "./protractor.conf.js"
+ }
+ },
+ "lint": [
+ {
+ "project": "src/tsconfig.app.json",
+ "exclude": "**/node_modules/**"
+ },
+ {
+ "project": "src/tsconfig.spec.json",
+ "exclude": "**/node_modules/**"
+ },
+ {
+ "project": "e2e/tsconfig.e2e.json",
+ "exclude": "**/node_modules/**"
+ }
+ ],
+ "test": {
+ "karma": {
+ "config": "./karma.conf.js"
+ }
+ },
+ "defaults": {
+ "styleExt": "css",
+ "component": {}
+ }
+}
diff --git a/dashboard/.editorconfig b/dashboard/.editorconfig
index b8a6e57..6e87a00 100644
--- a/dashboard/.editorconfig
+++ b/dashboard/.editorconfig
@@ -1,4 +1,4 @@
-# http://editorconfig.org
+# Editor configuration, see http://editorconfig.org
root = true
[*]
@@ -8,12 +8,6 @@ indent_size = 2
insert_final_newline = true
trim_trailing_whitespace = true
-
[*.md]
-max_line_length = 0
+max_line_length = off
trim_trailing_whitespace = false
-
-# Indentation override
-#[lib/**.js]
-#[{package.json,.travis.yml}]
-#[**/**.js]
diff --git a/dashboard/.gitignore b/dashboard/.gitignore
index c9c982d..6b66814 100644
--- a/dashboard/.gitignore
+++ b/dashboard/.gitignore
@@ -1,3 +1,43 @@
-src/app/**/*.js.map
-src/app/**/*.js
-node_modules/
\ No newline at end of file
+# See http://help.github.com/ignore-files/ for more about ignoring files.
+
+# compiled output
+/dist
+/tmp
+/out-tsc
+
+# dependencies
+/node_modules
+
+# IDEs and editors
+/.idea
+.project
+.classpath
+.c9/
+*.launch
+.settings/
+*.sublime-workspace
+
+# IDE - VSCode
+.vscode/*
+!.vscode/settings.json
+!.vscode/tasks.json
+!.vscode/launch.json
+!.vscode/extensions.json
+
+# misc
+/.sass-cache
+/connect.lock
+/coverage
+/libpeerconnection.log
+npm-debug.log
+testem.log
+/typings
+yarn-error.log
+
+# e2e
+/e2e/*.js
+/e2e/*.map
+
+# System Files
+.DS_Store
+Thumbs.db
diff --git a/dashboard/bs-config.json b/dashboard/bs-config.json
deleted file mode 100644
index 606cc8f..0000000
--- a/dashboard/bs-config.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- "server": {
- "baseDir": "src",
- "routes": {
- "/node_modules": "node_modules"
- }
- },
- "port": 3030
-}
diff --git a/dashboard/e2e/app.e2e-spec.ts b/dashboard/e2e/app.e2e-spec.ts
new file mode 100644
index 0000000..62e1783
--- /dev/null
+++ b/dashboard/e2e/app.e2e-spec.ts
@@ -0,0 +1,14 @@
+import { AppPage } from './app.po';
+
+describe('dashboard App', () => {
+ let page: AppPage;
+
+ beforeEach(() => {
+ page = new AppPage();
+ });
+
+ it('should display welcome message', () => {
+ page.navigateTo();
+ expect(page.getParagraphText()).toEqual('Welcome to app!');
+ });
+});
diff --git a/dashboard/e2e/app.po.ts b/dashboard/e2e/app.po.ts
new file mode 100644
index 0000000..82ea75b
--- /dev/null
+++ b/dashboard/e2e/app.po.ts
@@ -0,0 +1,11 @@
+import { browser, by, element } from 'protractor';
+
+export class AppPage {
+ navigateTo() {
+ return browser.get('/');
+ }
+
+ getParagraphText() {
+ return element(by.css('app-root h1')).getText();
+ }
+}
diff --git a/dashboard/e2e/tsconfig.e2e.json b/dashboard/e2e/tsconfig.e2e.json
new file mode 100644
index 0000000..1d9e5ed
--- /dev/null
+++ b/dashboard/e2e/tsconfig.e2e.json
@@ -0,0 +1,14 @@
+{
+ "extends": "../tsconfig.json",
+ "compilerOptions": {
+ "outDir": "../out-tsc/e2e",
+ "baseUrl": "./",
+ "module": "commonjs",
+ "target": "es5",
+ "types": [
+ "jasmine",
+ "jasminewd2",
+ "node"
+ ]
+ }
+}
diff --git a/dashboard/karma.conf.js b/dashboard/karma.conf.js
new file mode 100644
index 0000000..af139fa
--- /dev/null
+++ b/dashboard/karma.conf.js
@@ -0,0 +1,33 @@
+// Karma configuration file, see link for more information
+// https://karma-runner.github.io/1.0/config/configuration-file.html
+
+module.exports = function (config) {
+ config.set({
+ basePath: '',
+ frameworks: ['jasmine', '@angular/cli'],
+ plugins: [
+ require('karma-jasmine'),
+ require('karma-chrome-launcher'),
+ require('karma-jasmine-html-reporter'),
+ require('karma-coverage-istanbul-reporter'),
+ require('@angular/cli/plugins/karma')
+ ],
+ client:{
+ clearContext: false // leave Jasmine Spec Runner output visible in browser
+ },
+ coverageIstanbulReporter: {
+ reports: [ 'html', 'lcovonly' ],
+ fixWebpackSourcePaths: true
+ },
+ angularCli: {
+ environment: 'dev'
+ },
+ reporters: ['progress', 'kjhtml'],
+ port: 9876,
+ colors: true,
+ logLevel: config.LOG_INFO,
+ autoWatch: true,
+ browsers: ['Chrome'],
+ singleRun: false
+ });
+};
diff --git a/dashboard/package.json b/dashboard/package.json
index 9b4efdb..705c436 100644
--- a/dashboard/package.json
+++ b/dashboard/package.json
@@ -1,65 +1,50 @@
{
- "name": "angular-quickstart",
- "version": "1.0.0",
- "description": "QuickStart package.json from the documentation, supplemented with testing support",
- "scripts": {
- "build": "tsc -p src/",
- "build:watch": "tsc -p src/ -w",
- "build:e2e": "tsc -p e2e/",
- "serve": "lite-server -c=bs-config.json",
- "serve:e2e": "lite-server -c=bs-config.e2e.json",
- "prestart": "npm run build",
- "start": "concurrently \"npm run build:watch\" \"npm run serve\"",
- "pree2e": "npm run build:e2e",
- "e2e": "concurrently \"npm run serve:e2e\" \"npm run protractor\" --kill-others --success first",
- "preprotractor": "webdriver-manager update",
- "protractor": "protractor protractor.config.js",
- "pretest": "npm run build",
- "test": "concurrently \"npm run build:watch\" \"karma start karma.conf.js\"",
- "pretest:once": "npm run build",
- "test:once": "karma start karma.conf.js --single-run",
- "lint": "tslint ./src/**/*.ts -t verbose"
- },
- "keywords": [],
- "author": "",
+ "name": "dashboard",
+ "version": "0.0.0",
"license": "MIT",
+ "scripts": {
+ "ng": "ng",
+ "start": "ng serve",
+ "build": "ng build",
+ "test": "ng test",
+ "lint": "ng lint",
+ "e2e": "ng e2e"
+ },
+ "private": true,
"dependencies": {
- "@angular/common": "~4.0.0",
- "@angular/compiler": "~4.0.0",
- "@angular/core": "~4.0.0",
- "@angular/forms": "~4.0.0",
- "@angular/http": "~4.0.0",
- "@angular/platform-browser": "~4.0.0",
- "@angular/platform-browser-dynamic": "~4.0.0",
- "@angular/router": "~4.0.0",
-
- "angular-in-memory-web-api": "~0.3.0",
- "systemjs": "0.19.40",
+ "@angular/animations": "^4.2.4",
+ "@angular/common": "^4.2.4",
+ "@angular/compiler": "^4.2.4",
+ "@angular/core": "^4.2.4",
+ "@angular/forms": "^4.2.4",
+ "@angular/http": "^4.2.4",
+ "@angular/platform-browser": "^4.2.4",
+ "@angular/platform-browser-dynamic": "^4.2.4",
+ "@angular/router": "^4.2.4",
"core-js": "^2.4.1",
- "rxjs": "5.0.1",
- "zone.js": "^0.8.4",
- "bootstrap": "3.3.7",
- "jquery": "1.9.1 - 2"
+ "rxjs": "^5.4.2",
+ "zone.js": "^0.8.14",
+ "bootstrap": "3.3.7"
},
"devDependencies": {
- "concurrently": "^3.2.0",
- "lite-server": "^2.2.2",
- "typescript": "~2.1.0",
-
- "canonical-path": "0.0.2",
- "tslint": "^3.15.1",
- "lodash": "^4.16.4",
- "jasmine-core": "~2.4.1",
- "karma": "^1.3.0",
- "karma-chrome-launcher": "^2.0.0",
- "karma-cli": "^1.0.1",
- "karma-jasmine": "^1.0.2",
+ "@angular/cli": "1.3.2",
+ "@angular/compiler-cli": "^4.2.4",
+ "@angular/language-service": "^4.2.4",
+ "@types/jasmine": "~2.5.53",
+ "@types/jasminewd2": "~2.0.2",
+ "@types/node": "~6.0.60",
+ "codelyzer": "~3.1.1",
+ "jasmine-core": "~2.6.2",
+ "jasmine-spec-reporter": "~4.1.0",
+ "karma": "~1.7.0",
+ "karma-chrome-launcher": "~2.1.1",
+ "karma-cli": "~1.0.1",
+ "karma-coverage-istanbul-reporter": "^1.2.1",
+ "karma-jasmine": "~1.1.0",
"karma-jasmine-html-reporter": "^0.2.2",
- "protractor": "~4.0.14",
- "rimraf": "^2.5.4",
-
- "@types/node": "^6.0.46",
- "@types/jasmine": "2.5.36"
- },
- "repository": {}
+ "protractor": "~5.1.2",
+ "ts-node": "~3.2.0",
+ "tslint": "~5.3.2",
+ "typescript": "~2.3.3"
+ }
}
diff --git a/dashboard/protractor.conf.js b/dashboard/protractor.conf.js
new file mode 100644
index 0000000..7ee3b5e
--- /dev/null
+++ b/dashboard/protractor.conf.js
@@ -0,0 +1,28 @@
+// Protractor configuration file, see link for more information
+// https://github.com/angular/protractor/blob/master/lib/config.ts
+
+const { SpecReporter } = require('jasmine-spec-reporter');
+
+exports.config = {
+ allScriptsTimeout: 11000,
+ specs: [
+ './e2e/**/*.e2e-spec.ts'
+ ],
+ capabilities: {
+ 'browserName': 'chrome'
+ },
+ directConnect: true,
+ baseUrl: 'http://localhost:4200/',
+ framework: 'jasmine',
+ jasmineNodeOpts: {
+ showColors: true,
+ defaultTimeoutInterval: 30000,
+ print: function() {}
+ },
+ onPrepare() {
+ require('ts-node').register({
+ project: 'e2e/tsconfig.e2e.json'
+ });
+ jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } }));
+ }
+};
diff --git a/dashboard/src/app/album.component.html b/dashboard/src/app/album.component.html
deleted file mode 100644
index 05b2c12..0000000
--- a/dashboard/src/app/album.component.html
+++ /dev/null
@@ -1,119 +0,0 @@
-
-
{{albumName}}
-
-
-
Debug Zone
- Returned song: {{songs.length}}
- Theorical number song: {{ album ? album['Track Count'] : "" }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{album.Rating}}/100
-
-
Rating
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{album['Track Count']}}
-
-
Songs
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{album['Play Count']}} list.
-
-
~{{album['Play Count'] / album['Track Count'] | number:'1.0-0'}} listening avg.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{album['Total Time'] | convertMs}}
-
-
Album time
-
-
-
-
-
-
-
-
-
-
-
- Name
- Artist
- Album
- Album Artist
- Play Count
-
-
-
-
- {{song['Track Number'] ? (("0" + song['Track Number']).slice(-2)) : "--"}}
- {{song.Name}}
- {{song.Artist}}
- {{song.Album}}
- {{song['Album Artist']}}
- {{song['Play Count']}}
-
-
-
-
-
- More...
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/dashboard/src/app/album.component.css b/dashboard/src/app/album/album.component.css
similarity index 99%
rename from dashboard/src/app/album.component.css
rename to dashboard/src/app/album/album.component.css
index 0a3bcc4..d57e880 100644
--- a/dashboard/src/app/album.component.css
+++ b/dashboard/src/app/album/album.component.css
@@ -34,4 +34,4 @@
.btn-sort {
bottom: 20px;
right: 70px;
-}
\ No newline at end of file
+}
diff --git a/dashboard/src/app/album/album.component.html b/dashboard/src/app/album/album.component.html
new file mode 100644
index 0000000..a724210
--- /dev/null
+++ b/dashboard/src/app/album/album.component.html
@@ -0,0 +1,119 @@
+
+
{{albumName}}
+
+
+
Debug Zone
+ Returned song: {{songs.length}}
+ Theorical number song: {{ album ? album['Track Count'] : "" }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{album.Rating}}/100
+
+
Rating
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{album['Track Count']}}
+
+
Songs
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{album['Play Count']}} list.
+
+
~{{album['Play Count'] / album['Track Count'] | number:'1.0-0'}} listening avg.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{album['Total Time'] | convertMs}}
+
+
Album time
+
+
+
+
+
+
+
+
+
+
+
+ Name
+ Artist
+ Album
+ Album Artist
+ Play Count
+
+
+
+
+ {{song['Track Number'] ? (("0" + song['Track Number']).slice(-2)) : "--"}}
+ {{song.Name}}
+ {{song.Artist}}
+ {{song.Album}}
+ {{song['Album Artist']}}
+ {{song['Play Count']}}
+
+
+
+
+
+ More...
+
+
+
+
+
+
+
diff --git a/dashboard/src/app/album/album.component.spec.ts b/dashboard/src/app/album/album.component.spec.ts
new file mode 100644
index 0000000..215ee4f
--- /dev/null
+++ b/dashboard/src/app/album/album.component.spec.ts
@@ -0,0 +1,25 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { AlbumComponent } from './album.component';
+
+describe('AlbumComponent', () => {
+ let component: AlbumComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ AlbumComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(AlbumComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should be created', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/dashboard/src/app/album.component.ts b/dashboard/src/app/album/album.component.ts
similarity index 83%
rename from dashboard/src/app/album.component.ts
rename to dashboard/src/app/album/album.component.ts
index e058502..6808f16 100644
--- a/dashboard/src/app/album.component.ts
+++ b/dashboard/src/app/album/album.component.ts
@@ -1,23 +1,23 @@
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Params } from '@angular/router';
-import { Location } from '@angular/common';
+import { Location } from '@angular/common';
-import { ElsService } from './els.service';
-import { Song } from './object/song';
-import { Album } from './object/album';
+import { ElsService } from './../els.service';
+import { Song } from './../object/song';
+import { Album } from './../object/album';
@Component({
- selector: 'album-component',
+ selector: 'app-album-component',
templateUrl: './album.component.html',
- styleUrls: [ './album.component.css', './dashboard.component.css' ]
+ styleUrls: [ './album.component.css', './../dashboard.component.css' ]
})
export class AlbumComponent implements OnInit {
albumName = '';
songs: Array = [];
album: Album = new Album(); // If album not found, will be replaced by 'undefined'
- moreDataAvailable: boolean = false;
- atBottom: boolean = false;
+ moreDataAvailable = false;
+ atBottom = false;
constructor(
private elsService: ElsService,
diff --git a/dashboard/src/app/app-routing.module.ts b/dashboard/src/app/app-routing.module.ts
index ae61ab8..aee2d78 100644
--- a/dashboard/src/app/app-routing.module.ts
+++ b/dashboard/src/app/app-routing.module.ts
@@ -1,9 +1,9 @@
-import { NgModule } from '@angular/core';
+import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
-import { DashboardComponent } from './dashboard.component';
-import { AlbumComponent } from './album.component';
-import { ArtistComponent } from './artist.component';
+import { DashboardComponent } from './dashboard.component';
+import { AlbumComponent } from './album/album.component';
+import { ArtistComponent } from './artist/artist.component';
const routes: Routes = [
{ path: '', redirectTo: '/dashboard', pathMatch: 'full' },
diff --git a/dashboard/src/app/app.component.html b/dashboard/src/app/app.component.html
new file mode 100644
index 0000000..df2dc6f
--- /dev/null
+++ b/dashboard/src/app/app.component.html
@@ -0,0 +1,4 @@
+
+ Dashboard
+
+
diff --git a/dashboard/src/app/app.component.spec.ts b/dashboard/src/app/app.component.spec.ts
new file mode 100644
index 0000000..9510495
--- /dev/null
+++ b/dashboard/src/app/app.component.spec.ts
@@ -0,0 +1,32 @@
+import { TestBed, async } from '@angular/core/testing';
+
+import { AppComponent } from './app.component';
+
+describe('AppComponent', () => {
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [
+ AppComponent
+ ],
+ }).compileComponents();
+ }));
+
+ it('should create the app', async(() => {
+ const fixture = TestBed.createComponent(AppComponent);
+ const app = fixture.debugElement.componentInstance;
+ expect(app).toBeTruthy();
+ }));
+
+ it(`should have as title 'app'`, async(() => {
+ const fixture = TestBed.createComponent(AppComponent);
+ const app = fixture.debugElement.componentInstance;
+ expect(app.title).toEqual('app');
+ }));
+
+ it('should render title in a h1 tag', async(() => {
+ const fixture = TestBed.createComponent(AppComponent);
+ fixture.detectChanges();
+ const compiled = fixture.debugElement.nativeElement;
+ expect(compiled.querySelector('h1').textContent).toContain('Welcome to app!');
+ }));
+});
diff --git a/dashboard/src/app/app.component.ts b/dashboard/src/app/app.component.ts
index 5410cc8..7b0f672 100644
--- a/dashboard/src/app/app.component.ts
+++ b/dashboard/src/app/app.component.ts
@@ -1,17 +1,10 @@
import { Component } from '@angular/core';
@Component({
- selector: 'my-app',
- template: `
-
- Dashboard
- Heroes
-
-
- `,
- styleUrls: [ './app.component.css' ]
+ selector: 'app-root',
+ templateUrl: './app.component.html',
+ styleUrls: ['./app.component.css']
})
-
export class AppComponent {
- title = 'Tour of Heroes';
+ title = 'app';
}
diff --git a/dashboard/src/app/app.module.ts b/dashboard/src/app/app.module.ts
index e84b0db..5e16db1 100644
--- a/dashboard/src/app/app.module.ts
+++ b/dashboard/src/app/app.module.ts
@@ -1,30 +1,23 @@
-import { NgModule } from '@angular/core';
-import { BrowserModule } from '@angular/platform-browser';
-import { FormsModule } from '@angular/forms';
-import { HttpModule } from '@angular/http';
+import { NgModule } from '@angular/core';
+import { BrowserModule } from '@angular/platform-browser';
+import { HttpModule } from '@angular/http';
-// Imports for loading & configuring the in-memory web api
-// import { InMemoryWebApiModule } from 'angular-in-memory-web-api';
-// import { InMemoryDataService } from './in-memory-data.service';
+import { AppComponent } from './app.component';
+import { DashboardComponent } from './dashboard.component';
+import { AlbumComponent } from './album/album.component';
+import { ArtistComponent } from './artist/artist.component';
-import { AppComponent } from './app.component';
-import { DashboardComponent } from './dashboard.component';
-import { AlbumComponent } from './album.component';
-import { ArtistComponent } from './artist.component';
-
-import { ElsService } from './els.service';
+import { ElsService } from './els.service';
import { AppRoutingModule } from './app-routing.module';
import { ConvertMsPipe } from './convertms.pipe';
-import { SortPipe } from './sortby.pipe';
+import { SortByPipe } from './sort-by.pipe';
@NgModule({
- imports: [
+ imports: [
BrowserModule,
- FormsModule,
HttpModule,
- // InMemoryWebApiModule.forRoot(InMemoryDataService),
AppRoutingModule
],
declarations: [
@@ -33,7 +26,7 @@ import { SortPipe } from './sortby.pipe';
AlbumComponent,
ArtistComponent,
ConvertMsPipe,
- SortPipe
+ SortByPipe
],
providers: [
ElsService
diff --git a/dashboard/src/app/artist.component.html b/dashboard/src/app/artist.component.html
deleted file mode 100644
index cb73cb1..0000000
--- a/dashboard/src/app/artist.component.html
+++ /dev/null
@@ -1,126 +0,0 @@
-
-
{{artistName}}
-
-
-
Debug Zone
- Returned song: {{songs.length}}
- Theorical song: {{ artist ? artist['Track Count'] : "" }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{artist.Rating}}/100
-
-
Rating
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{artist.Album?.length}}
-
-
Albums
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{artist['Track Count']}}
-
-
Songs
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{artist['Play Count']}} list.
-
-
~{{artist['Play Count'] / artist['Track Count'] | number:'1.0-0'}} listening avg.
-
Listening
-
-
-
-
-
-
-
-
-
-
-
- Name
- Album
- Year
- Artist
- Album Artist
- Play Count
-
-
-
-
- {{song['Track Number'] ? (("0" + song['Track Number']).slice(-2)) : "--"}}
- {{song.Name}}
- {{song.Album}}
- {{song.Year}}
- {{song.Artist}}
- {{song['Album Artist'] ? song['Album Artist'] : "-" }}
- {{song['Play Count']}}
-
-
-
-
-
- More...
-
-
-
-
-
-
-
-
-
-
diff --git a/dashboard/src/app/artist/artist.component.css b/dashboard/src/app/artist/artist.component.css
new file mode 100644
index 0000000..e69de29
diff --git a/dashboard/src/app/artist/artist.component.html b/dashboard/src/app/artist/artist.component.html
new file mode 100644
index 0000000..0b65489
--- /dev/null
+++ b/dashboard/src/app/artist/artist.component.html
@@ -0,0 +1,126 @@
+
+
{{artistName}}
+
+
+
Debug Zone
+ Returned song: {{songs.length}}
+ Theorical song: {{ artist ? artist['Track Count'] : "" }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{artist.Rating}}/100
+
+
Rating
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{artist.Album?.length}}
+
+
Albums
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{artist['Track Count']}}
+
+
Songs
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{artist['Play Count']}} list.
+
+
~{{artist['Play Count'] / artist['Track Count'] | number:'1.0-0'}} listening avg.
+
Listening
+
+
+
+
+
+
+
+
+
+
+
+ Name
+ Album
+ Year
+ Artist
+ Album Artist
+ Play Count
+
+
+
+
+ {{song['Track Number'] ? (("0" + song['Track Number']).slice(-2)) : "--"}}
+ {{song.Name}}
+ {{song.Album}}
+ {{song.Year}}
+ {{song.Artist}}
+ {{song['Album Artist'] ? song['Album Artist'] : "-" }}
+ {{song['Play Count']}}
+
+
+
+
+
+ More...
+
+
+
+
+
+
+
+
+
+
diff --git a/dashboard/src/app/artist/artist.component.spec.ts b/dashboard/src/app/artist/artist.component.spec.ts
new file mode 100644
index 0000000..bb94ade
--- /dev/null
+++ b/dashboard/src/app/artist/artist.component.spec.ts
@@ -0,0 +1,25 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { ArtistComponent } from './artist.component';
+
+describe('ArtistComponent', () => {
+ let component: ArtistComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ ArtistComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(ArtistComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should be created', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/dashboard/src/app/artist.component.ts b/dashboard/src/app/artist/artist.component.ts
similarity index 75%
rename from dashboard/src/app/artist.component.ts
rename to dashboard/src/app/artist/artist.component.ts
index 72d2822..6b8f468 100644
--- a/dashboard/src/app/artist.component.ts
+++ b/dashboard/src/app/artist/artist.component.ts
@@ -1,17 +1,17 @@
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Params } from '@angular/router';
-import { Location } from '@angular/common';
+import { Location } from '@angular/common';
-import { ElsService } from './els.service';
-import { Song } from './object/song';
-import { Artist } from './object/artist';
+import { ElsService } from './../els.service';
+import { Song } from './../object/song';
+import { Artist } from './../object/artist';
-import { SortPipe } from './sortby.pipe';
+import { SortByPipe } from './../sort-by.pipe';
@Component({
- selector: 'artist-component',
+ selector: 'app-artist-component',
templateUrl: './artist.component.html',
- styleUrls: [ './album.component.css', './dashboard.component.css' ]
+ styleUrls: [ './../album/album.component.css', './../dashboard.component.css' ]
})
export class ArtistComponent implements OnInit {
@@ -19,11 +19,11 @@ export class ArtistComponent implements OnInit {
songs: Array = [];
artist: Artist = new Artist();
// To activate button in interface var
- moreDataAvailable: boolean = false;
- atBottom: boolean = false;
- sortable: boolean = false;
+ moreDataAvailable = false;
+ atBottom = false;
+ sortable = false;
- lockLoadData: boolean = false;
+ lockLoadData = false;
constructor(
private elsService: ElsService,
@@ -41,7 +41,7 @@ export class ArtistComponent implements OnInit {
// TODO Duplicate code!
loadSongs(): void {
if (this.lockLoadData) {
- console.debug('Loading data locked');
+ console.log('Loading data locked');
return;
}
@@ -60,7 +60,7 @@ export class ArtistComponent implements OnInit {
this.songs.push(song);
});
}
- console.debug('Unlock load data');
+ console.log('Unlock load data');
this.lockLoadData = false;
}
);
@@ -93,7 +93,7 @@ export class ArtistComponent implements OnInit {
}
sort(): void {
- this.songs = new SortPipe().transform(this.songs, 'Year', 'Album', 'Track Number', 'Play Count');
+ this.songs = new SortByPipe().transform(this.songs, 'Year', 'Album', 'Track Number', 'Play Count');
this.sortable = false;
}
}
diff --git a/dashboard/src/app/convertms.pipe.spec.ts b/dashboard/src/app/convertms.pipe.spec.ts
new file mode 100644
index 0000000..6de5614
--- /dev/null
+++ b/dashboard/src/app/convertms.pipe.spec.ts
@@ -0,0 +1,8 @@
+import { ConvertmsPipe } from './convertms.pipe';
+
+describe('ConvertmsPipe', () => {
+ it('create an instance', () => {
+ const pipe = new ConvertmsPipe();
+ expect(pipe).toBeTruthy();
+ });
+});
diff --git a/dashboard/src/app/convertms.pipe.ts b/dashboard/src/app/convertms.pipe.ts
index 57c0d6a..48601c6 100644
--- a/dashboard/src/app/convertms.pipe.ts
+++ b/dashboard/src/app/convertms.pipe.ts
@@ -1,11 +1,14 @@
import { Pipe, PipeTransform } from '@angular/core';
-@Pipe({name: 'convertMs'})
+@Pipe({
+ name: 'convertMs'
+})
export class ConvertMsPipe implements PipeTransform {
+
transform(timeMs: number): string {
let x = timeMs / 1000;
- let seconds = Math.round(x % 60);
+ const seconds = Math.round(x % 60);
x /= 60;
let minutes = 0;
@@ -16,7 +19,7 @@ export class ConvertMsPipe implements PipeTransform {
if (x > 1) { hours = Math.round(x % 24); }
// TODO Enable/disable day
x /= 24;
- let days = Math.round(x);
+ const days = Math.round(x);
// Final string
let ret = '';
diff --git a/dashboard/src/app/dashboard.component.css b/dashboard/src/app/dashboard.component.css
index 77825c4..2ecca97 100644
--- a/dashboard/src/app/dashboard.component.css
+++ b/dashboard/src/app/dashboard.component.css
@@ -35,4 +35,4 @@
background-color: #9b59b6;
margin: 0 auto;
-}
\ No newline at end of file
+}
diff --git a/dashboard/src/app/dashboard.component.ts b/dashboard/src/app/dashboard.component.ts
index 8c7de06..86a22b5 100644
--- a/dashboard/src/app/dashboard.component.ts
+++ b/dashboard/src/app/dashboard.component.ts
@@ -5,19 +5,19 @@ import { Song } from './object/song';
import { Bucket } from './object/bucket';
@Component({
- selector: 'my-dashboard',
+ selector: 'app-dashboard',
templateUrl: './dashboard.component.html',
styleUrls: [ './dashboard.component.css' ]
})
export class DashboardComponent implements OnInit {
- totalTime: number = 0;
- totalSize: number = 0;
+ totalTime = 0;
+ totalSize = 0;
totalSizeSt = '';
- trackCountSong: number = 0;
- trackCountArtist: number = 0;
- trackCountAlbum: number = 0;
- neverListenSong: number = 0;
+ trackCountSong = 0;
+ trackCountArtist = 0;
+ trackCountAlbum = 0;
+ neverListenSong = 0;
topGenres: Bucket[] = [];
bottomGenres: Bucket[] = [];
@@ -61,13 +61,13 @@ export class DashboardComponent implements OnInit {
*/
convertSizeToString(size: number) {
- let units = ['Bytes', 'KiB', 'MiB', 'GiB', 'TiB'];
+ const units = ['Bytes', 'KiB', 'MiB', 'GiB', 'TiB'];
if (size === 0) {
return '0 Byte';
}
- let i = Math.floor(Math.log(size) / Math.log(1024));
+ const i = Math.floor(Math.log(size) / Math.log(1024));
let calcSize = size / Math.pow(1024, i);
calcSize = Math.round(calcSize * 100) / 100;
diff --git a/dashboard/src/app/els.service.spec.ts b/dashboard/src/app/els.service.spec.ts
new file mode 100644
index 0000000..0360410
--- /dev/null
+++ b/dashboard/src/app/els.service.spec.ts
@@ -0,0 +1,15 @@
+import { TestBed, inject } from '@angular/core/testing';
+
+import { ElsService } from './els.service';
+
+describe('ElsService', () => {
+ beforeEach(() => {
+ TestBed.configureTestingModule({
+ providers: [ElsService]
+ });
+ });
+
+ it('should be created', inject([ElsService], (service: ElsService) => {
+ expect(service).toBeTruthy();
+ }));
+});
diff --git a/dashboard/src/app/els.service.ts b/dashboard/src/app/els.service.ts
index 035b244..bb1da7f 100644
--- a/dashboard/src/app/els.service.ts
+++ b/dashboard/src/app/els.service.ts
@@ -1,11 +1,11 @@
-import { Injectable } from '@angular/core';
+import { Injectable } from '@angular/core';
import { Headers, Http } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/toPromise';
import 'rxjs/add/operator/map';
-import { Song } from './object/song';
+import { Song } from './object/song';
import { Album } from './object/album';
import { Artist } from './object/artist';
import { Bucket } from './object/bucket';
@@ -117,7 +117,7 @@ export class ElsService {
return res.json().hits.hits;
})
.map((hits: Array) => {
- let result: Array = [];
+ const result: Array = [];
hits.forEach((hit) => {
result.push(hit._source);
});
@@ -134,7 +134,7 @@ export class ElsService {
}
getAlbumSongs(albumName: string, from: number = 0): Observable {
- console.debug('getAlbumSongs- Album name: ' + albumName + ' - from: ' + from);
+ console.info('getAlbumSongs- Album name: ' + albumName + ' - from: ' + from);
return this.http
.post(this.elsUrl + 'song' + ElsService.ACTION_SEARCH,
JSON.stringify({
@@ -148,7 +148,7 @@ export class ElsService {
return res.json().hits.hits;
})
.map((hits: Array) => {
- let result: Array = [];
+ const result: Array = [];
hits.forEach((hit) => {
result.push(hit._source);
});
@@ -157,7 +157,7 @@ export class ElsService {
}
getArtistSongs(artistName: string, from: number = 0): Observable {
- console.debug('getArtistSongs- Artist name: ' + artistName + ' - from: ' + from);
+ console.info('getArtistSongs- Artist name: ' + artistName + ' - from: ' + from);
return this.http
.post(this.elsUrl + 'song' + ElsService.ACTION_SEARCH,
JSON.stringify({
@@ -176,7 +176,7 @@ export class ElsService {
return res.json().hits.hits;
})
.map((hits: Array) => {
- let result: Array = [];
+ const result: Array = [];
hits.forEach((hit) => {
result.push(hit._source);
});
@@ -251,7 +251,7 @@ export class ElsService {
}), {headers: this.headers})
.map(res => res.json().aggregations.genres.buckets)
.map((hits: Array) => {
- let result: Array = [];
+ const result: Array = [];
hits.forEach((bucket) => {
result.push(bucket);
});
diff --git a/dashboard/src/app/object/album.ts b/dashboard/src/app/object/album.ts
index be5d3f8..ae7b88b 100644
--- a/dashboard/src/app/object/album.ts
+++ b/dashboard/src/app/object/album.ts
@@ -4,10 +4,10 @@ export class Album {
Artist: Array;
Rating: number;
Genre: Array;
- "Track Count": number;
- "Album Rating": number;
- "Persistent ID": string;
- "Album Rating Computed": boolean;
- "Play Count": number;
- "Total Time": number;
-}
\ No newline at end of file
+ 'Track Count': number;
+ 'Album Rating': number;
+ 'Persistent ID': string;
+ 'Album Rating Computed': boolean;
+ 'Play Count': number;
+ 'Total Time': number;
+}
diff --git a/dashboard/src/app/object/artist.ts b/dashboard/src/app/object/artist.ts
index 35a5417..2abb0e4 100644
--- a/dashboard/src/app/object/artist.ts
+++ b/dashboard/src/app/object/artist.ts
@@ -4,7 +4,7 @@ export class Artist {
Artist: string;
Rating: number;
Genre: Array;
- "Track Count": number;
- "Persistent ID": string;
- "Play Count": number;
-}
\ No newline at end of file
+ 'Track Count': number;
+ 'Persistent ID': string;
+ 'Play Count': number;
+}
diff --git a/dashboard/src/app/object/bucket.ts b/dashboard/src/app/object/bucket.ts
index 68fde47..54da595 100644
--- a/dashboard/src/app/object/bucket.ts
+++ b/dashboard/src/app/object/bucket.ts
@@ -1,4 +1,4 @@
export class Bucket {
key: string;
doc_count: number;
-}
\ No newline at end of file
+}
diff --git a/dashboard/src/app/object/song.ts b/dashboard/src/app/object/song.ts
index 0f98ba1..1181149 100644
--- a/dashboard/src/app/object/song.ts
+++ b/dashboard/src/app/object/song.ts
@@ -1,7 +1,7 @@
export class Song {
Name: string;
Artist: string;
- "Play Count": number;
+ 'Play Count': number;
Album: string;
- "Track Number": number; // TODO Default property
-}
\ No newline at end of file
+ 'Track Number': number; // TODO Default property
+}
diff --git a/dashboard/src/app/sort-by.pipe.spec.ts b/dashboard/src/app/sort-by.pipe.spec.ts
new file mode 100644
index 0000000..7c86419
--- /dev/null
+++ b/dashboard/src/app/sort-by.pipe.spec.ts
@@ -0,0 +1,8 @@
+import { SortByPipe } from './sort-by.pipe';
+
+describe('SortByPipe', () => {
+ it('create an instance', () => {
+ const pipe = new SortByPipe();
+ expect(pipe).toBeTruthy();
+ });
+});
diff --git a/dashboard/src/app/sortby.pipe.ts b/dashboard/src/app/sort-by.pipe.ts
similarity index 60%
rename from dashboard/src/app/sortby.pipe.ts
rename to dashboard/src/app/sort-by.pipe.ts
index e8af7d1..6a1245f 100644
--- a/dashboard/src/app/sortby.pipe.ts
+++ b/dashboard/src/app/sort-by.pipe.ts
@@ -1,14 +1,14 @@
-// Thank to http://4dev.tech/2016/09/angular2-how-to-sort-a-json-dataset-by-field/ for the pipe
-// Thank to http://stackoverflow.com/questions/28560801/javascript-sorting-array-by-multiple-criteria for the multi-args part
-
import { Pipe, PipeTransform } from '@angular/core';
-@Pipe({name: 'sortBy'})
-export class SortPipe implements PipeTransform {
+@Pipe({
+ name: 'sortBy'
+})
+export class SortByPipe implements PipeTransform {
+
transform(array: Array, ...args: any[]): Array {
array.sort((a: any, b: any) => {
for (let i = 0; i < array.length; i++) {
- let arg = args[i];
+ const arg = args[i];
if (a[arg] === undefined && b[arg] !== undefined) { return -1; }
if (a[arg] !== undefined && b[arg] === undefined) { return 1; }
@@ -20,4 +20,5 @@ export class SortPipe implements PipeTransform {
});
return array;
}
+
}
diff --git a/dashboard/src/assets/.gitkeep b/dashboard/src/assets/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/dashboard/src/environments/environment.prod.ts b/dashboard/src/environments/environment.prod.ts
new file mode 100644
index 0000000..3612073
--- /dev/null
+++ b/dashboard/src/environments/environment.prod.ts
@@ -0,0 +1,3 @@
+export const environment = {
+ production: true
+};
diff --git a/dashboard/src/environments/environment.ts b/dashboard/src/environments/environment.ts
new file mode 100644
index 0000000..b7f639a
--- /dev/null
+++ b/dashboard/src/environments/environment.ts
@@ -0,0 +1,8 @@
+// The file contents for the current environment will overwrite these during build.
+// The build system defaults to the dev environment which uses `environment.ts`, but if you do
+// `ng build --env=prod` then `environment.prod.ts` will be used instead.
+// The list of which env maps to which file can be found in `.angular-cli.json`.
+
+export const environment = {
+ production: false
+};
diff --git a/dashboard/src/index.html b/dashboard/src/index.html
index 0cb8751..2f553d9 100644
--- a/dashboard/src/index.html
+++ b/dashboard/src/index.html
@@ -1,29 +1,14 @@
-
-
-
- Music Dashboard
-
-
-
-
+
+
+
+
+ Dashboard
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Loading AppComponent content here ...
-
+
+
+
+
+
+
diff --git a/dashboard/src/main.js b/dashboard/src/main.js
deleted file mode 100644
index b668eef..0000000
--- a/dashboard/src/main.js
+++ /dev/null
@@ -1,5 +0,0 @@
-"use strict";
-var platform_browser_dynamic_1 = require("@angular/platform-browser-dynamic");
-var app_module_1 = require("./app/app.module");
-platform_browser_dynamic_1.platformBrowserDynamic().bootstrapModule(app_module_1.AppModule);
-//# sourceMappingURL=main.js.map
\ No newline at end of file
diff --git a/dashboard/src/main.js.map b/dashboard/src/main.js.map
deleted file mode 100644
index 0326ae4..0000000
--- a/dashboard/src/main.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"main.js","sourceRoot":"","sources":["main.ts"],"names":[],"mappings":";AAAA,8EAA2E;AAE3E,+CAA6C;AAE7C,iDAAsB,EAAE,CAAC,eAAe,CAAC,sBAAS,CAAC,CAAC"}
\ No newline at end of file
diff --git a/dashboard/src/main.ts b/dashboard/src/main.ts
index 311c44b..a9ca1ca 100644
--- a/dashboard/src/main.ts
+++ b/dashboard/src/main.ts
@@ -1,5 +1,11 @@
+import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
+import { environment } from './environments/environment';
+
+if (environment.production) {
+ enableProdMode();
+}
platformBrowserDynamic().bootstrapModule(AppModule);
diff --git a/dashboard/src/polyfills.ts b/dashboard/src/polyfills.ts
new file mode 100644
index 0000000..7831e97
--- /dev/null
+++ b/dashboard/src/polyfills.ts
@@ -0,0 +1,72 @@
+/**
+ * This file includes polyfills needed by Angular and is loaded before the app.
+ * You can add your own extra polyfills to this file.
+ *
+ * This file is divided into 2 sections:
+ * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers.
+ * 2. Application imports. Files imported after ZoneJS that should be loaded before your main
+ * file.
+ *
+ * The current setup is for so-called "evergreen" browsers; the last versions of browsers that
+ * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera),
+ * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile.
+ *
+ * Learn more in https://angular.io/docs/ts/latest/guide/browser-support.html
+ */
+
+/***************************************************************************************************
+ * BROWSER POLYFILLS
+ */
+
+/** IE9, IE10 and IE11 requires all of the following polyfills. **/
+// import 'core-js/es6/symbol';
+// import 'core-js/es6/object';
+// import 'core-js/es6/function';
+// import 'core-js/es6/parse-int';
+// import 'core-js/es6/parse-float';
+// import 'core-js/es6/number';
+// import 'core-js/es6/math';
+// import 'core-js/es6/string';
+// import 'core-js/es6/date';
+// import 'core-js/es6/array';
+// import 'core-js/es6/regexp';
+// import 'core-js/es6/map';
+// import 'core-js/es6/weak-map';
+// import 'core-js/es6/set';
+
+/** IE10 and IE11 requires the following for NgClass support on SVG elements */
+// import 'classlist.js'; // Run `npm install --save classlist.js`.
+
+/** Evergreen browsers require these. **/
+import 'core-js/es6/reflect';
+import 'core-js/es7/reflect';
+
+
+/**
+ * Required to support Web Animations `@angular/animation`.
+ * Needed for: All but Chrome, Firefox and Opera. http://caniuse.com/#feat=web-animation
+ **/
+// import 'web-animations-js'; // Run `npm install --save web-animations-js`.
+
+
+
+/***************************************************************************************************
+ * Zone JS is required by Angular itself.
+ */
+import 'zone.js/dist/zone'; // Included with Angular CLI.
+
+
+
+/***************************************************************************************************
+ * APPLICATION IMPORTS
+ */
+
+/**
+ * Date, currency, decimal and percent pipes.
+ * Needed for: All but Chrome, Firefox, Edge, IE11 and Safari 10
+ */
+// import 'intl'; // Run `npm install --save intl`.
+/**
+ * Need to import at least one locale-data with intl.
+ */
+// import 'intl/locale-data/jsonp/en';
diff --git a/dashboard/src/systemjs-angular-loader.js b/dashboard/src/systemjs-angular-loader.js
deleted file mode 100644
index 8b10054..0000000
--- a/dashboard/src/systemjs-angular-loader.js
+++ /dev/null
@@ -1,49 +0,0 @@
-var templateUrlRegex = /templateUrl\s*:(\s*['"`](.*?)['"`]\s*)/gm;
-var stylesRegex = /styleUrls *:(\s*\[[^\]]*?\])/g;
-var stringRegex = /(['`"])((?:[^\\]\\\1|.)*?)\1/g;
-
-module.exports.translate = function(load){
- if (load.source.indexOf('moduleId') != -1) return load;
-
- var url = document.createElement('a');
- url.href = load.address;
-
- var basePathParts = url.pathname.split('/');
-
- basePathParts.pop();
- var basePath = basePathParts.join('/');
-
- var baseHref = document.createElement('a');
- baseHref.href = this.baseURL;
- baseHref = baseHref.pathname;
-
- if (!baseHref.startsWith('/base/')) { // it is not karma
- basePath = basePath.replace(baseHref, '');
- }
-
- load.source = load.source
- .replace(templateUrlRegex, function(match, quote, url){
- var resolvedUrl = url;
-
- if (url.startsWith('.')) {
- resolvedUrl = basePath + url.substr(1);
- }
-
- return 'templateUrl: "' + resolvedUrl + '"';
- })
- .replace(stylesRegex, function(match, relativeUrls) {
- var urls = [];
-
- while ((match = stringRegex.exec(relativeUrls)) !== null) {
- if (match[2].startsWith('.')) {
- urls.push('"' + basePath + match[2].substr(1) + '"');
- } else {
- urls.push('"' + match[2] + '"');
- }
- }
-
- return "styleUrls: [" + urls.join(', ') + "]";
- });
-
- return load;
-};
diff --git a/dashboard/src/systemjs.config.extras.js b/dashboard/src/systemjs.config.extras.js
deleted file mode 100644
index 027dfe5..0000000
--- a/dashboard/src/systemjs.config.extras.js
+++ /dev/null
@@ -1,11 +0,0 @@
-/**
- * Add barrels and stuff
- * Adjust as necessary for your application needs.
- */
-// (function (global) {
-// System.config({
-// packages: {
-// // add packages here
-// }
-// });
-// })(this);
diff --git a/dashboard/src/systemjs.config.js b/dashboard/src/systemjs.config.js
deleted file mode 100644
index 129704a..0000000
--- a/dashboard/src/systemjs.config.js
+++ /dev/null
@@ -1,45 +0,0 @@
-/**
- * System configuration for Angular samples
- * Adjust as necessary for your application needs.
- */
-(function (global) {
- System.config({
- paths: {
- // paths serve as alias
- 'npm:': 'node_modules/'
- },
- // map tells the System loader where to look for things
- map: {
- // our app is within the app folder
- 'app': 'app',
-
- // angular bundles
- '@angular/core': 'npm:@angular/core/bundles/core.umd.js',
- '@angular/common': 'npm:@angular/common/bundles/common.umd.js',
- '@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js',
- '@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js',
- '@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
- '@angular/http': 'npm:@angular/http/bundles/http.umd.js',
- '@angular/router': 'npm:@angular/router/bundles/router.umd.js',
- '@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js',
-
- // other libraries
- 'rxjs': 'npm:rxjs',
- 'angular-in-memory-web-api': 'npm:angular-in-memory-web-api/bundles/in-memory-web-api.umd.js'
- },
- // packages tells the System loader how to load when no filename and/or no extension
- packages: {
- app: {
- defaultExtension: 'js',
- meta: {
- './*.js': {
- loader: 'systemjs-angular-loader.js'
- }
- }
- },
- rxjs: {
- defaultExtension: 'js'
- }
- }
- });
-})(this);
diff --git a/dashboard/src/test.ts b/dashboard/src/test.ts
new file mode 100644
index 0000000..cd612ee
--- /dev/null
+++ b/dashboard/src/test.ts
@@ -0,0 +1,32 @@
+// This file is required by karma.conf.js and loads recursively all the .spec and framework files
+
+import 'zone.js/dist/long-stack-trace-zone';
+import 'zone.js/dist/proxy.js';
+import 'zone.js/dist/sync-test';
+import 'zone.js/dist/jasmine-patch';
+import 'zone.js/dist/async-test';
+import 'zone.js/dist/fake-async-test';
+import { getTestBed } from '@angular/core/testing';
+import {
+ BrowserDynamicTestingModule,
+ platformBrowserDynamicTesting
+} from '@angular/platform-browser-dynamic/testing';
+
+// Unfortunately there's no typing for the `__karma__` variable. Just declare it as any.
+declare const __karma__: any;
+declare const require: any;
+
+// Prevent Karma from running prematurely.
+__karma__.loaded = function () {};
+
+// First, initialize the Angular testing environment.
+getTestBed().initTestEnvironment(
+ BrowserDynamicTestingModule,
+ platformBrowserDynamicTesting()
+);
+// Then we find all the tests.
+const context = require.context('./', true, /\.spec\.ts$/);
+// And load the modules.
+context.keys().map(context);
+// Finally, start Karma to run the tests.
+__karma__.start();
diff --git a/dashboard/src/tsconfig.app.json b/dashboard/src/tsconfig.app.json
new file mode 100644
index 0000000..39ba8db
--- /dev/null
+++ b/dashboard/src/tsconfig.app.json
@@ -0,0 +1,13 @@
+{
+ "extends": "../tsconfig.json",
+ "compilerOptions": {
+ "outDir": "../out-tsc/app",
+ "baseUrl": "./",
+ "module": "es2015",
+ "types": []
+ },
+ "exclude": [
+ "test.ts",
+ "**/*.spec.ts"
+ ]
+}
diff --git a/dashboard/src/tsconfig.json b/dashboard/src/tsconfig.json
deleted file mode 100644
index 2c7260d..0000000
--- a/dashboard/src/tsconfig.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "compilerOptions": {
- "target": "es5",
- "module": "commonjs",
- "moduleResolution": "node",
- "sourceMap": true,
- "emitDecoratorMetadata": true,
- "experimentalDecorators": true,
- "lib": [ "es2015", "dom" ],
- "noImplicitAny": true,
- "suppressImplicitAnyIndexErrors": true
- }
-}
diff --git a/dashboard/src/tsconfig.spec.json b/dashboard/src/tsconfig.spec.json
new file mode 100644
index 0000000..63d89ff
--- /dev/null
+++ b/dashboard/src/tsconfig.spec.json
@@ -0,0 +1,20 @@
+{
+ "extends": "../tsconfig.json",
+ "compilerOptions": {
+ "outDir": "../out-tsc/spec",
+ "baseUrl": "./",
+ "module": "commonjs",
+ "target": "es5",
+ "types": [
+ "jasmine",
+ "node"
+ ]
+ },
+ "files": [
+ "test.ts"
+ ],
+ "include": [
+ "**/*.spec.ts",
+ "**/*.d.ts"
+ ]
+}
diff --git a/dashboard/src/typings.d.ts b/dashboard/src/typings.d.ts
new file mode 100644
index 0000000..ef5c7bd
--- /dev/null
+++ b/dashboard/src/typings.d.ts
@@ -0,0 +1,5 @@
+/* SystemJS module definition */
+declare var module: NodeModule;
+interface NodeModule {
+ id: string;
+}
diff --git a/dashboard/tsconfig.json b/dashboard/tsconfig.json
new file mode 100644
index 0000000..a6c016b
--- /dev/null
+++ b/dashboard/tsconfig.json
@@ -0,0 +1,19 @@
+{
+ "compileOnSave": false,
+ "compilerOptions": {
+ "outDir": "./dist/out-tsc",
+ "sourceMap": true,
+ "declaration": false,
+ "moduleResolution": "node",
+ "emitDecoratorMetadata": true,
+ "experimentalDecorators": true,
+ "target": "es5",
+ "typeRoots": [
+ "node_modules/@types"
+ ],
+ "lib": [
+ "es2017",
+ "dom"
+ ]
+ }
+}
diff --git a/dashboard/tslint.json b/dashboard/tslint.json
index 004c941..cb76b40 100644
--- a/dashboard/tslint.json
+++ b/dashboard/tslint.json
@@ -1,5 +1,10 @@
{
+ "rulesDirectory": [
+ "node_modules/codelyzer"
+ ],
"rules": {
+ "arrow-return-shorthand": true,
+ "callable-types": true,
"class-name": true,
"comment-format": [
true,
@@ -8,12 +13,17 @@
"curly": true,
"eofline": true,
"forin": true,
+ "import-blacklist": [
+ true,
+ "rxjs"
+ ],
+ "import-spacing": true,
"indent": [
true,
"spaces"
],
+ "interface-over-type-literal": true,
"label-position": true,
- "label-undefined": true,
"max-line-length": [
true,
140
@@ -21,32 +31,43 @@
"member-access": false,
"member-ordering": [
true,
- "static-before-instance",
- "variables-before-functions"
+ {
+ "order": [
+ "static-field",
+ "instance-field",
+ "static-method",
+ "instance-method"
+ ]
+ }
],
"no-arg": true,
"no-bitwise": true,
"no-console": [
- false,
+ true,
"debug",
- "info",
"time",
"timeEnd",
"trace"
],
"no-construct": true,
"no-debugger": true,
- "no-duplicate-key": true,
- "no-duplicate-variable": true,
+ "no-duplicate-super": true,
"no-empty": false,
+ "no-empty-interface": true,
"no-eval": true,
+ "no-inferrable-types": [
+ true,
+ "ignore-params"
+ ],
+ "no-misused-new": true,
+ "no-non-null-assertion": true,
"no-shadowed-variable": true,
"no-string-literal": false,
+ "no-string-throw": true,
"no-switch-case-fall-through": true,
"no-trailing-whitespace": true,
+ "no-unnecessary-initializer": true,
"no-unused-expression": true,
- "no-unused-variable": true,
- "no-unreachable": true,
"no-use-before-declare": true,
"no-var-keyword": true,
"object-literal-sort-keys": false,
@@ -57,12 +78,14 @@
"check-else",
"check-whitespace"
],
+ "prefer-const": true,
"quotemark": [
true,
"single"
],
"radix": true,
"semicolon": [
+ true,
"always"
],
"triple-equals": [
@@ -79,6 +102,8 @@
"variable-declaration": "nospace"
}
],
+ "typeof-compare": true,
+ "unified-signatures": true,
"variable-name": false,
"whitespace": [
true,
@@ -87,6 +112,30 @@
"check-operator",
"check-separator",
"check-type"
- ]
+ ],
+ "directive-selector": [
+ true,
+ "attribute",
+ "app",
+ "camelCase"
+ ],
+ "component-selector": [
+ true,
+ "element",
+ "app",
+ "kebab-case"
+ ],
+ "use-input-property-decorator": true,
+ "use-output-property-decorator": true,
+ "use-host-property-decorator": true,
+ "no-input-rename": true,
+ "no-output-rename": true,
+ "use-life-cycle-interface": true,
+ "use-pipe-transform-interface": true,
+ "component-class-suffix": true,
+ "directive-class-suffix": true,
+ "no-access-missing-member": true,
+ "templates-use-public": true,
+ "invoke-injectable": true
}
}