diff options
author | Sebastien Douheret <sebastien.douheret@iot.bzh> | 2017-11-10 16:29:10 +0100 |
---|---|---|
committer | Sebastien Douheret <sebastien.douheret@iot.bzh> | 2017-11-10 16:36:12 +0100 |
commit | fb2f6b918beb0a994ad304bfd678ef0c5c562210 (patch) | |
tree | 21c64ee76658b2e68559891ba317cb893afd2d44 /webapp | |
parent | c51d5034d527578da70bdd41b9ce13f28455c598 (diff) |
Moved Dashboad webapp on Angular 5 !
Webapp loading time decreased from 2.7s to 1.5sec !
Signed-off-by: Sebastien Douheret <sebastien.douheret@iot.bzh>
Diffstat (limited to 'webapp')
60 files changed, 997 insertions, 834 deletions
diff --git a/webapp/.angular-cli.json b/webapp/.angular-cli.json new file mode 100644 index 0000000..202ea80 --- /dev/null +++ b/webapp/.angular-cli.json @@ -0,0 +1,62 @@ +{ + "$schema": "./node_modules/@angular/cli/lib/config/schema.json", + "project": { + "name": "xds-dashboard" + }, + "apps": [ + { + "root": "src", + "outDir": "dist", + "assets": [ + "assets" + ], + "index": "index.html", + "main": "main.ts", + "polyfills": "polyfills.ts", + "test": "test.ts", + "tsconfig": "tsconfig.app.json", + "testTsconfig": "tsconfig.spec.json", + "prefix": "xds", + "styles": [ + "styles.css", + "../node_modules/font-awesome/css/font-awesome.min.css", + "../node_modules/font-awesome-animation/dist/font-awesome-animation.min.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/webapp/.jshintrc b/webapp/.jshintrc new file mode 100644 index 0000000..7a0ae5c --- /dev/null +++ b/webapp/.jshintrc @@ -0,0 +1,7 @@ +{ + "esversion": 6, + "undef": true, + "unused": false, + "globalstrict": true, + "predef": [ "console", "require", "module", "setInterval", "clearInterval", "__dirname"] +}
\ No newline at end of file diff --git a/webapp/gulp.conf.js b/webapp/gulp.conf.js deleted file mode 100644 index 2e8fa17..0000000 --- a/webapp/gulp.conf.js +++ /dev/null @@ -1,34 +0,0 @@ -"use strict"; - -module.exports = { - prodMode: process.env.PRODUCTION || false, - outDir: "dist", - paths: { - tsSources: ["src/**/*.ts"], - srcDir: "src", - assets: ["assets/**"], - node_modules_libs: [ - 'core-js/client/shim.min.js', - 'reflect-metadata/Reflect.js', - 'rxjs-system-bundle/*.min.js', - 'socket.io-client/dist/socket.io*.js', - 'systemjs/dist/system-polyfills.js', - 'systemjs/dist/system.src.js', - 'zone.js/dist/**', - '@angular/**/bundles/**', - 'ngx-cookie/bundles/**', - 'ngx-bootstrap/bundles/**', - 'bootstrap/dist/**', - 'moment/*.min.js', - 'font-awesome-animation/dist/font-awesome-animation.min.css', - 'font-awesome/css/font-awesome.min.css', - 'font-awesome/fonts/**' - ] - }, - deploy: { - target_ip: 'ip', - username: "user", - //port: 6666, - dir: '/tmp/xds-agent' - } -} diff --git a/webapp/gulpfile.js b/webapp/gulpfile.js deleted file mode 100644 index 0226380..0000000 --- a/webapp/gulpfile.js +++ /dev/null @@ -1,123 +0,0 @@ -"use strict"; -//FIXME in VSC/eslint or add to typings declare function require(v: string): any; - -// FIXME: Rework based on -// https://github.com/iotbzh/app-framework-templates/blob/master/templates/hybrid-html5/gulpfile.js -// AND -// https://github.com/antonybudianto/angular-starter -// and/or -// https://github.com/smmorneau/tour-of-heroes/blob/master/gulpfile.js - -const gulp = require("gulp"), - gulpif = require('gulp-if'), - del = require("del"), - sourcemaps = require('gulp-sourcemaps'), - tsc = require("gulp-typescript"), - tsProject = tsc.createProject("tsconfig.json"), - tslint = require('gulp-tslint'), - gulpSequence = require('gulp-sequence'), - rsync = require('gulp-rsync'), - conf = require('./gulp.conf'); - - -var tslintJsonFile = "./tslint.json" -if (conf.prodMode) { - tslintJsonFile = "./tslint.prod.json" -} - - -/** - * Remove output directory. - */ -gulp.task('clean', (cb) => { - return del([conf.outDir], cb); -}); - -/** - * Lint all custom TypeScript files. - */ -gulp.task('tslint', function() { - return gulp.src(conf.paths.tsSources) - .pipe(tslint({ - formatter: 'verbose', - configuration: tslintJsonFile - })) - .pipe(tslint.report()); -}); - -/** - * Compile TypeScript sources and create sourcemaps in build directory. - */ -gulp.task("compile", ["tslint"], function() { - var tsResult = gulp.src(conf.paths.tsSources) - .pipe(sourcemaps.init()) - .pipe(tsProject()); - return tsResult.js - .pipe(sourcemaps.write(".", { sourceRoot: '/src' })) - .pipe(gulp.dest(conf.outDir)); -}); - -/** - * Copy all resources that are not TypeScript files into build directory. - */ -gulp.task("resources", function() { - return gulp.src(["src/**/*", "!**/*.ts"]) - .pipe(gulp.dest(conf.outDir)); -}); - -/** - * Copy all assets into build directory. - */ -gulp.task("assets", function() { - return gulp.src(conf.paths.assets) - .pipe(gulp.dest(conf.outDir + "/assets")); -}); - -/** - * Copy all required libraries into build directory. - */ -gulp.task("libs", function() { - return gulp.src(conf.paths.node_modules_libs, - { cwd: "node_modules/**" }) /* Glob required here. */ - .pipe(gulp.dest(conf.outDir + "/lib")); -}); - -/** - * Watch for changes in TypeScript, HTML and CSS files. - */ -gulp.task('watch', function () { - gulp.watch([conf.paths.tsSources], ['compile']).on('change', function (e) { - console.log('TypeScript file ' + e.path + ' has been changed. Compiling.'); - }); - gulp.watch(["src/**/*.html", "src/**/*.css"], ['resources']).on('change', function (e) { - console.log('Resource file ' + e.path + ' has been changed. Updating.'); - }); -}); - -/** - * Build the project. - */ -gulp.task("build", ['compile', 'resources', 'libs', 'assets'], function() { - console.log("Building the project ..."); -}); - -/** - * Deploy the project on another machine/container - */ -gulp.task('rsync', function () { - return gulp.src(conf.outDir) - .pipe(rsync({ - root: conf.outDir, - username: conf.deploy.username, - hostname: conf.deploy.target_ip, - port: conf.deploy.port || null, - archive: true, - recursive: true, - compress: true, - progress: false, - incremental: true, - destination: conf.deploy.dir - })); -}); - -gulp.task('deploy', gulpSequence('build', 'rsync'));
\ No newline at end of file diff --git a/webapp/package.json b/webapp/package.json index 9c22f6b..f4f843f 100644 --- a/webapp/package.json +++ b/webapp/package.json @@ -2,12 +2,13 @@ "name": "xds-dashboard", "version": "1.0.0", "description": "X (cross) Development System dashboard", - "scripts": { - "clean": "gulp clean", - "compile": "gulp compile", - "build": "gulp build", - "start": "concurrently --kill-others \"gulp watch\" \"lite-server\"" - }, + "keywords": [ + "XDS", + "AGL", + "IoT.bzh", + "angular", + "HTML5" + ], "repository": { "type": "git", "url": "https://github.com/iotbzh/xds-agent" @@ -17,16 +18,27 @@ "bugs": { "url": "https://github.com/iotbzh/xds-agent/issues" }, + "scripts": { + "build": "ng build --prod --verbose", + "start": "ng serve --prod --port=8000", + "watch": "ng build --preserve-symlinks --watch", + "server": "node server/server.js", + "ng": "ng", + "test": "ng test", + "lint": "ng lint", + "e2e": "ng e2e" + }, "dependencies": { - "@angular/common": "2.4.4", - "@angular/compiler": "2.4.4", - "@angular/core": "2.4.4", - "@angular/forms": "2.4.4", - "@angular/http": "2.4.4", - "@angular/platform-browser": "2.4.4", - "@angular/platform-browser-dynamic": "2.4.4", - "@angular/router": "3.4.4", - "@angular/upgrade": "2.4.4", + "@angular/animations": "5.0.1", + "@angular/common": "5.0.1", + "@angular/compiler": "5.0.1", + "@angular/core": "5.0.1", + "@angular/forms": "5.0.1", + "@angular/platform-browser": "5.0.1", + "@angular/platform-browser-dynamic": "5.0.1", + "@angular/router": "5.0.1", + "@ngx-translate/core": "^8.0.0", + "@ngx-translate/http-loader": "^2.0.0", "@types/core-js": "0.9.35", "@types/node": "7.0.5", "@types/socket.io-client": "^1.4.29", @@ -34,30 +46,39 @@ "core-js": "^2.4.1", "font-awesome": "^4.7.0", "font-awesome-animation": "0.0.10", - "ngx-bootstrap": "1.6.6", + "ng2-file-upload": "^1.2.0", + "ngx-bootstrap": "^2.0.0-beta.7", "ngx-cookie": "^1.0.0", "reflect-metadata": "^0.1.8", - "rxjs": "5.0.3", - "rxjs-system-bundle": "5.0.3", + "rxjs": "5.5.2", "socket.io-client": "^1.7.3", "socketio": "^1.0.0", "systemjs": "0.20.0", - "zone.js": "^0.7.6" + "zone.js": "^0.8.16" }, "devDependencies": { - "concurrently": "^3.1.0", - "del": "^2.2.0", - "gulp": "^3.9.1", - "gulp-if": "2.0.2", - "gulp-rsync": "0.0.7", - "gulp-sequence": "^0.4.6", - "gulp-sourcemaps": "^1.9.1", - "gulp-tslint": "^7.0.1", - "gulp-typescript": "^3.1.3", - "lite-server": "^2.2.2", - "ts-node": "^1.7.2", - "tslint": "^4.0.2", - "typescript": "^2.2.1", + "@angular/cli": "1.5.0", + "@angular/compiler-cli": "5.0.1", + "@angular/language-service": "5.0.1", + "@types/jasmine": "~2.5.53", + "@types/jasminewd2": "~2.0.2", + "@types/node": "~6.0.60", + "codelyzer": "~4.0.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", + "nodemon": "1.11.0", + "protractor": "~5.1.2", + "pump": "^1.0.2", + "ts-loader": "1.3.0", + "ts-node": "~3.2.0", + "tslint": "~5.4.3", + "typescript": "~2.4.0", "typings": "^2.0.0" } } diff --git a/webapp/src/app/alert/alert.component.spec.ts b/webapp/src/app/alert/alert.component.spec.ts new file mode 100644 index 0000000..3921dd6 --- /dev/null +++ b/webapp/src/app/alert/alert.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { AlertComponent } from './alert.component'; + +describe('AlertComponent', () => { + let component: AlertComponent; + let fixture: ComponentFixture<AlertComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ AlertComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(AlertComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/webapp/src/app/alert/alert.component.ts b/webapp/src/app/alert/alert.component.ts index 672d7bf..06c9bf5 100644 --- a/webapp/src/app/alert/alert.component.ts +++ b/webapp/src/app/alert/alert.component.ts @@ -1,18 +1,19 @@ -import { Component } from '@angular/core'; -import { Observable } from 'rxjs'; +import { Component, ViewEncapsulation } from '@angular/core'; +import { Observable } from 'rxjs/Observable'; -import {AlertService, IAlert} from '../services/alert.service'; +import { AlertService, IAlert } from '../services/alert.service'; @Component({ selector: 'app-alert', template: ` - <div style="width:80%; margin-left:auto; margin-right:auto;" *ngFor="let alert of (alerts$ | async)"> - <alert *ngIf="alert.show" [type]="alert.type" [dismissible]="alert.dismissible" [dismissOnTimeout]="alert.dismissTimeout" - (onClose)="onClose(alert)"> - <div style="text-align:center;" [innerHtml]="alert.msg"></div> - </alert> - </div> - ` + <div style="width:80%; margin-left:auto; margin-right:auto;" + *ngFor="let alert of (alerts$ | async)"> + <alert *ngIf="alert.show" [type]="alert.type" [dismissible]="alert.dismissible" [dismissOnTimeout]="alert.dismissTimeout" + (onClose)="onClose(alert)"> + <div style="text-align:center;" [innerHtml]="alert.msg"></div> + </alert> + </div> +`, }) export class AlertComponent { diff --git a/webapp/src/app/app-routing.module.ts b/webapp/src/app/app-routing.module.ts new file mode 100644 index 0000000..36629de --- /dev/null +++ b/webapp/src/app/app-routing.module.ts @@ -0,0 +1,18 @@ +import { NgModule } from '@angular/core'; +import { Routes, RouterModule } from '@angular/router'; +import { HomeComponent } from './home/home.component'; +import { ConfigComponent } from './config/config.component'; +import { DevelComponent } from './devel/devel.component'; + +const routes: Routes = [ + { path: 'config', component: ConfigComponent, data: { title: 'Config' } }, + { path: 'home', component: HomeComponent, data: { title: 'Home' } }, + { path: 'devel', component: DevelComponent, data: { title: 'Build & Deploy' } }, + { path: '**', component: HomeComponent } +]; + +@NgModule({ + imports: [RouterModule.forRoot(routes)], + exports: [RouterModule] +}) +export class AppRoutingModule { } diff --git a/webapp/src/app/app.component.ts b/webapp/src/app/app.component.ts index 40cfb24..0d1ce12 100644 --- a/webapp/src/app/app.component.ts +++ b/webapp/src/app/app.component.ts @@ -1,37 +1,45 @@ -import { Component, OnInit, OnDestroy } from "@angular/core"; -import { Router } from '@angular/router'; -//TODO import {TranslateService} from "ng2-translate"; +import { Component, OnInit, OnDestroy } from '@angular/core'; +import { TranslateService } from '@ngx-translate/core'; +import { ConfigService, IConfig } from './services/config.service'; @Component({ - selector: 'app', - templateUrl: './app/app.component.html', - styleUrls: ['./app/app.component.css'] + selector: 'app-root', + templateUrl: 'app.component.html', + styleUrls: ['app.component.css'] }) export class AppComponent implements OnInit, OnDestroy { + private defaultLanguage = 'en'; + public isCollapsed = true; - isCollapsed: boolean = true; - - private defaultLanguage: string = 'en'; - - // I initialize the app component. - //TODO constructor(private translate: TranslateService) { - constructor(public router: Router) { + constructor(private translate: TranslateService, private configSvr: ConfigService) { } ngOnInit() { - - /* TODO - this.translate.addLangs(["en", "fr"]); + this.translate.addLangs(['en', 'fr']); this.translate.setDefaultLang(this.defaultLanguage); - let browserLang = this.translate.getBrowserLang(); + const browserLang = this.translate.getBrowserLang(); this.translate.use(browserLang.match(/en|fr/) ? browserLang : this.defaultLanguage); - */ + + this.configSvr.Conf$.subscribe((cfg: IConfig) => { + let lang: string; + switch (cfg.language) { + case 'ENG': + lang = 'en'; + break; + case 'FRA': + lang = 'fr'; + break; + default: + lang = this.defaultLanguage; + } + this.translate.use(lang); + }); } ngOnDestroy(): void { + // this.aglIdentityService.loginResponse.unsubscribe(); + // this.aglIdentityService.logoutResponse.unsubscribe(); } - - } diff --git a/webapp/src/app/app.module.ts b/webapp/src/app/app.module.ts index c3fd586..31a7c2c 100644 --- a/webapp/src/app/app.module.ts +++ b/webapp/src/app/app.module.ts @@ -1,7 +1,11 @@ import { NgModule } from '@angular/core'; +import { HttpClientModule, HttpClient } from '@angular/common/http'; import { BrowserModule } from '@angular/platform-browser'; -import { HttpModule } from "@angular/http"; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { TranslateModule, TranslateLoader } from '@ngx-translate/core'; +import { TranslateHttpLoader } from '@ngx-translate/http-loader'; +import { FileUploadModule } from 'ng2-file-upload'; +import { LocationStrategy, HashLocationStrategy } from '@angular/common'; import { CookieModule } from 'ngx-cookie'; // Import bootstrap @@ -14,39 +18,51 @@ import { CollapseModule } from 'ngx-bootstrap/collapse'; import { BsDropdownModule } from 'ngx-bootstrap/dropdown'; // Import the application components and services. -import { Routing, AppRoutingProviders } from './app.routing'; -import { AppComponent } from "./app.component"; +import { AppRoutingModule } from './app-routing.module'; +import { AppComponent } from './app.component'; import { AlertComponent } from './alert/alert.component'; -import { ConfigComponent } from "./config/config.component"; -import { DlXdsAgentComponent, CapitalizePipe } from "./config/downloadXdsAgent.component"; -import { ProjectCardComponent } from "./projects/projectCard.component"; -import { ProjectReadableTypePipe } from "./projects/projectCard.component"; -import { ProjectsListAccordionComponent } from "./projects/projectsListAccordion.component"; -import { ProjectAddModalComponent} from "./projects/projectAddModal.component"; -import { SdkCardComponent } from "./sdks/sdkCard.component"; -import { SdksListAccordionComponent } from "./sdks/sdksListAccordion.component"; -import { SdkSelectDropdownComponent } from "./sdks/sdkSelectDropdown.component"; -import { SdkAddModalComponent} from "./sdks/sdkAddModal.component"; +import { HomeComponent } from './home/home.component'; +import { ConfigComponent } from './config/config.component'; +import { DwnlAgentComponent } from './config/downloadXdsAgent.component'; +import { DevelComponent } from './devel/devel.component'; +import { BuildComponent } from './devel/build/build.component'; +import { ProjectCardComponent } from './projects/projectCard.component'; +import { ProjectReadableTypePipe } from './projects/projectCard.component'; +import { ProjectsListAccordionComponent } from './projects/projectsListAccordion.component'; +import { ProjectAddModalComponent } from './projects/projectAddModal.component'; +import { SdkCardComponent } from './sdks/sdkCard.component'; +import { SdksListAccordionComponent } from './sdks/sdksListAccordion.component'; +import { SdkSelectDropdownComponent } from './sdks/sdkSelectDropdown.component'; +import { SdkAddModalComponent } from './sdks/sdkAddModal.component'; -import { HomeComponent } from "./home/home.component"; -import { DevelComponent } from "./devel/devel.component"; -import { BuildComponent } from "./devel/build/build.component"; -import { XDSAgentService } from "./services/xdsagent.service"; -import { ConfigService } from "./services/config.service"; -import { ProjectService } from "./services/project.service"; import { AlertService } from './services/alert.service'; +import { ConfigService } from './services/config.service'; +import { ProjectService } from './services/project.service'; +import { SdkService } from './services/sdk.service'; import { UtilsService } from './services/utils.service'; -import { SdkService } from "./services/sdk.service"; +import { XDSAgentService } from './services/xdsagent.service'; +import { SafePipe } from './common/safe.pipe'; +export function createTranslateLoader(http: HttpClient) { + return new TranslateHttpLoader(http, './assets/i18n/', '.json'); +} @NgModule({ imports: [ BrowserModule, - HttpModule, FormsModule, ReactiveFormsModule, - Routing, + HttpClientModule, + AppRoutingModule, + FileUploadModule, + TranslateModule.forRoot({ + loader: { + provide: TranslateLoader, + useFactory: (createTranslateLoader), + deps: [HttpClient] + } + }), CookieModule.forRoot(), AlertModule.forRoot(), ModalModule.forRoot(), @@ -58,13 +74,12 @@ import { SdkService } from "./services/sdk.service"; ], declarations: [ AppComponent, - AlertComponent, HomeComponent, - BuildComponent, - DevelComponent, + AlertComponent, ConfigComponent, - DlXdsAgentComponent, - CapitalizePipe, + DwnlAgentComponent, + DevelComponent, + BuildComponent, ProjectCardComponent, ProjectReadableTypePipe, ProjectsListAccordionComponent, @@ -73,21 +88,21 @@ import { SdkService } from "./services/sdk.service"; SdksListAccordionComponent, SdkSelectDropdownComponent, SdkAddModalComponent, + SafePipe ], providers: [ - AppRoutingProviders, { - provide: Window, - useValue: window + provide: LocationStrategy, useClass: HashLocationStrategy, }, - XDSAgentService, + AlertService, ConfigService, ProjectService, - AlertService, - UtilsService, SdkService, + UtilsService, + XDSAgentService ], bootstrap: [AppComponent] }) export class AppModule { + constructor() { } } diff --git a/webapp/src/app/app.routing.ts b/webapp/src/app/app.routing.ts deleted file mode 100644 index f0d808f..0000000 --- a/webapp/src/app/app.routing.ts +++ /dev/null @@ -1,19 +0,0 @@ -import {Routes, RouterModule} from "@angular/router"; -import {ModuleWithProviders} from "@angular/core"; -import {ConfigComponent} from "./config/config.component"; -import {HomeComponent} from "./home/home.component"; -import {DevelComponent} from "./devel/devel.component"; - - -const appRoutes: Routes = [ - {path: '', redirectTo: 'home', pathMatch: 'full'}, - - {path: 'config', component: ConfigComponent, data: {title: 'Config'}}, - {path: 'home', component: HomeComponent, data: {title: 'Home'}}, - {path: 'devel', component: DevelComponent, data: {title: 'Build & Deploy'}} -]; - -export const AppRoutingProviders: any[] = []; -export const Routing: ModuleWithProviders = RouterModule.forRoot(appRoutes, { - useHash: true -}); diff --git a/webapp/src/app/common/safe.pipe.ts b/webapp/src/app/common/safe.pipe.ts new file mode 100644 index 0000000..84fd6b5 --- /dev/null +++ b/webapp/src/app/common/safe.pipe.ts @@ -0,0 +1,10 @@ +import { Pipe, PipeTransform } from '@angular/core'; +import { DomSanitizer } from '@angular/platform-browser'; + +@Pipe({ name: 'safe' }) +export class SafePipe implements PipeTransform { + constructor(private sanitizer: DomSanitizer) { } + transform(url) { + return this.sanitizer.bypassSecurityTrustResourceUrl(url); + } +} diff --git a/webapp/src/app/config/config.component.html b/webapp/src/app/config/config.component.html index 4dbd238..ba3bd72 100644 --- a/webapp/src/app/config/config.component.html +++ b/webapp/src/app/config/config.component.html @@ -22,7 +22,7 @@ <td style="white-space: nowrap"> <div class="btn-group"> <button class="btn btn-link" (click)="xdsAgentRestartConn()"><span class="fa fa-refresh fa-size-x2"></span></button> - <dl-xds-agent class="button"></dl-xds-agent> + <xds-dwnl-agent class="button"></xds-dwnl-agent> </div> </td> </tr> @@ -62,7 +62,7 @@ </div> <div class="panel-body" [collapse]="sdksIsCollapsed"> <div class="row col-xs-12"> - <sdks-list-accordion [sdks]="(sdks$ | async)"></sdks-list-accordion> + <xds-sdks-list-accordion [sdks]="(sdks$ | async)"></xds-sdks-list-accordion> </div> </div> </div> @@ -82,16 +82,16 @@ </div> <div class="panel-body" [collapse]="projectsIsCollapsed"> <div class="row col-xs-12"> - <projects-list-accordion [projects]="(projects$ | async)"></projects-list-accordion> + <xds-projects-list-accordion [projects]="(projects$ | async)"></xds-projects-list-accordion> </div> </div> </div> <!-- Modals --> -<project-add-modal #childProjectModal [title]="'Add a new project'" [server-id]=curServerID> -</project-add-modal> -<sdk-add-modal #childSdkModal [title]="'Add a new SDK'"> -</sdk-add-modal> +<xds-project-add-modal #childProjectModal [title]="'Add a new project'" [server-id]=curServerID> +</xds-project-add-modal> +<xds-sdk-add-modal #childSdkModal [title]="'Add a new SDK'"> +</xds-sdk-add-modal> <!-- only for debug --> <div *ngIf="false" class="row"> diff --git a/webapp/src/app/config/config.component.spec.ts b/webapp/src/app/config/config.component.spec.ts new file mode 100644 index 0000000..ec5d3be --- /dev/null +++ b/webapp/src/app/config/config.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ConfigComponent } from './config.component'; + +describe('ConfigComponent', () => { + let component: ConfigComponent; + let fixture: ComponentFixture<ConfigComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ ConfigComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ConfigComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/webapp/src/app/config/config.component.ts b/webapp/src/app/config/config.component.ts index 6377844..3db7f60 100644 --- a/webapp/src/app/config/config.component.ts +++ b/webapp/src/app/config/config.component.ts @@ -1,19 +1,20 @@ -import { Component, ViewChild, OnInit } from "@angular/core"; +import { Component, OnInit, ViewChild, ViewEncapsulation } from '@angular/core'; import { Observable } from 'rxjs/Observable'; -import { FormControl, FormGroup, Validators, FormBuilder } from '@angular/forms'; import { CollapseModule } from 'ngx-bootstrap/collapse'; -import { ConfigService, IConfig } from "../services/config.service"; -import { ProjectService, IProject } from "../services/project.service"; -import { XDSAgentService, IAgentStatus, IXDSConfig } from "../services/xdsagent.service"; -import { AlertService } from "../services/alert.service"; -import { ProjectAddModalComponent } from "../projects/projectAddModal.component"; -import { SdkService, ISdk } from "../services/sdk.service"; -import { SdkAddModalComponent } from "../sdks/sdkAddModal.component"; +import { ConfigService, IConfig } from '../services/config.service'; +import { ProjectService, IProject } from '../services/project.service'; +import { XDSAgentService, IAgentStatus, IXDSConfig } from '../services/xdsagent.service'; +import { AlertService } from '../services/alert.service'; +import { ProjectAddModalComponent } from '../projects/projectAddModal.component'; +import { SdkService, ISdk } from '../services/sdk.service'; +import { SdkAddModalComponent } from '../sdks/sdkAddModal.component'; @Component({ - templateUrl: './app/config/config.component.html', - styleUrls: ['./app/config/config.component.css'] + selector: 'app-config', + templateUrl: './config.component.html', + styleUrls: ['./config.component.css'], + encapsulation: ViewEncapsulation.None }) // Inspired from https://embed.plnkr.co/jgDTXknPzAaqcg9XA9zq/ @@ -31,20 +32,20 @@ export class ConfigComponent implements OnInit { curProj: number; curServer: number; curServerID: string; - userEditedLabel: boolean = false; + userEditedLabel = false; - gConfigIsCollapsed: boolean = true; - sdksIsCollapsed: boolean = true; - projectsIsCollapsed: boolean = false; + gConfigIsCollapsed = true; + sdksIsCollapsed = true; + projectsIsCollapsed = false; // TODO replace by reactive FormControl + add validation - xdsServerConnected: boolean = false; + xdsServerConnected = false; xdsServerUrl: string; xdsServerRetry: string; projectsRootDir: string; // FIXME: should be remove when projectAddModal will always return full path showApplyBtn = { // Used to show/hide Apply buttons - "retry": false, - "rootDir": false, + 'retry': false, + 'rootDir': false, }; constructor( @@ -70,7 +71,7 @@ export class ConfigComponent implements OnInit { if (!cfg || cfg.servers.length < 1) { return; } - let svr = cfg.servers[this.curServer]; + const svr = cfg.servers[this.curServer]; this.curServerID = svr.id; this.xdsServerConnected = svr.connected; this.xdsServerUrl = svr.url; @@ -81,16 +82,16 @@ export class ConfigComponent implements OnInit { submitGlobConf(field: string) { switch (field) { - case "retry": - let re = new RegExp('^[0-9]+$'); - let rr = parseInt(this.xdsServerRetry, 10); + case 'retry': + const re = new RegExp('^[0-9]+$'); + const rr = parseInt(this.xdsServerRetry, 10); if (re.test(this.xdsServerRetry) && rr >= 0) { this.xdsAgentSvr.setServerRetry(this.curServerID, rr); } else { - this.alert.warning("Not a valid number", true); + this.alert.warning('Not a valid number', true); } break; - case "rootDir": + case 'rootDir': this.configSvr.projectsRootDir = this.projectsRootDir; break; default: @@ -100,7 +101,7 @@ export class ConfigComponent implements OnInit { } xdsAgentRestartConn() { - let url = this.xdsServerUrl; + const url = this.xdsServerUrl; this.xdsAgentSvr.setServerUrl(this.curServerID, url); } diff --git a/webapp/src/app/config/downloadXdsAgent.component.ts b/webapp/src/app/config/downloadXdsAgent.component.ts index 0b63e50..3901331 100644 --- a/webapp/src/app/config/downloadXdsAgent.component.ts +++ b/webapp/src/app/config/downloadXdsAgent.component.ts @@ -1,7 +1,7 @@ -import { Component, Input, Pipe, PipeTransform } from '@angular/core'; +import { Component } from '@angular/core'; @Component({ - selector: 'dl-xds-agent', + selector: 'xds-dwnl-agent', template: ` <template #popTemplate> <h3>Install xds-agent:</h3> @@ -28,20 +28,8 @@ import { Component, Input, Pipe, PipeTransform } from '@angular/core'; `] }) -export class DlXdsAgentComponent { +export class DwnlAgentComponent { - public url_OS_Linux = "https://en.opensuse.org/LinuxAutomotive#Installation_AGL_XDS"; - public url_OS_Other = "https://github.com/iotbzh/xds-agent#how-to-install-on-other-platform"; -} - -@Pipe({ - name: 'capitalize' -}) -export class CapitalizePipe implements PipeTransform { - transform(value: string): string { - if (value) { - return value.charAt(0).toUpperCase() + value.slice(1); - } - return value; - } + public url_OS_Linux = 'https://en.opensuse.org/LinuxAutomotive#Installation_AGL_XDS'; + public url_OS_Other = 'https://github.com/iotbzh/xds-agent#how-to-install-on-other-platform'; } diff --git a/webapp/src/app/devel/build/build.component.html b/webapp/src/app/devel/build/build.component.html index 2bcd2c7..0cf0290 100644 --- a/webapp/src/app/devel/build/build.component.html +++ b/webapp/src/app/devel/build/build.component.html @@ -18,9 +18,9 @@ <th>Cross SDK</th> <td> <!-- FIXME why not working ? - <sdk-select-dropdown [sdks]="(sdks$ | async)"></sdk-select-dropdown> + <xds-sdk-select-dropdown [sdks]="(sdks$ | async)"></xds-sdk-select-dropdown> --> - <sdk-select-dropdown></sdk-select-dropdown> + <xds-sdk-select-dropdown></xds-sdk-select-dropdown> </td> </tr> <tr> @@ -83,7 +83,6 @@ <button class="btn btn-primary btn-large" (click)="build()" [disabled]="!curProject">Build</button> <button class="btn btn-primary btn-large" (click)="populate()" [disabled]="!curProject ">Populate</button> <button *ngIf="debugEnable" class="btn btn-primary btn-large" (click)="execCmd()" [disabled]="!curProject ">Execute command</button> - <button *ngIf="debugEnable" class="btn btn-primary btn-large" (click)="make()" [disabled]="!curProject ">Make</button> </div> </div> </div> diff --git a/webapp/src/app/devel/build/build.component.spec.ts b/webapp/src/app/devel/build/build.component.spec.ts new file mode 100644 index 0000000..016192c --- /dev/null +++ b/webapp/src/app/devel/build/build.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { BuildComponent } from './build.component'; + +describe('BuildComponent', () => { + let component: BuildComponent; + let fixture: ComponentFixture<BuildComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ BuildComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(BuildComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/webapp/src/app/devel/build/build.component.ts b/webapp/src/app/devel/build/build.component.ts index 87df4e1..49f42eb 100644 --- a/webapp/src/app/devel/build/build.component.ts +++ b/webapp/src/app/devel/build/build.component.ts @@ -1,21 +1,21 @@ -import { Component, AfterViewChecked, ElementRef, ViewChild, OnInit, Input } from '@angular/core'; -import { Observable } from 'rxjs'; +import { Component, ViewEncapsulation, AfterViewChecked, ElementRef, ViewChild, OnInit, Input } from '@angular/core'; +import { Observable } from 'rxjs/Observable'; import { FormControl, FormGroup, Validators, FormBuilder } from '@angular/forms'; import { CookieService } from 'ngx-cookie'; import 'rxjs/add/operator/scan'; import 'rxjs/add/operator/startWith'; -import { XDSAgentService, ICmdOutput } from "../../services/xdsagent.service"; -import { ProjectService, IProject } from "../../services/project.service"; -import { AlertService, IAlert } from "../../services/alert.service"; -import { SdkService } from "../../services/sdk.service"; +import { XDSAgentService, ICmdOutput } from '../../services/xdsagent.service'; +import { ProjectService, IProject } from '../../services/project.service'; +import { AlertService, IAlert } from '../../services/alert.service'; +import { SdkService } from '../../services/sdk.service'; @Component({ - selector: 'panel-build', - moduleId: module.id, + selector: 'xds-panel-build', templateUrl: './build.component.html', - styleUrls: ['./build.component.css'] + styleUrls: ['./build.component.css'], +encapsulation: ViewEncapsulation.None }) export class BuildComponent implements OnInit, AfterViewChecked { @@ -24,9 +24,9 @@ export class BuildComponent implements OnInit, AfterViewChecked { @Input() curProject: IProject; public buildForm: FormGroup; - public subpathCtrl = new FormControl("", Validators.required); - public debugEnable: boolean = false; - public buildIsCollapsed: boolean = false; + public subpathCtrl = new FormControl('', Validators.required); + public debugEnable = false; + public buildIsCollapsed = false; public cmdOutput: string; public cmdInfo: string; @@ -39,16 +39,16 @@ export class BuildComponent implements OnInit, AfterViewChecked { private sdkSvr: SdkService, private cookie: CookieService, ) { - this.cmdOutput = ""; - this.cmdInfo = ""; // TODO: to be remove (only for debug) + this.cmdOutput = ''; + this.cmdInfo = ''; // TODO: to be remove (only for debug) this.buildForm = fb.group({ subpath: this.subpathCtrl, - cmdClean: ["", Validators.nullValidator], - cmdPrebuild: ["", Validators.nullValidator], - cmdBuild: ["", Validators.nullValidator], - cmdPopulate: ["", Validators.nullValidator], - cmdArgs: ["", Validators.nullValidator], - envVars: ["", Validators.nullValidator], + cmdClean: ['', Validators.nullValidator], + cmdPrebuild: ['', Validators.nullValidator], + cmdBuild: ['', Validators.nullValidator], + cmdPopulate: ['', Validators.nullValidator], + cmdArgs: ['', Validators.nullValidator], + envVars: ['', Validators.nullValidator], }); } @@ -56,13 +56,13 @@ export class BuildComponent implements OnInit, AfterViewChecked { // Set default settings // TODO save & restore values from cookies this.buildForm.patchValue({ - subpath: "", - cmdClean: "rm -rf build", - cmdPrebuild: "mkdir -p build && cd build && cmake ..", - cmdBuild: "cd build && make", - cmdPopulate: "cd build && make remote-target-populate", - cmdArgs: "", - envVars: "", + subpath: '', + cmdClean: 'rm -rf build', + cmdPrebuild: 'mkdir -p build && cd build && cmake ..', + cmdBuild: 'cd build && make', + cmdPopulate: 'cd build && make remote-target-populate', + cmdArgs: '', + envVars: '', }); // Command output data tunneling @@ -79,14 +79,14 @@ export class BuildComponent implements OnInit, AfterViewChecked { } if (exit && exit.code !== 0) { - this.cmdOutput += "--- Command exited with code " + exit.code + " ---\n\n"; + this.cmdOutput += '--- Command exited with code ' + exit.code + ' ---\n\n'; } }); this._scrollToBottom(); // only use for debug - this.debugEnable = (this.cookie.get("debug_build") === "1"); + this.debugEnable = (this.cookie.get('debug_build') === '1'); } ngAfterViewChecked() { @@ -145,17 +145,17 @@ export class BuildComponent implements OnInit, AfterViewChecked { this.alertSvr.warning('No active project', true); } - let prjID = this.curProject.id; + const prjID = this.curProject.id; this.cmdOutput += this._outputHeader(); - let sdkid = this.sdkSvr.getCurrentId(); + const sdkid = this.sdkSvr.getCurrentId(); // Detect key=value in env string to build array of string - let envArr = []; + const envArr = []; env.split(';').forEach(v => envArr.push(v.trim())); - let t0 = performance.now(); + const t0 = performance.now(); this.cmdInfo = 'Start build of ' + prjID + ' at ' + t0; this.xdsSvr.exec(prjID, dir, cmd, sdkid, args, envArr) @@ -168,36 +168,6 @@ export class BuildComponent implements OnInit, AfterViewChecked { }); } - make(args: string) { - if (!this.curProject) { - this.alertSvr.warning('No active project', true); - } - - let prjID = this.curProject.id; - - this.cmdOutput += this._outputHeader(); - - let sdkid = this.sdkSvr.getCurrentId(); - - let argsArr = args ? args.split(' ') : this.buildForm.value.cmdArgs.split(' '); - - // Detect key=value in env string to build array of string - let envArr = []; - this.buildForm.value.envVars.split(';').forEach(v => envArr.push(v.trim())); - - let t0 = performance.now(); - this.cmdInfo = 'Start build of ' + prjID + ' at ' + t0; - - this.xdsSvr.make(prjID, this.buildForm.value.subpath, sdkid, argsArr, envArr) - .subscribe(res => { - this.startTime.set(String(res.cmdID), t0); - }, - err => { - this.cmdInfo = 'Last command duration: ' + this._computeTime(t0); - this.alertSvr.error('ERROR: ' + err); - }); - } - private _scrollToBottom(): void { try { this.scrollContainer.nativeElement.scrollTop = this.scrollContainer.nativeElement.scrollHeight; @@ -205,7 +175,7 @@ export class BuildComponent implements OnInit, AfterViewChecked { } private _computeTime(t0: number, t1?: number): string { - let enlap = Math.round((t1 || performance.now()) - t0); + const enlap = Math.round((t1 || performance.now()) - t0); if (enlap < 1000.0) { return enlap.toFixed(2) + ' ms'; } else { @@ -214,10 +184,10 @@ export class BuildComponent implements OnInit, AfterViewChecked { } private _outputHeader(): string { - return "--- " + new Date().toString() + " ---\n"; + return '--- ' + new Date().toString() + ' ---\n'; } private _outputFooter(): string { - return "\n"; + return '\n'; } } diff --git a/webapp/src/app/devel/devel.component.html b/webapp/src/app/devel/devel.component.html index cc62889..495eed4 100644 --- a/webapp/src/app/devel/devel.component.html +++ b/webapp/src/app/devel/devel.component.html @@ -30,7 +30,7 @@ <div class="row"> <!--<div class="col-md-8">--> <div class="col-md-12"> - <panel-build [curProject]=curPrj></panel-build> + <xds-panel-build [curProject]=curPrj></xds-panel-build> </div> <!-- TODO: disable for now <div class="col-md-4"> diff --git a/webapp/src/app/devel/devel.component.spec.ts b/webapp/src/app/devel/devel.component.spec.ts new file mode 100644 index 0000000..6483bf5 --- /dev/null +++ b/webapp/src/app/devel/devel.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { DevelComponent } from './devel.component'; + +describe('DevelComponent', () => { + let component: DevelComponent; + let fixture: ComponentFixture<DevelComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ DevelComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(DevelComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/webapp/src/app/devel/devel.component.ts b/webapp/src/app/devel/devel.component.ts index 5c8b9f2..eda03ef 100644 --- a/webapp/src/app/devel/devel.component.ts +++ b/webapp/src/app/devel/devel.component.ts @@ -1,17 +1,16 @@ -import { Component } from '@angular/core'; +import { Component, OnInit, ViewEncapsulation } from '@angular/core'; +import { Observable } from 'rxjs/Observable'; -import { Observable } from 'rxjs'; - -import { ProjectService, IProject } from "../services/project.service"; +import { ProjectService, IProject } from '../services/project.service'; @Component({ - selector: 'devel', - moduleId: module.id, + selector: 'xds-devel', templateUrl: './devel.component.html', styleUrls: ['./devel.component.css'], + encapsulation: ViewEncapsulation.None }) -export class DevelComponent { +export class DevelComponent implements OnInit { curPrj: IProject; Prjs$: Observable<IProject[]>; @@ -23,7 +22,7 @@ export class DevelComponent { this.Prjs$ = this.projectSvr.Projects$; this.Prjs$.subscribe((prjs) => { // Select project if no one is selected or no project exists - if (this.curPrj && "id" in this.curPrj) { + if (this.curPrj && 'id' in this.curPrj) { this.curPrj = prjs.find(p => p.id === this.curPrj.id) || prjs[0]; } else if (this.curPrj == null) { this.curPrj = prjs[0]; diff --git a/webapp/src/app/home/home.component.css b/webapp/src/app/home/home.component.css new file mode 100644 index 0000000..7831443 --- /dev/null +++ b/webapp/src/app/home/home.component.css @@ -0,0 +1,18 @@ +.wide img { + width: 98%; +} +.carousel-item { + max-height: 90%; +} +h1, h2, h3, h4, p { + color: #330066; +} +.html-inner { + color: #330066; +} +h1 { + font-size: 4em; +} +p { + font-size: 2.5em; +} diff --git a/webapp/src/app/home/home.component.html b/webapp/src/app/home/home.component.html new file mode 100644 index 0000000..568fb9b --- /dev/null +++ b/webapp/src/app/home/home.component.html @@ -0,0 +1,13 @@ +<div class="wide"> + <carousel [interval]="carInterval" [(activeSlide)]="activeSlideIndex"> + <slide *ngFor="let sl of slides; let index=index"> + <img [src]="sl.img" [alt]="sl.imgAlt"> + <div class="carousel-caption"> + <h1 *ngIf="sl.hText">{{ sl.hText }}</h1> + <h1 *ngIf="sl.hHtml" class="html-inner" [innerHtml]="sl.hHtml"></h1> + <p *ngIf="sl.text">{{ sl.text }}</p> + <div *ngIf="sl.html" class="html-inner" [innerHtml]="sl.html"></div> + </div> + </slide> + </carousel> +</div> diff --git a/webapp/src/app/home/home.component.ts b/webapp/src/app/home/home.component.ts index 0e3c995..66a2f30 100644 --- a/webapp/src/app/home/home.component.ts +++ b/webapp/src/app/home/home.component.ts @@ -12,70 +12,35 @@ export interface ISlide { } @Component({ - selector: 'home', - moduleId: module.id, - template: ` - <style> - .wide img { - width: 98%; - } - .carousel-item { - max-height: 90%; - } - h1, h2, h3, h4, p { - color: #330066; - } - .html-inner { - color: #330066; - } - h1 { - font-size: 4em; - } - p { - font-size: 2.5em; - } - - </style> - - <div class="wide"> - <carousel [interval]="carInterval" [(activeSlide)]="activeSlideIndex"> - <slide *ngFor="let sl of slides; let index=index"> - <img [src]="sl.img" [alt]="sl.imgAlt"> - <div class="carousel-caption"> - <h1 *ngIf="sl.hText">{{ sl.hText }}</h1> - <h1 *ngIf="sl.hHtml" class="html-inner" [innerHtml]="sl.hHtml"></h1> - <p *ngIf="sl.text">{{ sl.text }}</p> - <div *ngIf="sl.html" class="html-inner" [innerHtml]="sl.html"></div> - </div> - </slide> - </carousel> - </div> - ` + selector: 'xds-home', + templateUrl: 'home.component.html', + styleUrls: ['home.component.css'] }) export class HomeComponent { - public carInterval: number = 4000; + public carInterval = 4000; + public activeSlideIndex = 0; // FIXME SEB - Add more slides and info public slides: ISlide[] = [ { img: 'assets/images/iot-graphx.jpg', - imgAlt: "iot graphx image", - hText: "Welcome to XDS Dashboard !", - text: "X(cross) Development System allows developers to easily cross-compile applications.", + imgAlt: 'iot graphx image', + hText: 'Welcome to XDS Dashboard !', + text: 'X(cross) Development System allows developers to easily cross-compile applications.', }, { img: 'assets/images/iot-graphx.jpg', - imgAlt: "iot graphx image", - hText: "Create, Build, Deploy, Enjoy !", + imgAlt: 'iot graphx image', + hText: 'Create, Build, Deploy, Enjoy !', }, { img: 'assets/images/iot-graphx.jpg', - imgAlt: "iot graphx image", - hHtml: '<p>To Start: click on <i class="fa fa-cog" style="color:#9d9d9d;"></i> icon and add new folder</p>', + imgAlt: 'iot graphx image', + hHtml: '<p>To Start: click on <i class=\'fa fa-cog\' style=\'color:#9d9d9d;\'></i> icon and add new folder</p>', } ]; constructor() { } -}
\ No newline at end of file +} diff --git a/webapp/src/app/main.ts b/webapp/src/app/main.ts deleted file mode 100644 index 1f68ccc..0000000 --- a/webapp/src/app/main.ts +++ /dev/null @@ -1,6 +0,0 @@ -import {platformBrowserDynamic} from '@angular/platform-browser-dynamic'; -import {AppModule} from './app.module'; - -const platform = platformBrowserDynamic(); - -platform.bootstrapModule(AppModule);
\ No newline at end of file diff --git a/webapp/src/app/projects/projectAddModal.component.ts b/webapp/src/app/projects/projectAddModal.component.ts index 1352060..0718f4c 100644 --- a/webapp/src/app/projects/projectAddModal.component.ts +++ b/webapp/src/app/projects/projectAddModal.component.ts @@ -8,22 +8,22 @@ import 'rxjs/add/operator/map'; import 'rxjs/add/operator/filter'; import 'rxjs/add/operator/debounceTime'; -import { AlertService, IAlert } from "../services/alert.service"; -import { ProjectService, IProject, ProjectType, ProjectTypes } from "../services/project.service"; +import { AlertService, IAlert } from '../services/alert.service'; +import { ProjectService, IProject, ProjectType, ProjectTypes } from '../services/project.service'; @Component({ - selector: 'project-add-modal', - templateUrl: './app/projects/projectAddModal.component.html', - styleUrls: ['./app/projects/projectAddModal.component.css'] + selector: 'xds-project-add-modal', + templateUrl: 'projectAddModal.component.html', + styleUrls: ['projectAddModal.component.css'] }) -export class ProjectAddModalComponent { +export class ProjectAddModalComponent implements OnInit { @ViewChild('childProjectModal') public childProjectModal: ModalDirective; @Input() title?: string; @Input('server-id') serverID: string; - cancelAction: boolean = false; - userEditedLabel: boolean = false; + cancelAction = false; + userEditedLabel = false; projectTypes = ProjectTypes; addProjectForm: FormGroup; @@ -37,17 +37,17 @@ export class ProjectAddModalComponent { private fb: FormBuilder ) { // Define types (first one is special/placeholder) - this.projectTypes.unshift({ value: ProjectType.UNSET, display: "--Select a type--" }); + this.projectTypes.unshift({ value: ProjectType.UNSET, display: '--Select a type--' }); - this.typeCtrl = new FormControl(this.projectTypes[0].value, Validators.pattern("[A-Za-z]+")); - this.pathCliCtrl = new FormControl("", Validators.required); - this.pathSvrCtrl = new FormControl({ value: "", disabled: true }, [Validators.required, Validators.minLength(1)]); + this.typeCtrl = new FormControl(this.projectTypes[0].value, Validators.pattern('[A-Za-z]+')); + this.pathCliCtrl = new FormControl('', Validators.required); + this.pathSvrCtrl = new FormControl({ value: '', disabled: true }, [Validators.required, Validators.minLength(1)]); this.addProjectForm = fb.group({ type: this.typeCtrl, pathCli: this.pathCliCtrl, pathSvr: this.pathSvrCtrl, - label: ["", Validators.nullValidator], + label: ['', Validators.nullValidator], }); } @@ -57,15 +57,15 @@ export class ProjectAddModalComponent { .debounceTime(100) .filter(n => n) .map(n => { - let last = n.split('/'); + const last = n.split('/'); let nm = n; if (last.length > 0) { nm = last.pop(); - if (nm === "" && last.length > 0) { + if (nm === '' && last.length > 0) { nm = last.pop(); } } - return "Project_" + nm; + return 'Project_' + nm; }) .subscribe(value => { if (value && !this.userEditedLabel) { @@ -77,8 +77,8 @@ export class ProjectAddModalComponent { this.typeCtrl.valueChanges .debounceTime(500) .subscribe(valType => { - let dis = (valType === String(ProjectType.SYNCTHING)); - this.pathSvrCtrl.reset({ value: "", disabled: dis }); + const dis = (valType === String(ProjectType.SYNCTHING)); + this.pathSvrCtrl.reset({ value: '', disabled: dis }); }); } @@ -93,19 +93,19 @@ export class ProjectAddModalComponent { } onKeyLabel(event: any) { - this.userEditedLabel = (this.addProjectForm.value.label !== ""); + this.userEditedLabel = (this.addProjectForm.value.label !== ''); } /* FIXME: change input to file type - <td><input type="file" id="select-local-path" webkitdirectory - formControlName="pathCli" placeholder="myProject" (change)="onChangeLocalProject($event)"></td> + <td><input type='file' id='select-local-path' webkitdirectory + formControlName='pathCli' placeholder='myProject' (change)='onChangeLocalProject($event)'></td> onChangeLocalProject(e) { if e.target.files.length < 1 { console.log('NO files'); } let dir = e.target.files[0].webkitRelativePath; - console.log("files: " + dir); + console.log('files: ' + dir); let u = URL.createObjectURL(e.target.files[0]); } */ @@ -117,9 +117,9 @@ export class ProjectAddModalComponent { return; } - let formVal = this.addProjectForm.value; + const formVal = this.addProjectForm.value; - let type = formVal['type'].value; + const type = formVal['type'].value; this.projectSvr.Add({ serverId: this.serverID, label: formVal['label'], @@ -129,12 +129,12 @@ export class ProjectAddModalComponent { // FIXME: allow to set defaultSdkID from New Project config panel }) .subscribe(prj => { - this.alert.info("Project " + prj.label + " successfully created."); + this.alert.info('Project ' + prj.label + ' successfully created.'); this.hide(); // Reset Value for the next creation this.addProjectForm.reset(); - let selectedType = this.projectTypes[0].value; + const selectedType = this.projectTypes[0].value; this.addProjectForm.patchValue({ type: selectedType }); }, diff --git a/webapp/src/app/projects/projectCard.component.ts b/webapp/src/app/projects/projectCard.component.ts index fdacba4..a28b96c 100644 --- a/webapp/src/app/projects/projectCard.component.ts +++ b/webapp/src/app/projects/projectCard.component.ts @@ -1,9 +1,9 @@ import { Component, Input, Pipe, PipeTransform } from '@angular/core'; -import { ProjectService, IProject, ProjectType } from "../services/project.service"; -import { AlertService } from "../services/alert.service"; +import { ProjectService, IProject, ProjectType } from '../services/project.service'; +import { AlertService } from '../services/alert.service'; @Component({ - selector: 'project-card', + selector: 'xds-project-card', template: ` <div class="row"> <div class="col-xs-12"> @@ -44,7 +44,7 @@ import { AlertService } from "../services/alert.service"; </tbody> </table > `, - styleUrls: ['./app/config/config.component.css'] + styleUrls: ['../config/config.component.css'] }) export class ProjectCardComponent { @@ -61,7 +61,7 @@ export class ProjectCardComponent { this.projectSvr.Delete(prj) .subscribe(res => { }, err => { - this.alert.error("Delete ERROR: " + err); + this.alert.error('Delete ERROR: ' + err); }); } @@ -69,7 +69,7 @@ export class ProjectCardComponent { this.projectSvr.Sync(prj) .subscribe(res => { }, err => { - this.alert.error("ERROR: " + err); + this.alert.error('ERROR: ' + err); }); } @@ -83,8 +83,8 @@ export class ProjectCardComponent { export class ProjectReadableTypePipe implements PipeTransform { transform(type: ProjectType): string { switch (type) { - case ProjectType.NATIVE_PATHMAP: return "Native (path mapping)"; - case ProjectType.SYNCTHING: return "Cloud (Syncthing)"; + case ProjectType.NATIVE_PATHMAP: return 'Native (path mapping)'; + case ProjectType.SYNCTHING: return 'Cloud (Syncthing)'; default: return String(type); } } diff --git a/webapp/src/app/projects/projectsListAccordion.component.ts b/webapp/src/app/projects/projectsListAccordion.component.ts index 210be5c..0dd2f12 100644 --- a/webapp/src/app/projects/projectsListAccordion.component.ts +++ b/webapp/src/app/projects/projectsListAccordion.component.ts @@ -1,9 +1,9 @@ -import { Component, Input } from "@angular/core"; +import { Component, Input } from '@angular/core'; -import { IProject } from "../services/project.service"; +import { IProject } from '../services/project.service'; @Component({ - selector: 'projects-list-accordion', + selector: 'xds-projects-list-accordion', template: ` <style> .fa.fa-exclamation-triangle { @@ -25,7 +25,7 @@ import { IProject } from "../services/project.service"; <i class="fa" [ngClass]="{'fa-chevron-down': group.isOpen, 'fa-chevron-right': !group.isOpen}"></i> </div> </div> - <project-card [project]="prj"></project-card> + <xds-project-card [project]="prj"></xds-project-card> </accordion-group> </accordion> ` diff --git a/webapp/src/app/sdks/sdkAddModal.component.html b/webapp/src/app/sdks/sdkAddModal.component.html index 2c07fca..44c667e 100644 --- a/webapp/src/app/sdks/sdkAddModal.component.html +++ b/webapp/src/app/sdks/sdkAddModal.component.html @@ -4,7 +4,7 @@ <div class="modal-content"> <div class="modal-header"> <h4 class="modal-title pull-left">{{title}}</h4> - <button type="button" class="close pull-right" aria-label="Close" (click)="hideChildModal()"> + <button type="button" class="close pull-right" aria-label="Close" (click)="hide()"> <span aria-hidden="true">×</span> </button> </div> diff --git a/webapp/src/app/sdks/sdkAddModal.component.ts b/webapp/src/app/sdks/sdkAddModal.component.ts index b6c8eb2..064f02f 100644 --- a/webapp/src/app/sdks/sdkAddModal.component.ts +++ b/webapp/src/app/sdks/sdkAddModal.component.ts @@ -2,8 +2,8 @@ import { Component, Input, ViewChild } from '@angular/core'; import { ModalDirective } from 'ngx-bootstrap/modal'; @Component({ - selector: 'sdk-add-modal', - templateUrl: './app/sdks/sdkAddModal.component.html', + selector: 'xds-sdk-add-modal', + templateUrl: 'sdkAddModal.component.html', }) export class SdkAddModalComponent { @ViewChild('sdkChildModal') public sdkChildModal: ModalDirective; diff --git a/webapp/src/app/sdks/sdkCard.component.ts b/webapp/src/app/sdks/sdkCard.component.ts index 3256a0b..b277887 100644 --- a/webapp/src/app/sdks/sdkCard.component.ts +++ b/webapp/src/app/sdks/sdkCard.component.ts @@ -1,8 +1,8 @@ import { Component, Input } from '@angular/core'; -import { ISdk } from "../services/sdk.service"; +import { ISdk } from '../services/sdk.service'; @Component({ - selector: 'sdk-card', + selector: 'xds-sdk-card', template: ` <div class="row"> <div class="col-xs-12"> @@ -38,7 +38,7 @@ import { ISdk } from "../services/sdk.service"; </tbody> </table > `, - styleUrls: ['./app/config/config.component.css'] + styleUrls: ['../config/config.component.css'] }) export class SdkCardComponent { diff --git a/webapp/src/app/sdks/sdkSelectDropdown.component.ts b/webapp/src/app/sdks/sdkSelectDropdown.component.ts index a2fe37a..7cd2dc7 100644 --- a/webapp/src/app/sdks/sdkSelectDropdown.component.ts +++ b/webapp/src/app/sdks/sdkSelectDropdown.component.ts @@ -1,9 +1,9 @@ -import { Component, Input } from "@angular/core"; +import { Component, OnInit, Input } from '@angular/core'; -import { ISdk, SdkService } from "../services/sdk.service"; +import { ISdk, SdkService } from '../services/sdk.service'; @Component({ - selector: 'sdk-select-dropdown', + selector: 'xds-sdk-select-dropdown', template: ` <div class="btn-group" dropdown *ngIf="curSdk" > <button dropdownToggle type="button" class="btn btn-primary dropdown-toggle" style="width: 20em;"> @@ -17,11 +17,11 @@ import { ISdk, SdkService } from "../services/sdk.service"; </div> ` }) -export class SdkSelectDropdownComponent { +export class SdkSelectDropdownComponent implements OnInit { // FIXME investigate to understand why not working with sdks as input - // <sdk-select-dropdown [sdks]="(sdks$ | async)"></sdk-select-dropdown> - //@Input() sdks: ISdk[]; + // <xds-sdk-select-dropdown [sdks]="(sdks$ | async)"></xds-sdk-select-dropdown> + // @Input() sdks: ISdk[]; sdks: ISdk[]; curSdk: ISdk; diff --git a/webapp/src/app/sdks/sdksListAccordion.component.ts b/webapp/src/app/sdks/sdksListAccordion.component.ts index 9d5f7e9..73ad182 100644 --- a/webapp/src/app/sdks/sdksListAccordion.component.ts +++ b/webapp/src/app/sdks/sdksListAccordion.component.ts @@ -1,9 +1,9 @@ -import { Component, Input } from "@angular/core"; +import { Component, Input } from '@angular/core'; -import { ISdk } from "../services/sdk.service"; +import { ISdk } from '../services/sdk.service'; @Component({ - selector: 'sdks-list-accordion', + selector: 'xds-sdks-list-accordion', template: ` <accordion> <accordion-group #group *ngFor="let sdk of sdks"> @@ -12,7 +12,7 @@ import { ISdk } from "../services/sdk.service"; <i class="pull-right float-xs-right fa" [ngClass]="{'fa-chevron-down': group.isOpen, 'fa-chevron-right': !group.isOpen}"></i> </div> - <sdk-card [sdk]="sdk"></sdk-card> + <xds-sdk-card [sdk]="sdk"></xds-sdk-card> </accordion-group> </accordion> ` diff --git a/webapp/src/app/services/alert.service.spec.ts b/webapp/src/app/services/alert.service.spec.ts new file mode 100644 index 0000000..66a8477 --- /dev/null +++ b/webapp/src/app/services/alert.service.spec.ts @@ -0,0 +1,15 @@ +import { TestBed, inject } from '@angular/core/testing'; + +import { AlertService } from './alert.service'; + +describe('AlertService', () => { + beforeEach(() => { + TestBed.configureTestingModule({ + providers: [AlertService] + }); + }); + + it('should be created', inject([AlertService], (service: AlertService) => { + expect(service).toBeTruthy(); + })); +}); diff --git a/webapp/src/app/services/alert.service.ts b/webapp/src/app/services/alert.service.ts index 2978e84..aee5827 100644 --- a/webapp/src/app/services/alert.service.ts +++ b/webapp/src/app/services/alert.service.ts @@ -4,7 +4,7 @@ import { Observable } from 'rxjs/Observable'; import { Subject } from 'rxjs/Subject'; -export type AlertType = "danger" | "warning" | "info" | "success"; +export type AlertType = 'danger' | 'warning' | 'info' | 'success'; export interface IAlert { type: AlertType; @@ -22,7 +22,7 @@ export class AlertService { private _alerts: IAlert[]; private alertsSubject = <Subject<IAlert[]>>new Subject(); private uid = 0; - private defaultDissmissTmo = 5; // in seconds + private defaultDismissTmo = 5; // in seconds constructor(private sanitizer: DomSanitizer) { this.alerts = this.alertsSubject.asObservable(); @@ -32,20 +32,20 @@ export class AlertService { public error(msg: string, dismissTime?: number) { this.add({ - type: "danger", msg: msg, dismissible: true, dismissTimeout: dismissTime + type: 'danger', msg: msg, dismissible: true, dismissTimeout: dismissTime }); } public warning(msg: string, dismissible?: boolean) { - this.add({ type: "warning", msg: msg, dismissible: true, dismissTimeout: (dismissible ? this.defaultDissmissTmo : 0) }); + this.add({ type: 'warning', msg: msg, dismissible: true, dismissTimeout: (dismissible ? this.defaultDismissTmo : 0) }); } public info(msg: string) { - this.add({ type: "info", msg: msg, dismissible: true, dismissTimeout: this.defaultDissmissTmo }); + this.add({ type: 'info', msg: msg, dismissible: true, dismissTimeout: this.defaultDismissTmo }); } public add(al: IAlert) { - let msg = String(al.msg).replace("\n", "<br>"); + const msg = String(al.msg).replace('\n', '<br>'); this._alerts.push({ show: true, type: al.type, @@ -59,7 +59,7 @@ export class AlertService { } public del(al: IAlert) { - let idx = this._alerts.findIndex((a) => a.id === al.id); + const idx = this._alerts.findIndex((a) => a.id === al.id); if (idx > -1) { this._alerts.splice(idx, 1); } diff --git a/webapp/src/app/services/config.service.spec.ts b/webapp/src/app/services/config.service.spec.ts new file mode 100644 index 0000000..a20d4ba --- /dev/null +++ b/webapp/src/app/services/config.service.spec.ts @@ -0,0 +1,15 @@ +import { TestBed, inject } from '@angular/core/testing'; + +import { ConfigService } from './config.service'; + +describe('ConfigService', () => { + beforeEach(() => { + TestBed.configureTestingModule({ + providers: [ConfigService] + }); + }); + + it('should be created', inject([ConfigService], (service: ConfigService) => { + expect(service).toBeTruthy(); + })); +}); diff --git a/webapp/src/app/services/config.service.ts b/webapp/src/app/services/config.service.ts index bbe2fb8..ffe2b45 100644 --- a/webapp/src/app/services/config.service.ts +++ b/webapp/src/app/services/config.service.ts @@ -3,10 +3,11 @@ import { CookieService } from 'ngx-cookie'; import { Observable } from 'rxjs/Observable'; import { BehaviorSubject } from 'rxjs/BehaviorSubject'; -import { AlertService, IAlert } from "../services/alert.service"; -import { UtilsService } from "../services/utils.service"; +import { AlertService, IAlert } from '../services/alert.service'; +import { UtilsService } from '../services/utils.service'; export interface IConfig { + language: string; projectsRootDir: string; } @@ -18,7 +19,7 @@ export class ConfigService { private confSubject: BehaviorSubject<IConfig>; private confStore: IConfig; - constructor(private _window: Window, + constructor( private cookie: CookieService, private alert: AlertService, private utils: UtilsService, @@ -31,14 +32,15 @@ export class ConfigService { // Load config load() { // Try to retrieve previous config from cookie - let cookConf = this.cookie.getObject("xds-config"); + const cookConf = this.cookie.getObject('xds-config'); if (cookConf != null) { this.confStore = <IConfig>cookConf; } else { // Set default config this.confStore = { - projectsRootDir: "", - //projects: [] + language: 'ENG', + projectsRootDir: '', + // projects: [] }; } } @@ -49,8 +51,8 @@ export class ConfigService { this.confSubject.next(Object.assign({}, this.confStore)); // Don't save projects in cookies (too big!) - let cfg = Object.assign({}, this.confStore); - this.cookie.putObject("xds-config", cfg); + const cfg = Object.assign({}, this.confStore); + this.cookie.putObject('xds-config', cfg); } set projectsRootDir(p: string) { diff --git a/webapp/src/app/services/project.service.ts b/webapp/src/app/services/project.service.ts index 53adc80..61d8f1c 100644 --- a/webapp/src/app/services/project.service.ts +++ b/webapp/src/app/services/project.service.ts @@ -2,25 +2,25 @@ import { Injectable, SecurityContext } from '@angular/core'; import { Observable } from 'rxjs/Observable'; import { BehaviorSubject } from 'rxjs/BehaviorSubject'; -import { XDSAgentService, IXDSProjectConfig } from "../services/xdsagent.service"; +import { XDSAgentService, IXDSProjectConfig } from '../services/xdsagent.service'; export enum ProjectType { - UNSET = "", - NATIVE_PATHMAP = "PathMap", - SYNCTHING = "CloudSync" + UNSET = '', + NATIVE_PATHMAP = 'PathMap', + SYNCTHING = 'CloudSync' } -export var ProjectTypes = [ - { value: ProjectType.NATIVE_PATHMAP, display: "Path mapping" }, - { value: ProjectType.SYNCTHING, display: "Cloud Sync" } +export const ProjectTypes = [ + { value: ProjectType.NATIVE_PATHMAP, display: 'Path mapping' }, + { value: ProjectType.SYNCTHING, display: 'Cloud Sync' } ]; -export var ProjectStatus = { - ErrorConfig: "ErrorConfig", - Disable: "Disable", - Enable: "Enable", - Pause: "Pause", - Syncing: "Syncing" +export const ProjectStatus = { + ErrorConfig: 'ErrorConfig', + Disable: 'Disable', + Enable: 'Enable', + Pause: 'Pause', + Syncing: 'Syncing' }; export interface IProject { @@ -61,7 +61,7 @@ export class ProjectService { // Update Project data this.xdsSvr.ProjectState$.subscribe(prj => { - let i = this._getProjectIdx(prj.id); + const i = this._getProjectIdx(prj.id); if (i >= 0) { // XXX for now, only isInSync and status may change this._prjsList[i].isInSync = prj.isInSync; @@ -76,20 +76,20 @@ export class ProjectService { if (ev && ev.data && ev.data.id) { this._addProject(ev.data); } else { - console.log("Warning: received events with unknown data: ev=", ev); + console.log('Warning: received events with unknown data: ev=', ev); } }); this.xdsSvr.addEventListener('event:project-delete', (ev) => { if (ev && ev.data && ev.data.id) { - let idx = this._prjsList.findIndex(item => item.id === ev.data.id); + const idx = this._prjsList.findIndex(item => item.id === ev.data.id); if (idx === -1) { - console.log("Warning: received events on unknown project id: ev=", ev); + console.log('Warning: received events on unknown project id: ev=', ev); return; } this._prjsList.splice(idx, 1); this.prjsSubject.next(Object.assign([], this._prjsList)); } else { - console.log("Warning: received events with unknown data: ev=", ev); + console.log('Warning: received events with unknown data: ev=', ev); } }); @@ -107,14 +107,14 @@ export class ProjectService { if (this.current && this.current.id) { return this.current.id; } - return ""; + return ''; } Add(prj: IProject): Observable<IProject> { - let xdsPrj: IXDSProjectConfig = { - id: "", + const xdsPrj: IXDSProjectConfig = { + id: '', serverId: prj.serverId, - label: prj.label || "", + label: prj.label || '', clientPath: prj.pathClient.trim(), serverPath: prj.pathServer, type: prj.type, @@ -122,23 +122,23 @@ export class ProjectService { }; // Send config to XDS server return this.xdsSvr.addProject(xdsPrj) - .map(xdsPrj => this._convToIProject(xdsPrj)); + .map(xp => this._convToIProject(xp)); } Delete(prj: IProject): Observable<IProject> { - let idx = this._getProjectIdx(prj.id); - let delPrj = prj; + const idx = this._getProjectIdx(prj.id); + const delPrj = prj; if (idx === -1) { - throw new Error("Invalid project id (id=" + prj.id + ")"); + throw new Error('Invalid project id (id=' + prj.id + ')'); } return this.xdsSvr.deleteProject(prj.id) - .map(res => { return delPrj; }); + .map(res => delPrj); } Sync(prj: IProject): Observable<string> { - let idx = this._getProjectIdx(prj.id); + const idx = this._getProjectIdx(prj.id); if (idx === -1) { - throw new Error("Invalid project id (id=" + prj.id + ")"); + throw new Error('Invalid project id (id=' + prj.id + ')'); } return this.xdsSvr.syncProject(prj.id); } @@ -155,7 +155,7 @@ export class ProjectService { private _convToIProject(rPrj: IXDSProjectConfig): IProject { // Convert XDSFolderConfig to IProject - let pp: IProject = { + const pp: IProject = { id: rPrj.id, serverId: rPrj.serverId, label: rPrj.label, @@ -174,7 +174,7 @@ export class ProjectService { private _addProject(rPrj: IXDSProjectConfig, noNext?: boolean): IProject { // Convert XDSFolderConfig to IProject - let pp = this._convToIProject(rPrj); + const pp = this._convToIProject(rPrj); // add new project this._prjsList.push(pp); diff --git a/webapp/src/app/services/sdk.service.ts b/webapp/src/app/services/sdk.service.ts index 6d8a5f6..d492774 100644 --- a/webapp/src/app/services/sdk.service.ts +++ b/webapp/src/app/services/sdk.service.ts @@ -2,7 +2,7 @@ import { Injectable, SecurityContext } from '@angular/core'; import { Observable } from 'rxjs/Observable'; import { BehaviorSubject } from 'rxjs/BehaviorSubject'; -import { XDSAgentService } from "../services/xdsagent.service"; +import { XDSAgentService } from '../services/xdsagent.service'; export interface ISdk { id: string; @@ -29,7 +29,7 @@ export class SdkService { return; } // FIXME support multiple server - //cfg.servers.forEach(svr => { + // cfg.servers.forEach(svr => { this.xdsSvr.getSdks(cfg.servers[0].id).subscribe((s) => { this._sdksList = s; this.sdksSubject.next(s); @@ -49,6 +49,6 @@ export class SdkService { if (this.current && this.current.id) { return this.current.id; } - return ""; + return ''; } } diff --git a/webapp/src/app/services/utils.service.ts b/webapp/src/app/services/utils.service.ts index 84b9ab6..e665e2a 100644 --- a/webapp/src/app/services/utils.service.ts +++ b/webapp/src/app/services/utils.service.ts @@ -5,29 +5,29 @@ export class UtilsService { constructor() { } getOSName(lowerCase?: boolean): string { - var checkField = function (ff) { - if (ff.indexOf("Linux") !== -1) { - return "Linux"; - } else if (ff.indexOf("Win") !== -1) { - return "Windows"; - } else if (ff.indexOf("Mac") !== -1) { - return "MacOS"; - } else if (ff.indexOf("X11") !== -1) { - return "UNIX"; + const checkField = function (ff) { + if (ff.indexOf('Linux') !== -1) { + return 'Linux'; + } else if (ff.indexOf('Win') !== -1) { + return 'Windows'; + } else if (ff.indexOf('Mac') !== -1) { + return 'MacOS'; + } else if (ff.indexOf('X11') !== -1) { + return 'UNIX'; } - return ""; + return ''; }; let OSName = checkField(navigator.platform); - if (OSName === "") { + if (OSName === '') { OSName = checkField(navigator.appVersion); } - if (OSName === "") { - OSName = "Unknown OS"; + if (OSName === '') { + OSName = 'Unknown OS'; } if (lowerCase) { return OSName.toLowerCase(); } return OSName; } -}
\ No newline at end of file +} diff --git a/webapp/src/app/services/xdsagent.service.ts b/webapp/src/app/services/xdsagent.service.ts index c4f2787..23880ff 100644 --- a/webapp/src/app/services/xdsagent.service.ts +++ b/webapp/src/app/services/xdsagent.service.ts @@ -1,6 +1,6 @@ -import { Injectable } from '@angular/core'; -import { Http, Headers, RequestOptionsArgs, Response } from '@angular/http'; -import { Location } from '@angular/common'; +import { Injectable, Inject } from '@angular/core'; +import { HttpClient, HttpHeaders, HttpErrorResponse } from '@angular/common/http'; +import { DOCUMENT } from '@angular/common'; import { Observable } from 'rxjs/Observable'; import { Subject } from 'rxjs/Subject'; import { BehaviorSubject } from 'rxjs/BehaviorSubject'; @@ -8,7 +8,7 @@ import * as io from 'socket.io-client'; import { AlertService } from './alert.service'; import { ISdk } from './sdk.service'; -import { ProjectType} from "./project.service"; +import { ProjectType } from './project.service'; // Import RxJs required methods import 'rxjs/add/operator/map'; @@ -115,14 +115,16 @@ export class XDSAgentService { private socket: SocketIOClient.Socket; - constructor(private http: Http, private _window: Window, private alert: AlertService) { + constructor( @Inject(DOCUMENT) private document: Document, + private http: HttpClient, private alert: AlertService) { this.XdsConfig$ = this.configSubject.asObservable(); this.Status$ = this.statusSubject.asObservable(); - this.baseUrl = this._window.location.origin + '/api/v1'; + const originUrl = this.document.location.origin; + this.baseUrl = originUrl + '/api/v1'; - let re = this._window.location.origin.match(/http[s]?:\/\/([^\/]*)[\/]?/); + const re = originUrl.match(/http[s]?:\/\/([^\/]*)[\/]?/); if (re === null || re.length < 2) { console.error('ERROR: cannot determine Websocket url'); } else { @@ -188,8 +190,8 @@ export class XDSAgentService { // (project-add and project-delete events are managed by project.service) this.socket.on('event:server-config', ev => { if (ev && ev.data) { - let cfg: IXDServerCfg = ev.data; - let idx = this._config.servers.findIndex(el => el.id === cfg.id); + const cfg: IXDServerCfg = ev.data; + const idx = this._config.servers.findIndex(el => el.id === cfg.id); if (idx >= 0) { this._config.servers[idx] = Object.assign({}, cfg); } @@ -231,7 +233,7 @@ export class XDSAgentService { } setServerRetry(serverID: string, r: number) { - let svr = this._getServer(serverID); + const svr = this._getServer(serverID); if (!svr) { return Observable.of([]); } @@ -249,7 +251,7 @@ export class XDSAgentService { } setServerUrl(serverID: string, url: string) { - let svr = this._getServer(serverID); + const svr = this._getServer(serverID); if (!svr) { return Observable.of([]); } @@ -269,7 +271,7 @@ export class XDSAgentService { ** SDKs ***/ getSdks(serverID: string): Observable<ISdk[]> { - let svr = this._getServer(serverID); + const svr = this._getServer(serverID); if (!svr || !svr.connected) { return Observable.of([]); } @@ -305,42 +307,29 @@ export class XDSAgentService { id: prjID, rpath: dir, cmd: cmd, - sdkID: sdkid || "", + sdkID: sdkid || '', args: args || [], env: env || [], }); } - make(prjID: string, dir: string, sdkid?: string, args?: string[], env?: string[]): Observable<any> { - // SEB TODO add serverID - return this._post('/make', - { - id: prjID, - rpath: dir, - sdkID: sdkid, - args: args || [], - env: env || [], - }); - } - - /** ** Private functions ***/ private _RegisterEvents() { // Register to all existing events - this._post('/events/register', { "name": "event:all" }) + this._post('/events/register', { 'name': 'event:all' }) .subscribe( res => { }, error => { - this.alert.error("ERROR while registering to all events: ", error); + this.alert.error('ERROR while registering to all events: ', error); } ); } private _getServer(ID: string): IXDServerCfg { - let svr = this._config.servers.filter(item => item.id === ID); + const svr = this._config.servers.filter(item => item.id === ID); if (svr.length < 1) { return null; } @@ -349,7 +338,7 @@ export class XDSAgentService { private _attachAuthHeaders(options?: any) { options = options || {}; - let headers = options.headers || new Headers(); + const headers = options.headers || new HttpHeaders(); // headers.append('Authorization', 'Basic ' + btoa('username:password')); headers.append('Accept', 'application/json'); headers.append('Content-Type', 'application/json'); @@ -361,31 +350,24 @@ export class XDSAgentService { private _get(url: string): Observable<any> { return this.http.get(this.baseUrl + url, this._attachAuthHeaders()) - .map((res: Response) => res.json()) .catch(this._decodeError); } private _post(url: string, body: any): Observable<any> { return this.http.post(this.baseUrl + url, JSON.stringify(body), this._attachAuthHeaders()) - .map((res: Response) => res.json()) .catch((error) => { return this._decodeError(error); }); } private _delete(url: string): Observable<any> { return this.http.delete(this.baseUrl + url, this._attachAuthHeaders()) - .map((res: Response) => res.json()) .catch(this._decodeError); } private _decodeError(err: any) { let e: string; - if (err instanceof Response) { - const body = err.json() || 'Agent error'; - e = body.error || JSON.stringify(body); - if (!e || e === "" || e === '{"isTrusted":true}') { - e = `${err.status} - ${err.statusText || 'Unknown error'}`; - } - } else if (typeof err === "object") { + if (err instanceof HttpErrorResponse) { + e = err.error || err.message || 'Unknown error'; + } else if (typeof err === 'object') { if (err.statusText) { e = err.statusText; } else if (err.error) { diff --git a/webapp/src/assets/css/main.css b/webapp/src/assets/css/main.css new file mode 100644 index 0000000..4a42c83 --- /dev/null +++ b/webapp/src/assets/css/main.css @@ -0,0 +1,5 @@ +html, +body { + height: 100%; + margin: 0 auto; +} diff --git a/webapp/assets/favicon.ico b/webapp/src/assets/favicon.ico Binary files differindex 6bf5138..6bf5138 100644 --- a/webapp/assets/favicon.ico +++ b/webapp/src/assets/favicon.ico diff --git a/webapp/src/assets/i18n/en.json b/webapp/src/assets/i18n/en.json new file mode 100644 index 0000000..c5f242c --- /dev/null +++ b/webapp/src/assets/i18n/en.json @@ -0,0 +1,33 @@ +{ + "LOGIN": { + "EMAIL": "Email", + "PASSWORD": "Password", + "SUBMIT_LOGIN": "Login" + }, + "HOME": { + "TITLE": "Welcome" + }, + "MENUBAR": { + "HOME": "Home", + "BUILD": "Build" + }, + "SETTINGS": { + "HOME": { + "TITLE": "Settings" + } + }, + "EVENT_EMMITER": { + "SEL_LANG": "Select Language" + }, + "POPUP": { + "CONFIRM": "Confirm switching user", + "CANCEL": "Cancel", + "TIME-LEFT": "Time left", + "SECONDS": "seconds" + }, + "TOOLTIP": { + "PROJECTS": { + "NEW": "new project successfully created" + } + } +} diff --git a/webapp/src/assets/i18n/fr.json b/webapp/src/assets/i18n/fr.json new file mode 100644 index 0000000..c2b4fb6 --- /dev/null +++ b/webapp/src/assets/i18n/fr.json @@ -0,0 +1,33 @@ +{ + "LOGIN": { + "EMAIL": "Email", + "PASSWORD": "Mot de Passe", + "SUBMIT_LOGIN": "S'identifier" + }, + "HOME": { + "TITLE": "Bienvenue" + }, + "MENUBAR": { + "HOME": "Accueil", + "BUILD": "Build" + }, + "SETTINGS": { + "HOME": { + "TITLE": "Paramètres" + } + }, + "EVENT_EMMITER": { + "SEL_LANG": "Selection de la langue" + }, + "POPUP": { + "CONFIRM": "Confirmer le changement de compte", + "CANCEL": "Annuler", + "TIME-LEFT": "Temps restant", + "SECONDS": "secondes" + }, + "TOOLTIP": { + "PROJECTS": { + "NEW": "un nouveau projet a été créé" + } + } +} diff --git a/webapp/assets/images/iot-bzh-logo-small.png b/webapp/src/assets/images/iot-bzh-logo-small.png Binary files differindex 2c3b2ae..2c3b2ae 100644 --- a/webapp/assets/images/iot-bzh-logo-small.png +++ b/webapp/src/assets/images/iot-bzh-logo-small.png diff --git a/webapp/assets/images/iot-graphx.jpg b/webapp/src/assets/images/iot-graphx.jpg Binary files differindex 74c640a..74c640a 100644 --- a/webapp/assets/images/iot-graphx.jpg +++ b/webapp/src/assets/images/iot-graphx.jpg diff --git a/webapp/src/environments/environment.prod.ts b/webapp/src/environments/environment.prod.ts new file mode 100644 index 0000000..86bb4ef --- /dev/null +++ b/webapp/src/environments/environment.prod.ts @@ -0,0 +1,6 @@ +export const environment = { + production: true, + maxConnectionRetry: 10, + + debug: false, // enable console.debug statements +}; diff --git a/webapp/src/environments/environment.ts b/webapp/src/environments/environment.ts new file mode 100644 index 0000000..c09231e --- /dev/null +++ b/webapp/src/environments/environment.ts @@ -0,0 +1,6 @@ +export const environment = { + production: false, + maxConnectionRetry: 10, + + debug: true, // enable console.debug statements +}; diff --git a/webapp/src/index.html b/webapp/src/index.html index 290b4be..ca8176f 100644 --- a/webapp/src/index.html +++ b/webapp/src/index.html @@ -1,50 +1,24 @@ +<!doctype html> <html> - <head> - <title> - XDS Dashboard - </title> - <meta name="viewport" content="width=device-width, initial-scale=1"> - - <link rel="icon" type="image/x-icon" href="assets/favicon.ico"> - - <!-- TODO cleanup - <link rel="stylesheet" href="lib/foundation-sites/dist/css/foundation.min.css"> - --> - <link <link href="lib/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet"> - - <link rel="stylesheet" href="lib/font-awesome/css/font-awesome.min.css"> - <link rel="stylesheet" href="lib/font-awesome-animation/dist/font-awesome-animation.min.css"> + <meta charset="utf-8"> + <title>XDS Dashboard</title> + <base href="/"> - <!-- 1. Load libraries --> - <!-- Polyfill(s) for older browsers --> - <script src="lib/core-js/client/shim.min.js"></script> - - <script src="lib/zone.js/dist/zone.js"></script> - <script src="lib/reflect-metadata/Reflect.js"></script> - <script src="lib/systemjs/dist/system.src.js"></script> - - <!-- 2. Configure SystemJS --> - <script src="systemjs.config.js"></script> - <script> - System.import('app') - .then(null, console.error.bind(console)); - </script> - - <script src="https://code.jquery.com/jquery-2.1.1.min.js"></script> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <link rel="icon" type="image/x-icon" href="assets/favicon.ico"> + <link rel="stylesheet" href="./assets/css/main.css"> </head> -<!-- 3. Display the application --> - <body style="padding-top: 70px;"> <!-- padding needed due to fixed navbar --> - <app> + <app-root> <div style="text-align:center; position:absolute; top:50%; width:100%; transform:translate(0,-50%);"> <img id="logo-iot" src="assets/images/iot-bzh-logo-small.png"> <br> Loading... <i class="fa fa-spinner fa-spin fa-fw"></i> </div> - </app> + </app-root> </body> </html> diff --git a/webapp/src/main.ts b/webapp/src/main.ts new file mode 100644 index 0000000..401abe5 --- /dev/null +++ b/webapp/src/main.ts @@ -0,0 +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/webapp/src/polyfills.ts b/webapp/src/polyfills.ts new file mode 100644 index 0000000..7831e97 --- /dev/null +++ b/webapp/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/webapp/src/styles.css b/webapp/src/styles.css new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/webapp/src/styles.css diff --git a/webapp/src/systemjs.config.js b/webapp/src/systemjs.config.js deleted file mode 100644 index 15c52ba..0000000 --- a/webapp/src/systemjs.config.js +++ /dev/null @@ -1,69 +0,0 @@ -(function (global) { - System.config({ - paths: { - // paths serve as alias - 'npm:': 'lib/' - }, - bundles: { - "npm:rxjs-system-bundle/Rx.system.min.js": [ - "rxjs", - "rxjs/*", - "rxjs/operator/*", - "rxjs/observable/*", - "rxjs/scheduler/*", - "rxjs/symbol/*", - "rxjs/add/operator/*", - "rxjs/add/observable/*", - "rxjs/util/*" - ] - }, - // 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', - 'ngx-cookie': 'npm:ngx-cookie/bundles/ngx-cookie.umd.js', - // ng2-bootstrap - 'moment': 'npm:moment', - 'ngx-bootstrap/alert': 'npm:ngx-bootstrap/bundles/ngx-bootstrap.umd.min.js', - 'ngx-bootstrap/modal': 'npm:ngx-bootstrap/bundles/ngx-bootstrap.umd.min.js', - 'ngx-bootstrap/accordion': 'npm:ngx-bootstrap/bundles/ngx-bootstrap.umd.min.js', - 'ngx-bootstrap/carousel': 'npm:ngx-bootstrap/bundles/ngx-bootstrap.umd.min.js', - 'ngx-bootstrap/popover': 'npm:ngx-bootstrap/bundles/ngx-bootstrap.umd.min.js', - 'ngx-bootstrap/dropdown': 'npm:ngx-bootstrap/bundles/ngx-bootstrap.umd.min.js', - 'ngx-bootstrap/collapse': 'npm:ngx-bootstrap/bundles/ngx-bootstrap.umd.min.js', - // other libraries - 'socket.io-client': 'npm:socket.io-client/dist/socket.io.min.js' - }, - // packages tells the System loader how to load when no filename and/or no extension - packages: { - 'app': { - main: './main.js', - defaultExtension: 'js' - }, - 'rxjs': { - defaultExtension: false - }, - 'socket.io-client': { - defaultExtension: 'js' - }, - 'ngx-bootstrap': { - format: 'cjs', - main: 'bundles/ng2-bootstrap.umd.js', - defaultExtension: 'js' - }, - 'moment': { - main: 'moment.js', - defaultExtension: 'js' - } - } - }); -})(this); diff --git a/webapp/src/tsconfig.app.json b/webapp/src/tsconfig.app.json new file mode 100644 index 0000000..39ba8db --- /dev/null +++ b/webapp/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/webapp/src/tsconfig.spec.json b/webapp/src/tsconfig.spec.json new file mode 100644 index 0000000..63d89ff --- /dev/null +++ b/webapp/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/webapp/tsconfig.json b/webapp/tsconfig.json index 9bad681..0fdb5c8 100644 --- a/webapp/tsconfig.json +++ b/webapp/tsconfig.json @@ -1,18 +1,19 @@ { + "compileOnSave": false, "compilerOptions": { - "outDir": "dist/app", - "target": "es5", - "module": "commonjs", - "moduleResolution": "node", + "outDir": "./dist/out-tsc", "sourceMap": true, + "declaration": false, + "moduleResolution": "node", "emitDecoratorMetadata": true, "experimentalDecorators": true, - "removeComments": false, - "noImplicitAny": false, - "noStrictGenericChecks": true // better to switch to RxJS 5.4.2 ; workaround https://stackoverflow.com/questions/44810195/how-do-i-get-around-this-subject-incorrectly-extends-observable-error-in-types - }, - "exclude": [ - "gulpfile.ts", - "node_modules" - ] -} + "target": "es5", + "typeRoots": [ + "node_modules/@types" + ], + "lib": [ + "es2017", + "dom" + ] + } +}
\ No newline at end of file diff --git a/webapp/tslint.json b/webapp/tslint.json index 15969a4..22f2336 100644 --- a/webapp/tslint.json +++ b/webapp/tslint.json @@ -1,55 +1,142 @@ { - "rules": { - "class-name": true, - "curly": true, - "eofline": false, - "forin": true, - "indent": [ - true, - 4 + "rulesDirectory": [ + "node_modules/codelyzer" ], - "label-position": true, - "max-line-length": [ - true, - 140 - ], - "no-arg": true, - "no-bitwise": true, - "no-console": [ - true, - "info", - "time", - "timeEnd", - "trace" - ], - "no-construct": true, - "no-debugger": true, - "no-duplicate-variable": true, - "no-empty": false, - "no-eval": true, - "no-string-literal": false, - "no-trailing-whitespace": true, - "no-use-before-declare": true, - "one-line": [ - true, - "check-open-brace", - "check-catch", - "check-else", - "check-whitespace" - ], - "radix": true, - "semicolon": true, - "triple-equals": [ - true, - "allow-null-check" - ], - "variable-name": false, - "whitespace": [ - true, - "check-branch", - "check-decl", - "check-operator", - "check-separator" - ] - } + "rules": { + "arrow-return-shorthand": true, + "callable-types": true, + "class-name": true, + "comment-format": [ + true, + "check-space" + ], + "curly": true, + "eofline": true, + "forin": true, + "import-blacklist": [ + true, + "rxjs" + ], + "import-spacing": true, + "indent": [ + true, + "spaces" + ], + "interface-over-type-literal": true, + "label-position": true, + "max-line-length": [ + true, + 140 + ], + "member-access": false, + "member-ordering": [ + true, + { + "order": [ + "static-field", + "instance-field", + "static-method", + "instance-method" + ] + } + ], + "no-arg": true, + "no-bitwise": true, + "no-console": [ + true, + "debug", + "info", + "time", + "timeEnd", + "trace" + ], + "no-construct": true, + "no-debugger": 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-use-before-declare": true, + "no-var-keyword": true, + "object-literal-sort-keys": false, + "one-line": [ + true, + "check-open-brace", + "check-catch", + "check-else", + "check-whitespace" + ], + "prefer-const": true, + "quotemark": [ + true, + "single" + ], + "radix": true, + "semicolon": [ + true, + "always" + ], + "triple-equals": [ + true, + "allow-null-check" + ], + "typedef-whitespace": [ + true, + { + "call-signature": "nospace", + "index-signature": "nospace", + "parameter": "nospace", + "property-declaration": "nospace", + "variable-declaration": "nospace" + } + ], + "typeof-compare": true, + "unified-signatures": true, + "variable-name": false, + "whitespace": [ + true, + "check-branch", + "check-decl", + "check-operator", + "check-separator", + "check-type" + ], + "directive-selector": [ + true, + "attribute", + "app", + "camelCase" + ], + "component-selector": [ + true, + "element", + ["app", "xds"], + "kebab-case" + ], + "use-input-property-decorator": true, + "use-output-property-decorator": true, + "use-host-property-decorator": true, + "no-input-rename": false, + "no-output-rename": false, + "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 + } } diff --git a/webapp/tslint.prod.json b/webapp/tslint.prod.json deleted file mode 100644 index aa64c7f..0000000 --- a/webapp/tslint.prod.json +++ /dev/null @@ -1,56 +0,0 @@ -{ - "rules": { - "class-name": true, - "curly": true, - "eofline": false, - "forin": true, - "indent": [ - true, - 4 - ], - "label-position": true, - "max-line-length": [ - true, - 140 - ], - "no-arg": true, - "no-bitwise": true, - "no-console": [ - true, - "debug", - "info", - "time", - "timeEnd", - "trace" - ], - "no-construct": true, - "no-debugger": true, - "no-duplicate-variable": true, - "no-empty": false, - "no-eval": true, - "no-string-literal": false, - "no-trailing-whitespace": true, - "no-use-before-declare": true, - "one-line": [ - true, - "check-open-brace", - "check-catch", - "check-else", - "check-whitespace" - ], - "radix": true, - "semicolon": true, - "triple-equals": [ - true, - "allow-null-check" - ], - "variable-name": false, - "whitespace": [ - true, - "check-branch", - "check-decl", - "check-operator", - "check-separator" - ] - } -} |