TSK-389 Fix linting and add it to build process.

This commit is contained in:
Martin Rojas Miguel Angel 2018-03-19 12:34:40 +01:00
parent c7208cf882
commit e4c761bb04
57 changed files with 852 additions and 891 deletions

View File

@ -1,59 +1,54 @@
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"project": {
"name": "admin"
},
"apps": [
{
"root": "src",
"outDir": "dist",
"assets": [
"assets",
"taskana.ico"
],
"index": "index.html",
"main": "main.ts",
"polyfills": "polyfills.ts",
"test": "test.ts",
"tsconfig": "tsconfig.app.json",
"testTsconfig": "tsconfig.spec.json",
"prefix": "app",
"styles": [
"../node_modules/bootstrap-sass/assets/stylesheets/_bootstrap.scss",
"./assets/_site.scss",
"./assets/_forms.scss"
],
"scripts": ["../node_modules/jquery/dist/jquery.min.js","../node_modules/bootstrap/dist/js/bootstrap.min.js"],
"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"
},
{
"project": "src/tsconfig.spec.json"
},
{
"project": "e2e/tsconfig.e2e.json"
}
],
"test": {
"karma": {
"config": "./karma.conf.js"
}
},
"defaults": {
"styleExt": "scss",
"component": {}
}
}
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"project": {
"name": "admin"
},
"apps": [
{
"root": "src",
"outDir": "dist",
"assets": [
"assets",
"taskana.ico"
],
"index": "index.html",
"main": "main.ts",
"polyfills": "polyfills.ts",
"test": "test.ts",
"tsconfig": "tsconfig.app.json",
"testTsconfig": "tsconfig.spec.json",
"prefix": "app",
"styles": [
"../node_modules/bootstrap-sass/assets/stylesheets/_bootstrap.scss",
"./assets/_site.scss",
"./assets/_forms.scss"
],
"scripts": [
"../node_modules/jquery/dist/jquery.min.js",
"../node_modules/bootstrap/dist/js/bootstrap.min.js"
],
"environmentSource": "environments/environment.ts",
"environments": {
"dev": "environments/environment.ts",
"prod": "environments/environment.prod.ts"
}
}
],
"lint": [
{
"project": "src/tsconfig.app.json"
},
{
"project": "src/tsconfig.spec.json"
}
],
"test": {
"karma": {
"config": "./karma.conf.js"
}
},
"defaults": {
"styleExt": "scss",
"component": {}
}
}

View File

@ -18,11 +18,6 @@ Run `ng build` to build the project. The build artifacts will be stored in the `
Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).
## Running end-to-end tests
Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/).
Before running the tests make sure you are serving the app via `ng serve`.
## Further help
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md).

View File

@ -1,14 +0,0 @@
import { AdminPage } from './app.po';
describe('admin App', () => {
let page: AdminPage;
beforeEach(() => {
page = new AdminPage();
});
it('should display message saying app works', () => {
page.navigateTo();
expect(page.getParagraphText()).toEqual('app works!');
});
});

View File

@ -1,11 +0,0 @@
import { browser, by, element } from 'protractor';
export class AdminPage {
navigateTo() {
return browser.get('/');
}
getParagraphText() {
return element(by.css('app-root h1')).getText();
}
}

View File

@ -1,12 +0,0 @@
{
"extends": "../tsconfig.json",
"compilerOptions": {
"outDir": "../out-tsc/e2e",
"module": "commonjs",
"target": "es5",
"types": [
"jasmine",
"node"
]
}
}

View File

@ -5,13 +5,12 @@
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": " ng build --env=dev",
"build:prod": "ng build --environment=prod --no-progress",
"build": " npm run lint && ng build --env=dev ",
"build:prod": "npm run lint && ng build --target=production --environment=prod --no-progress",
"test": "./node_modules/.bin/karma start --single-run --browsers Firefox",
"test-phantom": "./node_modules/.bin/karma start --single-run --browsers PhantomJS",
"test:watch": "./node_modules/.bin/karma start --browsers Chrome",
"lint": "ng lint",
"e2e": "ng e2e"
"lint": "ng lint"
},
"private": true,
"dependencies": {

View File

@ -1,30 +0,0 @@
// 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() {}
},
beforeLaunch: function() {
require('ts-node').register({
project: 'e2e/tsconfig.e2e.json'
});
},
onPrepare() {
jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } }));
}
};

View File

@ -8,53 +8,53 @@ import { Router, Routes } from '@angular/router';
describe('AppComponent', () => {
var app, fixture, debugElement;
let app, fixture, debugElement;
const routes: Routes = [
{ path: 'categories', component: AppComponent }
];
const routes: Routes = [
{ path: 'categories', component: AppComponent }
];
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [
AppComponent
],
imports:[
AngularSvgIconModule,
RouterTestingModule.withRoutes(routes),
HttpClientModule
]
}).compileComponents();
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [
AppComponent
],
imports: [
AngularSvgIconModule,
RouterTestingModule.withRoutes(routes),
HttpClientModule
]
}).compileComponents();
fixture = TestBed.createComponent(AppComponent);
app = fixture.debugElement.componentInstance;
debugElement = fixture.debugElement.nativeElement;
}));
fixture = TestBed.createComponent(AppComponent);
app = fixture.debugElement.componentInstance;
debugElement = fixture.debugElement.nativeElement;
afterEach(async(()=>{
document.body.removeChild(debugElement);
}));
}));
it('should create the app', (() => {
expect(app).toBeTruthy();
}));
afterEach(async(() => {
document.body.removeChild(debugElement);
}));
it(`should have as title 'Taskana administration'`, (() => {
expect(app.title).toEqual('Taskana administration');
}));
it('should create the app', (() => {
expect(app).toBeTruthy();
}));
it('should render title in a <a> tag', (() => {
fixture.detectChanges();
expect(debugElement.querySelector('ul p a').textContent).toContain('Taskana administration');
}));
it(`should have as title 'Taskana administration'`, (() => {
expect(app.title).toEqual('Taskana administration');
}));
it('should call Router.navigateByUrl("categories") and workbasketRoute should be false', (inject([Router], (router: Router) => {
expect(app.workbasketsRoute).toBe(true);
fixture.detectChanges();
router.navigateByUrl(`/categories`);
expect(app.workbasketsRoute).toBe(false);
})));
it('should render title in a <a> tag', (() => {
fixture.detectChanges();
expect(debugElement.querySelector('ul p a').textContent).toContain('Taskana administration');
}));
it('should call Router.navigateByUrl("categories") and workbasketRoute should be false', (inject([Router], (router: Router) => {
expect(app.workbasketsRoute).toBe(true);
fixture.detectChanges();
router.navigateByUrl(`/categories`);
expect(app.workbasketsRoute).toBe(false);
})));
})

View File

@ -3,28 +3,28 @@ import { environment } from '../environments/environment';
import { Router, ActivatedRoute, NavigationStart } from '@angular/router';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
selector: 'taskana-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit{
title = 'Taskana administration';
export class AppComponent implements OnInit {
title = 'Taskana administration';
adminUrl: string = environment.taskanaAdminUrl;
monitorUrl: string = environment.taskanaMonitorUrl;
workplaceUrl: string = environment.taskanaWorkplaceUrl;
workbasketsRoute : boolean = true;
adminUrl: string = environment.taskanaAdminUrl;
monitorUrl: string = environment.taskanaMonitorUrl;
workplaceUrl: string = environment.taskanaWorkplaceUrl;
workbasketsRoute = true;
constructor( private route: ActivatedRoute, private router: Router) {
}
constructor(private route: ActivatedRoute, private router: Router) {
}
ngOnInit(){
this.router.events.subscribe(event => {
if(event instanceof NavigationStart) {
if(event.url.indexOf('categories') !== -1){
this.workbasketsRoute = false;
}
}
});
}
ngOnInit() {
this.router.events.subscribe(event => {
if (event instanceof NavigationStart) {
if (event.url.indexOf('categories') !== -1) {
this.workbasketsRoute = false;
}
}
});
}
}

View File

@ -2,8 +2,8 @@
* Modules
*/
import { BrowserModule } from '@angular/platform-browser';
import { NgModule, } from '@angular/core';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { NgModule, } from '@angular/core';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { HttpClientModule } from '@angular/common/http';
import { AppRoutingModule } from './app-routing.module';
import { AlertModule } from 'ngx-bootstrap';
@ -30,8 +30,8 @@ import { AlertComponent } from './shared/alert/alert.component';
import { SortComponent } from './shared/sort/sort.component';
import { GeneralMessageModalComponent } from './shared/general-message-modal/general-message-modal.component';
//Shared
import { MasterAndDetailComponent} from './shared/masterAndDetail/master-and-detail.component';
// Shared
import { MasterAndDetailComponent } from './shared/masterAndDetail/master-and-detail.component';
/**
* Services
@ -50,54 +50,54 @@ import { MapValuesPipe } from './pipes/map-values.pipe';
import { RemoveNoneTypePipe } from './pipes/remove-none-type';
import { SelectWorkBasketPipe } from './pipes/seleted-workbasket.pipe';
const MODULES = [
BrowserModule,
FormsModule,
TabsModule.forRoot(),
TreeModule,
AppRoutingModule,
AlertModule.forRoot(),
AngularSvgIconModule,
HttpClientModule,
BrowserAnimationsModule,
ReactiveFormsModule
];
const MODULES = [
BrowserModule,
FormsModule,
TabsModule.forRoot(),
TreeModule,
AppRoutingModule,
AlertModule.forRoot(),
AngularSvgIconModule,
HttpClientModule,
BrowserAnimationsModule,
ReactiveFormsModule
];
const DECLARATIONS = [
AppComponent,
WorkbasketListComponent,
AccessItemsComponent,
WorkbasketDetailsComponent,
MasterAndDetailComponent,
WorkbasketInformationComponent,
NoAccessComponent,
SpinnerComponent,
FilterComponent,
IconTypeComponent,
AlertComponent,
GeneralMessageModalComponent,
DistributionTargetsComponent,
SortComponent,
DualListComponent,
MapValuesPipe,
RemoveNoneTypePipe,
SelectWorkBasketPipe
];
const DECLARATIONS = [
AppComponent,
WorkbasketListComponent,
AccessItemsComponent,
WorkbasketDetailsComponent,
MasterAndDetailComponent,
WorkbasketInformationComponent,
NoAccessComponent,
SpinnerComponent,
FilterComponent,
IconTypeComponent,
AlertComponent,
GeneralMessageModalComponent,
DistributionTargetsComponent,
SortComponent,
DualListComponent,
MapValuesPipe,
RemoveNoneTypePipe,
SelectWorkBasketPipe
];
@NgModule({
declarations: DECLARATIONS,
imports: MODULES,
providers: [
WorkbasketService,
MasterAndDetailService,
PermissionService,
{
provide: HTTP_INTERCEPTORS,
useClass: HttpClientInterceptor,
multi: true
},
AlertService
],
bootstrap: [AppComponent]
declarations: DECLARATIONS,
imports: MODULES,
providers: [
WorkbasketService,
MasterAndDetailService,
PermissionService,
{
provide: HTTP_INTERCEPTORS,
useClass: HttpClientInterceptor,
multi: true
},
AlertService
],
bootstrap: [AppComponent]
})
export class AppModule { }

View File

@ -1,7 +1,7 @@
export class Links {
constructor(
public self: {'href': string},
public distributionTargets: {'href': string} = undefined,
public accessItems: {'href': string} = undefined
){}
}
public self: { 'href': string },
public distributionTargets: { 'href': string } = undefined,
public accessItems: { 'href': string } = undefined
) { }
}

View File

@ -1,9 +1,9 @@
import { Links } from "./links";
import { WorkbasketAccessItems } from "./workbasket-access-items";
import { Links } from './links';
import { WorkbasketAccessItems } from './workbasket-access-items';
export class WorkbasketAccessItemsResource {
constructor(
public _embedded: { 'accessItems': Array<WorkbasketAccessItems> } = { 'accessItems': [] },
public _links: Links = undefined
) { }
}
}

View File

@ -1,4 +1,4 @@
import { Links } from "./links";
import { Links } from './links';
export class WorkbasketAccessItems {
constructor(
@ -24,4 +24,4 @@ export class WorkbasketAccessItems {
public permCustom12: boolean = false,
public _links: Links = undefined
) { }
}
}

View File

@ -1,7 +1,8 @@
import { WorkbasketSummary } from './workbasket-summary';
import { Links } from './links';
export class WorkbasketDistributionTargetsResource {
constructor(public _embedded: {'distributionTargets': Array<WorkbasketSummary> } = {'distributionTargets': []}, public _links: Links = null) {
export class WorkbasketDistributionTargetsResource {
constructor(public _embedded: { 'distributionTargets': Array<WorkbasketSummary> } =
{ 'distributionTargets': [] }, public _links: Links = null) {
}
}
}

View File

@ -2,6 +2,7 @@ import { WorkbasketSummary } from './workbasket-summary';
import { Links } from './links';
export class WorkbasketSummaryResource {
constructor(public _embedded: {'workbaskets': Array<WorkbasketSummary> } = {'workbaskets': []}, public _links: Links = null) {
constructor(public _embedded: { 'workbaskets': Array<WorkbasketSummary> } =
{ 'workbaskets': [] }, public _links: Links = null) {
}
}
}

View File

@ -1,11 +1,11 @@
import {Links} from './links';
import { Links } from './links';
export class WorkbasketSummary{
export class WorkbasketSummary {
constructor(
public workbasketId: string,
public key: string,
public name: string,
public description: string,
public description: string,
public owner: string,
public modified: string,
public domain: string,
@ -14,6 +14,6 @@ export class WorkbasketSummary{
public orgLevel2: string,
public orgLevel3: string,
public orgLevel4: string,
public _links: Links = undefined){
}
}
public _links: Links = undefined) {
}
}

View File

@ -1,25 +1,5 @@
import { Links } from './links';
export class Workbasket{
constructor(
public workbasketId: string,
public created: string = undefined,
public key: string = undefined,
public domain: string = undefined,
public type: string = undefined,
public modified: string = undefined,
public name: string = undefined,
public description: string = undefined,
public owner: string = undefined,
public custom1: string = undefined,
public custom2: string = undefined,
public custom3: string = undefined,
public custom4: string = undefined,
public orgLevel1: string = undefined,
public orgLevel2: string = undefined,
public orgLevel3: string = undefined,
public orgLevel4: string = undefined,
public _links:Links = undefined) {
}
export class Workbasket {
public static equals(org: Workbasket, comp: Workbasket): boolean {
if (org.workbasketId !== comp.workbasketId) { return false; }
@ -42,4 +22,25 @@ export class Workbasket{
return true;
}
}
constructor(
public workbasketId: string,
public created: string = undefined,
public key: string = undefined,
public domain: string = undefined,
public type: string = undefined,
public modified: string = undefined,
public name: string = undefined,
public description: string = undefined,
public owner: string = undefined,
public custom1: string = undefined,
public custom2: string = undefined,
public custom3: string = undefined,
public custom4: string = undefined,
public orgLevel1: string = undefined,
public orgLevel2: string = undefined,
public orgLevel3: string = undefined,
public orgLevel4: string = undefined,
public _links: Links = undefined) {
}
}

View File

@ -1,18 +0,0 @@
import {Links} from './links';
export class WorkbasketSummary {
constructor(
public workbasketId: string,
public key: string,
public name: string,
public description: string,
public owner: string,
public modified: string,
public domain: string,
public type: string,
public orgLevel1: string,
public orgLevel2: string,
public orgLevel3: string,
public orgLevel4: string,
public links: Array<Links> = undefined){}
}

View File

@ -1,9 +1,9 @@
import {Pipe, PipeTransform} from '@angular/core';
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({name: 'mapValues'})
@Pipe({ name: 'mapValues' })
export class MapValuesPipe implements PipeTransform {
transform(value: any, args?: any[]): Object[] {
let returnArray = [];
const returnArray = [];
value.forEach((entryVal, entryKey) => {
returnArray.push({
@ -14,4 +14,4 @@ export class MapValuesPipe implements PipeTransform {
return returnArray;
}
}
}

View File

@ -3,14 +3,15 @@ import { Pipe, PipeTransform } from '@angular/core';
@Pipe({ name: 'removeEmptyType' })
export class RemoveNoneTypePipe implements PipeTransform {
transform(value: any): Object[] {
let returnArray = [];
const returnArray = [];
value.forEach((entry) => {
if (entry.key !== '')
if (entry.key !== '') {
returnArray.push({
key: entry.key,
value: entry.value
});
}
});
return returnArray;
}
}
}

View File

@ -9,8 +9,12 @@ export class SelectWorkBasketPipe implements PipeTransform {
}
for (let index = originArray.length - 1; index >= 0; index--) {
if ((arg1 && !selectionArray.some(elementToRemove => { return originArray[index].workbasketId === elementToRemove.workbasketId })) ||
!arg1 && selectionArray.some(elementToRemove => { return originArray[index].workbasketId === elementToRemove.workbasketId })) {
if ((arg1 && !selectionArray.some(elementToRemove => {
return originArray[index].workbasketId === elementToRemove.workbasketId
})) ||
!arg1 && selectionArray.some(elementToRemove => {
return originArray[index].workbasketId === elementToRemove.workbasketId
})) {
originArray.splice(index, 1);
}
}

View File

@ -1,5 +1,7 @@
import { Injectable } from '@angular/core';
import { Subject, Observable } from 'rxjs';
import { Subject } from 'rxjs/Subject';
import { Observable } from 'rxjs/Observable';
export enum AlertType {
SUCCESS = 'success',
@ -11,9 +13,9 @@ export enum AlertType {
export class AlertModel {
constructor(public type: string = AlertType.SUCCESS,
public text: string = 'Success',
public autoClosing: boolean = true,
public closingDelay: number = 2500){
public text: string = 'Success',
public autoClosing: boolean = true,
public closingDelay: number = 2500) {
}
}

View File

@ -6,14 +6,14 @@ import { HttpClientInterceptor } from './http-client-interceptor.service';
import { PermissionService } from './permission.service';
describe('HttpExtensionService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports:[HttpClientModule, HttpModule],
providers: [HttpClientInterceptor, PermissionService]
});
});
beforeEach(() => {
TestBed.configureTestingModule({
imports: [HttpClientModule, HttpModule],
providers: [HttpClientInterceptor, PermissionService]
});
});
it('should be created', inject([HttpClientInterceptor], (service: HttpClientInterceptor) => {
expect(service).toBeTruthy();
}));
it('should be created', inject([HttpClientInterceptor], (service: HttpClientInterceptor) => {
expect(service).toBeTruthy();
}));
});

View File

@ -6,24 +6,22 @@ import 'rxjs/add/observable/throw';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import { PermissionService } from './permission.service';
@Injectable()
export class HttpClientInterceptor implements HttpInterceptor {
permissionService: PermissionService;
permissionService: PermissionService;
constructor(permissionService: PermissionService) {
this.permissionService = permissionService;
}
constructor(permissionService: PermissionService) {
this.permissionService = permissionService;
}
intercept (req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(req).do(event => {
setTimeout(() => {this.permissionService.setPermission(true);},1)
}, err => {
if (err instanceof HttpErrorResponse && (err.status === 401 || err.status ===403 )) {
setTimeout(() => {this.permissionService.setPermission(false);},1)
}
});
}
}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(req).do(event => {
this.permissionService.setPermission(true);
}, err => {
if (err instanceof HttpErrorResponse && (err.status === 401 || err.status === 403)) {
this.permissionService.setPermission(false)
}
});
}
}

View File

@ -9,11 +9,11 @@ export class MasterAndDetailService {
constructor() { }
setShowDetail(newValue : boolean){
this.showDetail.next(newValue)
setShowDetail(newValue: boolean) {
this.showDetail.next(newValue);
}
getShowDetail(){
getShowDetail() {
return this.showDetail.asObservable();
}

View File

@ -15,4 +15,4 @@ export class PermissionService {
hasPermission(): Observable<boolean> {
return this.permission.asObservable();
}
}
}

View File

@ -2,51 +2,52 @@ import { TestBed, inject, async } from '@angular/core/testing';
import { WorkbasketService } from './workbasket.service';
import { Direction } from '../shared/sort/sort.component';
import { HttpModule, Http } from '@angular/http';
import { HttpClientModule, HttpClient } from '@angular/common/http';
import { HttpClientModule, HttpClient } from '@angular/common/http';
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
describe('WorkbasketService ', () => {
var workbasketService, httpClient;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [HttpClientModule, HttpClientTestingModule],
providers: [WorkbasketService, HttpClient, HttpTestingController]
});
httpClient = TestBed.get(HttpClient);
workbasketService = TestBed.get(WorkbasketService);
});
let workbasketService, httpClient;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [HttpClientModule, HttpClientTestingModule],
providers: [WorkbasketService, HttpClient, HttpTestingController]
});
describe(' WorkbasketSummary GET method ',() => {
httpClient = TestBed.get(HttpClient);
workbasketService = TestBed.get(WorkbasketService);
beforeEach(() => {
spyOn(httpClient, 'get').and.returnValue('');
});
});
it('should have a valid query parameter expression sortBy=key, order=asc as default', () => {
workbasketService.getWorkBasketsSummary();
expect(httpClient.get).toHaveBeenCalledWith('http://localhost:8080/v1/workbaskets/?sortBy=key&order=asc', jasmine.any(Object));
});
it('should have a valid query parameter expression with sortBy=name and order=desc', () => {
workbasketService.getWorkBasketsSummary(undefined, 'name', Direction.DESC);
expect(httpClient.get).toHaveBeenCalledWith('http://localhost:8080/v1/workbaskets/?sortBy=name&order=desc', jasmine.any(Object));
});
it('should have a valid query parameter expression with sortBy=name and order=desc and descLike=some description ',() => {
workbasketService.getWorkBasketsSummary(undefined,'name', Direction.DESC, undefined, undefined, 'some description');
expect(httpClient.get).toHaveBeenCalledWith('http://localhost:8080/v1/workbaskets/?sortBy=name&order=desc&descLike=some description', jasmine.any(Object));
});
it('should have a valid query parameter expression with sortBy=key, order=asc, descLike=some description and type=group ',() => {
workbasketService.getWorkBasketsSummary(undefined,'name', Direction.DESC, undefined, undefined, 'some description', undefined, undefined, 'group');
expect(httpClient.get).toHaveBeenCalledWith('http://localhost:8080/v1/workbaskets/?sortBy=name&order=desc&descLike=some description&type=group', jasmine.any(Object));
});
describe(' WorkbasketSummary GET method ', () => {
});
beforeEach(() => {
spyOn(httpClient, 'get').and.returnValue('');
});
it('should have a valid query parameter expression sortBy=key, order=asc as default', () => {
workbasketService.getWorkBasketsSummary();
expect(httpClient.get).toHaveBeenCalledWith('http://localhost:8080/v1/workbaskets/?sortBy=key&order=asc',
jasmine.any(Object));
});
it('should have a valid query parameter expression with sortBy=name and order=desc', () => {
workbasketService.getWorkBasketsSummary(undefined, 'name', Direction.DESC);
expect(httpClient.get).toHaveBeenCalledWith('http://localhost:8080/v1/workbaskets/?sortBy=name&order=desc',
jasmine.any(Object));
});
it('should have a valid query parameter expression with sortBy=name and order=desc and descLike=some description ', () => {
workbasketService.getWorkBasketsSummary(undefined, 'name', Direction.DESC, undefined, undefined, 'some description');
expect(httpClient.get).toHaveBeenCalledWith('http://localhost:8080/v1/workbaskets/' +
'?sortBy=name&order=desc&descLike=some description', jasmine.any(Object));
});
it('should have a valid query parameter expression with sortBy=key, order=asc, descLike=some description and type=group ', () => {
workbasketService.getWorkBasketsSummary(undefined, 'name', Direction.DESC,
undefined, undefined, 'some description', undefined, undefined, 'group');
expect(httpClient.get).toHaveBeenCalledWith('http://localhost:8080/v1/workbaskets/' +
'?sortBy=name&order=desc&descLike=some description&type=group', jasmine.any(Object));
});
});
});

View File

@ -18,13 +18,11 @@ export class WorkbasketService {
public workBasketSelected = new Subject<string>();
public workBasketSaved = new Subject<number>();
constructor(private httpClient: HttpClient) { }
//Sorting
// Sorting
readonly SORTBY = 'sortBy';
readonly ORDER = 'order';
//Filtering
// Filtering
readonly NAME = 'name';
readonly NAMELIKE = 'nameLike';
readonly DESCLIKE = 'descLike';
@ -34,19 +32,21 @@ export class WorkbasketService {
readonly KEY = 'key';
readonly KEYLIKE = 'keyLike';
//Access
// Access
readonly REQUIREDPERMISSION = 'requiredPermission';
httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/hal+json',
'Content-Type': 'application/json',
'Authorization': 'Basic VEVBTUxFQURfMTpURUFNTEVBRF8x'
})
};
private workbasketSummaryRef: Observable<WorkbasketSummaryResource>;
//#region "REST calls"
constructor(private httpClient: HttpClient) { }
// #region "REST calls"
// GET
getWorkBasketsSummary(forceRequest: boolean = false,
sortBy: string = this.KEY,
@ -63,8 +63,9 @@ export class WorkbasketService {
if (this.workbasketSummaryRef && !forceRequest) {
return this.workbasketSummaryRef;
}
return this.workbasketSummaryRef = this.httpClient.get<WorkbasketSummaryResource>(`${environment.taskanaRestUrl}/v1/workbaskets/${this.getWorkbasketSummaryQueryParameters(sortBy, order, name,
nameLike, descLike, owner, ownerLike, type, key, keyLike, requiredPermission)}`, this.httpOptions);
return this.workbasketSummaryRef = this.httpClient.get<WorkbasketSummaryResource>(
`${environment.taskanaRestUrl}/v1/workbaskets/${this.getWorkbasketSummaryQueryParameters(sortBy, order, name,
nameLike, descLike, owner, ownerLike, type, key, keyLike, requiredPermission)}`, this.httpOptions);
}
// GET
@ -92,7 +93,7 @@ export class WorkbasketService {
}
// POST
createWorkBasketAccessItem(url: string, workbasketAccessItem: WorkbasketAccessItems): Observable<WorkbasketAccessItems> {
return this.httpClient.post<WorkbasketAccessItems>(url , workbasketAccessItem, this.httpOptions);
return this.httpClient.post<WorkbasketAccessItems>(url, workbasketAccessItem, this.httpOptions);
}
// PUT
updateWorkBasketAccessItem(url: string, workbasketAccessItem: Array<WorkbasketAccessItems>): Observable<string> {
@ -106,14 +107,13 @@ export class WorkbasketService {
}
// PUT
updateWorkBasketsDistributionTargets(url: string, distributionTargetsIds :Array<string>): Observable<WorkbasketDistributionTargetsResource> {
updateWorkBasketsDistributionTargets(url: string, distributionTargetsIds: Array<string>):
Observable<WorkbasketDistributionTargetsResource> {
return this.httpClient.put<WorkbasketDistributionTargetsResource>(url, distributionTargetsIds, this.httpOptions);
}
//#endregion
//#region "Service extras"
// #endregion
// #region "Service extras"
selectWorkBasket(id: string) {
this.workBasketSelected.next(id);
}
@ -129,9 +129,9 @@ export class WorkbasketService {
workbasketSavedTriggered(): Observable<number> {
return this.workBasketSaved.asObservable();
}
//#endregion
// #endregion
//#region private
// #region private
private getWorkbasketSummaryQueryParameters(sortBy: string,
order: string,
name: string,
@ -143,7 +143,7 @@ export class WorkbasketService {
key: string,
keyLike: string,
requiredPermission: string): string {
let query: string = '?';
let query = '?';
query += sortBy ? `${this.SORTBY}=${sortBy}&` : '';
query += order ? `${this.ORDER}=${order}&` : '';
query += name ? `${this.NAME}=${name}&` : '';
@ -176,5 +176,5 @@ export class WorkbasketService {
return Observable.throw(errMsg);
}
//#endregion
// #endregion
}

View File

@ -12,7 +12,7 @@ describe('AlertComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
imports:[BrowserAnimationsModule],
imports: [BrowserAnimationsModule],
declarations: [AlertComponent],
providers: [AlertService]
})
@ -36,35 +36,35 @@ describe('AlertComponent', () => {
});
it('should show alert message', () => {
alertService.triggerAlert(new AlertModel(AlertType.SUCCESS,'some custom text',));
alertService.triggerAlert(new AlertModel(AlertType.SUCCESS, 'some custom text', ));
fixture.detectChanges();
expect(debugElement.querySelector('.alert.alert-success')).toBeDefined();
expect(debugElement.querySelector('.alert.alert-success').innerText).toBe('some custom text');
});
it('should have differents alert types', () => {
alertService.triggerAlert(new AlertModel(AlertType.DANGER,'some custom text',));
alertService.triggerAlert(new AlertModel(AlertType.DANGER, 'some custom text', ));
fixture.detectChanges();
expect(debugElement.querySelector('.alert.alert-danger')).toBeDefined();
alertService.triggerAlert(new AlertModel(AlertType.WARNING,'some custom text',));
alertService.triggerAlert(new AlertModel(AlertType.WARNING, 'some custom text', ));
fixture.detectChanges();
expect(debugElement.querySelector('.alert.alert-warning')).toBeDefined();
});
it('should define a closing timeout if alert has autoclosing property', (done) => {
alertService.triggerAlert(new AlertModel(AlertType.SUCCESS,'some custom text',true, 5));
it('should define a closing timeout if alert has autoclosing property', (done) => {
alertService.triggerAlert(new AlertModel(AlertType.SUCCESS, 'some custom text', true, 5));
fixture.detectChanges();
expect(component.alert).toBeDefined();
setTimeout(()=>{
setTimeout(() => {
fixture.detectChanges();
expect(component.alert).toBeUndefined();
done();
},6)
}, 6)
});
it('should have defined a closing button if alert has no autoclosing property', () => {
alertService.triggerAlert(new AlertModel(AlertType.DANGER,'some custom text',false));
alertService.triggerAlert(new AlertModel(AlertType.DANGER, 'some custom text', false));
fixture.detectChanges();
expect(debugElement.querySelector('.alert.alert-danger > button')).toBeDefined();
});

View File

@ -8,17 +8,17 @@ import { FilterComponent, FilterModel } from './filter.component';
import { MapValuesPipe } from '../../pipes/map-values.pipe';
describe('FilterComponent', () => {
let component: FilterComponent,
let component: FilterComponent,
fixture: ComponentFixture<FilterComponent>,
debugElement: any;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ FilterComponent, IconTypeComponent, MapValuesPipe ],
imports: [AngularSvgIconModule, FormsModule, HttpClientModule, HttpModule ]
declarations: [FilterComponent, IconTypeComponent, MapValuesPipe],
imports: [AngularSvgIconModule, FormsModule, HttpClientModule, HttpModule]
})
.compileComponents();
.compileComponents();
fixture = TestBed.createComponent(FilterComponent);
component = fixture.componentInstance;
@ -50,7 +50,7 @@ describe('FilterComponent', () => {
});
it('should be able to clear all fields after pressing clear button', () => {
component.filter = new FilterModel('a','a','a','a','a');
component.filter = new FilterModel('a', 'a', 'a', 'a', 'a');
debugElement.querySelector('[title="Clear"]').click();
expect(component.filter.name).toBe('');
expect(component.filter.description).toBe('');
@ -60,14 +60,14 @@ describe('FilterComponent', () => {
});
it('should be able to select a type and return it based on a number', () => {
expect(component).toBeTruthy();
expect(component).toBeTruthy();
});
it('should be able to emit a filter after clicking on search button', (done) => {
component.filter = new FilterModel('a', 'name1', 'a', 'a');
component.filter = new FilterModel('a', 'name1', 'a', 'a');
component.performFilter.subscribe(filter => {
expect(filter.name).toBe('name1');
done();
done();
})
debugElement.querySelector('[title="Search"]').click();
});

View File

@ -2,49 +2,53 @@ import { Component, Input, OnInit, Output, EventEmitter } from '@angular/core';
import { IconTypeComponent, ICONTYPES } from '../type-icon/icon-type.component'
export class FilterModel {
type:string;
name:string;
description:string;
owner:string;
key: string;
constructor(type:string = '', name:string = '', description:string = '', owner:string = '', key:string = ''){
this.type = type;
this.name = name;
this.description= description;
this.owner = owner;
this.key = key;
}
type: string;
name: string;
description: string;
owner: string;
key: string;
constructor(type: string = '', name: string = '', description: string = '', owner: string = '', key: string = '') {
this.type = type;
this.name = name;
this.description = description;
this.owner = owner;
this.key = key;
}
}
@Component({
selector: 'taskana-filter',
templateUrl: './filter.component.html',
styleUrls: ['./filter.component.scss']
selector: 'taskana-filter',
templateUrl: './filter.component.html',
styleUrls: ['./filter.component.scss']
})
export class FilterComponent{
export class FilterComponent {
constructor() {
this.allTypes = IconTypeComponent.allTypes;
}
allTypes: Map<string, string>;
filter: FilterModel = new FilterModel();
@Input()
target:string;
allTypes: Map<string, string>;
filter: FilterModel = new FilterModel();
@Output()
performFilter = new EventEmitter<FilterModel>();
selectType(type: ICONTYPES){
this.filter.type = type;
}
@Input()
target: string;
clear(){
this.filter = new FilterModel();
}
@Output()
performFilter = new EventEmitter<FilterModel>();
search(){
this.performFilter.emit(this.filter);
}
toggleDropDown = false;
constructor() {
this.allTypes = IconTypeComponent.allTypes;
}
selectType(type: ICONTYPES) {
this.filter.type = type;
}
clear() {
this.filter = new FilterModel();
}
search() {
this.performFilter.emit(this.filter);
}
}

View File

@ -7,15 +7,15 @@ declare var $: any;
styleUrls: ['./general-message-modal.component.scss']
})
export class GeneralMessageModalComponent implements OnChanges {
@Input() message: string;
@Input() message: string;
@Output() messageChange = new EventEmitter<string>();
@Input()
title: string = '';
title = '';
@Input()
error: boolean = false;
error = false;
@ViewChild('generalModal')
private modal;

View File

@ -1,4 +1,4 @@
import {Location} from "@angular/common";
import { Location } from '@angular/common';
import { Component, OnInit, OnDestroy } from '@angular/core';
import { TestBed, async, inject, fakeAsync } from '@angular/core/testing';
import { MasterAndDetailComponent } from './master-and-detail.component';
@ -9,65 +9,66 @@ import { HttpClientModule } from '@angular/common/http';
import { MasterAndDetailService } from '../../services/master-and-detail.service'
@Component({
selector: 'dummy-master',
template: 'dummymaster'
selector: 'taskana-dummy-master',
template: 'dummymaster'
})
export class DummyMasterComponent {
}
@Component({
selector: 'dummy-detail',
template: 'dummydetail'
selector: 'taskana-dummy-detail',
template: 'dummydetail'
})
export class DummyDetailComponent {
}
describe('MasterAndDetailComponent ', () => {
var component, fixture, debugElement, location, router;
let component, fixture, debugElement, location, router;
const routes: Routes = [
{ path: 'workbaskets',
component: MasterAndDetailComponent,
children: [
{
path: '',
component: DummyMasterComponent,
outlet: 'master'
},
{
path: ':id',
component: DummyDetailComponent,
outlet: 'detail'
}
]
{
path: 'workbaskets',
component: MasterAndDetailComponent,
children: [
{
path: '',
component: DummyMasterComponent,
outlet: 'master'
},
{
path: ':id',
component: DummyDetailComponent,
outlet: 'detail'
}
]
}
];
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ MasterAndDetailComponent, DummyMasterComponent, DummyDetailComponent ],
imports:[
declarations: [MasterAndDetailComponent, DummyMasterComponent, DummyDetailComponent],
imports: [
RouterTestingModule.withRoutes(routes),
AngularSvgIconModule,
HttpClientModule
],
providers: [MasterAndDetailService]
})
.compileComponents();
.compileComponents();
fixture = TestBed.createComponent(MasterAndDetailComponent);
component = fixture.debugElement.componentInstance;
debugElement = fixture.debugElement.nativeElement;
location = TestBed.get(Location);
router = TestBed.get(Router);
router.initialNavigation();
router.initialNavigation();
}));
afterEach(async(()=>{
afterEach(async(() => {
document.body.removeChild(debugElement);
}));
@ -75,25 +76,25 @@ describe('MasterAndDetailComponent ', () => {
expect(component).toBeTruthy();
});
it('should call Router.navigateByUrl("/wokbaskets") and showDetail property should be false', async ( () => {
it('should call Router.navigateByUrl("/wokbaskets") and showDetail property should be false', async(() => {
expect(component.showDetail).toBe(false);
fixture.detectChanges();
router.navigateByUrl('/workbaskets');
expect(component.showDetail).toBe(false);
}));
it('should call Router.navigateByUrl("/wokbaskets/(detail:Id)") and showDetail property should be true', async ( () => {
it('should call Router.navigateByUrl("/wokbaskets/(detail:Id)") and showDetail property should be true', async(() => {
expect(component.showDetail).toBe(false);
fixture.detectChanges();
router.navigateByUrl('/workbaskets/(detail:2)');
expect(component.showDetail).toBe(true);
}));
it('should navigate to parent state when backIsClicked', async( () => {
it('should navigate to parent state when backIsClicked', async(() => {
const spy = spyOn(router, 'navigateByUrl');
router.navigateByUrl('/workbaskets/(detail:2)');
@ -101,7 +102,7 @@ describe('MasterAndDetailComponent ', () => {
expect(spy.calls.first().args[0]).toBe('/workbaskets/(detail:2)');
component.backClicked();
expect(spy.calls.mostRecent().args.length).toBe(2);
}));
});

View File

@ -1,28 +1,28 @@
import { Component, OnInit, OnDestroy } from '@angular/core';
import { Router, Routes, ActivatedRoute, NavigationStart, RouterEvent } from '@angular/router';
import { Router, Routes, ActivatedRoute, NavigationStart, RouterEvent } from '@angular/router';
import { MasterAndDetailService } from '../../services/master-and-detail.service'
@Component({
selector: 'master-and-detail',
selector: 'taskana-master-and-detail',
templateUrl: './master-and-detail.component.html',
styleUrls: ['./master-and-detail.component.scss'],
})
export class MasterAndDetailComponent implements OnInit{
export class MasterAndDetailComponent implements OnInit {
private detailRoutes: Array<string> = ['/workbaskets/(detail', 'clasifications'];
private sub: any;
showDetail: Boolean = false;
constructor(private route: ActivatedRoute, private router: Router, private masterAndDetailService: MasterAndDetailService){
constructor(private route: ActivatedRoute, private router: Router, private masterAndDetailService: MasterAndDetailService) {
}
ngOnInit(): void {
this.showDetail = this.showDetails();
this.masterAndDetailService.setShowDetail(this.showDetail? true: false);
this.masterAndDetailService.setShowDetail(this.showDetail ? true : false);
this.router.events.subscribe(event => {
if(event instanceof NavigationStart) {
if (event instanceof NavigationStart) {
this.showDetail = this.showDetails(event);
this.masterAndDetailService.setShowDetail(this.showDetail? true: false);
this.masterAndDetailService.setShowDetail(this.showDetail ? true : false);
}
});
}
@ -31,19 +31,19 @@ export class MasterAndDetailComponent implements OnInit{
this.router.navigate(['../'], { relativeTo: this.route });
}
private showDetails(event? : RouterEvent): Boolean {
if(event === undefined) {
private showDetails(event?: RouterEvent): Boolean {
if (event === undefined) {
return this.checkUrl(this.router.url);
}
return this.checkUrl(event.url)
}
private checkUrl(url: string): Boolean {
for(let routeDetail of this.detailRoutes){
if(url.indexOf(routeDetail) !== -1){
for (const routeDetail of this.detailRoutes) {
if (url.indexOf(routeDetail) !== -1) {
return true;
}
}
}
return false;
}
}
}

View File

@ -1,19 +1,19 @@
import { Component, OnInit, Output, EventEmitter } from '@angular/core';
export enum Direction {
ASC = 'asc',
DESC = 'desc'
ASC = 'asc',
DESC = 'desc'
};
export class SortingModel {
sortBy:string;
sortDirection:string;
constructor(sortBy:string = 'key', sortDirection:Direction = Direction.ASC){
this.sortBy = sortBy;
this.sortDirection = sortDirection;
}
export class SortingModel {
sortBy: string;
sortDirection: string;
constructor(sortBy: string = 'key', sortDirection: Direction = Direction.ASC) {
this.sortBy = sortBy;
this.sortDirection = sortDirection;
}
}
@Component({
selector: 'taskana-sort',
@ -21,28 +21,30 @@ export enum Direction {
styleUrls: ['./sort.component.scss']
})
export class SortComponent implements OnInit {
readonly sortingFields: Map<string, string> = new Map([['name', 'Name'], ['key', 'Id'], ['description', 'Description'], ['owner', 'Owner'], ['type', 'Type']]);
readonly sortingFields: Map<string, string> = new Map(
[['name', 'Name'], ['key', 'Id'], ['description', 'Description'], ['owner', 'Owner'], ['type', 'Type']]);
constructor() { }
@Output()
performSorting = new EventEmitter<SortingModel>();
sort: SortingModel = new SortingModel();
constructor() { }
ngOnInit() {
}
changeOrder(sortDirection: string) {
this.sort.sortDirection = (sortDirection === Direction.ASC) ? Direction.ASC : Direction.DESC;
this.search();
this.sort.sortDirection = (sortDirection === Direction.ASC) ? Direction.ASC : Direction.DESC;
this.search();
}
changeSortBy(sortBy: string) {
this.sort.sortBy = sortBy;
this.search();
this.sort.sortBy = sortBy;
this.search();
}
private search(){
private search() {
this.performSorting.emit(this.sort);
}

View File

@ -8,9 +8,9 @@ describe('SpinnerComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ SpinnerComponent ]
declarations: [SpinnerComponent]
})
.compileComponents();
.compileComponents();
}));
beforeEach(() => {

View File

@ -1,4 +1,4 @@
import { Component, Input, ElementRef, Output, EventEmitter } from '@angular/core';
import { Component, Input, ElementRef, Output, EventEmitter, OnDestroy } from '@angular/core';
import { ViewChild } from '@angular/core';
declare var $: any;
@ -7,15 +7,15 @@ declare var $: any;
templateUrl: './spinner.component.html',
styleUrls: ['./spinner.component.scss']
})
export class SpinnerComponent {
export class SpinnerComponent implements OnDestroy {
private currentTimeout: any;
private requestTimeout: any;
private maxRequestTimeout: number = 10000;
private maxRequestTimeout = 10000;
isDelayedRunning: boolean = false;
isDelayedRunning = false;
@Input()
delay: number = 200;
delay = 200;
@Input()
set isRunning(value: boolean) {
@ -34,7 +34,7 @@ export class SpinnerComponent {
}
@Input()
isModal: boolean = false;
isModal = false;
@Input()
positionClass: string = undefined;
@ -48,13 +48,13 @@ export class SpinnerComponent {
private runSpinner(value) {
this.currentTimeout = setTimeout(() => {
if (this.isModal) { $(this.modal.nativeElement).modal('toggle'); }
this.isDelayedRunning = value;
this.cancelTimeout();
this.isDelayedRunning = value;
this.cancelTimeout();
this.requestTimeout = setTimeout(() => {
this.requestTimeoutExceeded.emit('There was an error with your request, please make sure you have internet connection');
this.cancelTimeout();
this.isRunning = false;
},this.maxRequestTimeout);
}, this.maxRequestTimeout);
}, this.delay);
}
private closeModal() {
@ -74,4 +74,4 @@ export class SpinnerComponent {
ngOnDestroy(): any {
this.cancelTimeout();
}
}
}

View File

@ -10,10 +10,10 @@ describe('IconTypeComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
imports:[AngularSvgIconModule,HttpClientModule, HttpModule],
declarations: [ IconTypeComponent ]
imports: [AngularSvgIconModule, HttpClientModule, HttpModule],
declarations: [IconTypeComponent]
})
.compileComponents();
.compileComponents();
}));
beforeEach(() => {

View File

@ -17,20 +17,24 @@ export enum ICONTYPES {
})
export class IconTypeComponent implements OnInit {
public static get allTypes(): Map<string, string> { return new Map([['', 'None'], ['PERSONAL', 'Personal'], ['GROUP', 'Group'], ['CLEARANCE', 'Clearance'], ['TOPIC', 'Topic']])};
constructor() { }
@Input()
type: ICONTYPES = ICONTYPES.PERSONAL;
@Input()
selected: boolean = false;
selected = false;
@Input()
tooltip: boolean = false;
tooltip = false;
public static get allTypes(): Map<string, string> {
return new Map([['', 'None'], ['PERSONAL', 'Personal'], ['GROUP', 'Group'], ['CLEARANCE', 'Clearance'], ['TOPIC', 'Topic']])
};
constructor() { }
ngOnInit() {
}
}

View File

@ -32,14 +32,18 @@ describe('AccessItemsComponent', () => {
beforeEach(() => {
fixture = TestBed.createComponent(AccessItemsComponent);
component = fixture.componentInstance;
component.workbasket = new Workbasket('1','','','','','','','','','','','','','','','', '', new Links(undefined,undefined, {'href': 'someurl' }));
component.workbasket = new Workbasket('1', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
new Links(undefined, undefined, { 'href': 'someurl' }));
workbasketService = TestBed.get(WorkbasketService);
alertService = TestBed.get(AlertService);
spyOn(workbasketService, 'getWorkBasketAccessItems').and.returnValue(Observable.of(new WorkbasketAccessItemsResource(
{'accessItems': new Array<WorkbasketAccessItems>(
new WorkbasketAccessItems('id1', '1', 'accessID1', false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false),
new WorkbasketAccessItems('id2', '1', 'accessID2')) }, new Links({ 'href': 'someurl' })
)));
{
'accessItems': new Array<WorkbasketAccessItems>(
new WorkbasketAccessItems('id1', '1', 'accessID1', false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false, false),
new WorkbasketAccessItems('id2', '1', 'accessID2'))
}, new Links({ 'href': 'someurl' })
)));
spyOn(workbasketService, 'updateWorkBasketAccessItem').and.returnValue(Observable.of(true)),
spyOn(alertService, 'triggerAlert').and.returnValue(Observable.of(true)),
debugElement = fixture.debugElement.nativeElement;
@ -62,7 +66,7 @@ describe('AccessItemsComponent', () => {
});
it('should show Add new access item button', () => {
expect(debugElement.querySelector('#button-add-access-item')).toBeTruthy;
expect(debugElement.querySelector('#button-add-access-item')).toBeTruthy();
});
it('should remove an access item if remove button is clicked', () => {
@ -74,7 +78,8 @@ describe('AccessItemsComponent', () => {
it('should show alert successfull after saving', () => {
component.onSave();
expect(alertService.triggerAlert).toHaveBeenCalledWith(new AlertModel(AlertType.SUCCESS, `Workbasket ${component.workbasket.key} Access items were saved successfully`));
expect(alertService.triggerAlert).toHaveBeenCalledWith(
new AlertModel(AlertType.SUCCESS, `Workbasket ${component.workbasket.key} Access items were saved successfully`));
});
});

View File

@ -1,5 +1,5 @@
import { Component, OnInit, Input, AfterViewInit } from '@angular/core';
import { Subscription } from 'rxjs';
import { Component, OnInit, Input, AfterViewInit, OnDestroy } from '@angular/core';
import { Subscription } from 'rxjs/Subscription';
import { Workbasket } from '../../../model/workbasket';
import { WorkbasketAccessItems } from '../../../model/workbasket-access-items';
@ -15,7 +15,7 @@ declare var $: any;
templateUrl: './access-items.component.html',
styleUrls: ['./access-items.component.scss']
})
export class AccessItemsComponent implements OnInit {
export class AccessItemsComponent implements OnInit, OnDestroy {
@Input()
workbasket: Workbasket;
@ -24,27 +24,28 @@ export class AccessItemsComponent implements OnInit {
accessItems: Array<WorkbasketAccessItems>;
accessItemsClone: Array<WorkbasketAccessItems>;
accessItemsResetClone: Array<WorkbasketAccessItems>;
requestInProgress: boolean = false;
modalSpinner: boolean = true;
requestInProgress = false;
modalSpinner = true;
modalTitle: string;
modalErrorMessage: string;
accessItemsubscription: Subscription;
constructor(private workbasketService: WorkbasketService, private alertService: AlertService) { }
ngOnInit() {
this.accessItemsubscription = this.workbasketService.getWorkBasketAccessItems(this.workbasket._links.accessItems.href).subscribe( (accessItemsResource: WorkbasketAccessItemsResource) =>{
this.accessItemsResource = accessItemsResource;
this.accessItems = accessItemsResource._embedded?accessItemsResource._embedded.accessItems: [];
this.accessItemsClone = this.cloneAccessItems(this.accessItems);
this.accessItemsResetClone = this.cloneAccessItems(this.accessItems);
})
this.accessItemsubscription = this.workbasketService.getWorkBasketAccessItems(this.workbasket._links.accessItems.href)
.subscribe((accessItemsResource: WorkbasketAccessItemsResource) => {
this.accessItemsResource = accessItemsResource;
this.accessItems = accessItemsResource._embedded ? accessItemsResource._embedded.accessItems : [];
this.accessItemsClone = this.cloneAccessItems(this.accessItems);
this.accessItemsResetClone = this.cloneAccessItems(this.accessItems);
})
}
addAccessItem() {
this.accessItems.push(new WorkbasketAccessItems(undefined,this.workbasket.workbasketId, undefined, true));
this.accessItems.push(new WorkbasketAccessItems(undefined, this.workbasket.workbasketId, undefined, true));
this.accessItemsClone.push(new WorkbasketAccessItems());
}
@ -55,38 +56,38 @@ export class AccessItemsComponent implements OnInit {
}
remove(index: number) {
this.accessItems.splice(index,1);
this.accessItemsClone.splice(index,1);
this.accessItems.splice(index, 1);
this.accessItemsClone.splice(index, 1);
}
onSave(): boolean {
this.requestInProgress = true;
this.workbasketService.updateWorkBasketAccessItem(this.accessItemsResource._links.self.href , this.accessItems).subscribe(response =>{
this.accessItemsClone = this.cloneAccessItems(this.accessItems);
this.accessItemsResetClone = this.cloneAccessItems(this.accessItems);
this.alertService.triggerAlert(new AlertModel(AlertType.SUCCESS, `Workbasket ${this.workbasket.name} Access items were saved successfully`));
this.requestInProgress = false;
return true;
},
error => {
this.modalErrorMessage = error.message;
this.requestInProgress = false;
return false;
})
this.workbasketService.updateWorkBasketAccessItem(this.accessItemsResource._links.self.href, this.accessItems)
.subscribe(response => {
this.accessItemsClone = this.cloneAccessItems(this.accessItems);
this.accessItemsResetClone = this.cloneAccessItems(this.accessItems);
this.alertService.triggerAlert(new AlertModel(
AlertType.SUCCESS, `Workbasket ${this.workbasket.name} Access items were saved successfully`));
this.requestInProgress = false;
return true;
},
error => {
this.modalErrorMessage = error.message;
this.requestInProgress = false;
return false;
})
return false;
}
setValue() { debugger; }
private cloneAccessItems(inputaccessItem): Array<WorkbasketAccessItems>{
let accessItemClone = new Array<WorkbasketAccessItems>();
private cloneAccessItems(inputaccessItem): Array<WorkbasketAccessItems> {
const accessItemClone = new Array<WorkbasketAccessItems>();
inputaccessItem.forEach(accessItem => {
accessItemClone.push({... accessItem});
accessItemClone.push({ ...accessItem });
});
return accessItemClone;
}
private ngOnDestroy(): void {
ngOnDestroy(): void {
if (this.accessItemsubscription) { this.accessItemsubscription.unsubscribe(); }
}
}

View File

@ -23,8 +23,8 @@ import { DualListComponent } from './dual-list/dual-list.component';
const workbasketSummaryResource: WorkbasketSummaryResource = new WorkbasketSummaryResource({
'workbaskets': new Array<WorkbasketSummary>(
new WorkbasketSummary("1", "key1", "NAME1", "description 1", "owner 1", "", "", "PERSONAL", "", "", "", ""),
new WorkbasketSummary("2", "key2", "NAME2", "description 2", "owner 2", "", "", "GROUP", "", "", "", ""))
new WorkbasketSummary('1', 'key1', 'NAME1', 'description 1', 'owner 1', '', '', 'PERSONAL', '', '', '', ''),
new WorkbasketSummary('2', 'key2', 'NAME2', 'description 2', 'owner 2', '', '', 'GROUP', '', '', '', ''))
}, new Links({ 'href': 'url' }));
@Component({
@ -43,12 +43,14 @@ describe('DistributionTargetsComponent', () => {
let component: DistributionTargetsComponent;
let fixture: ComponentFixture<DistributionTargetsComponent>;
let workbasketService;
let workbasket = new Workbasket('1', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', new Links({ 'href': 'someurl' }, { 'href': 'someurl' }, { 'href': 'someurl' }));
const workbasket = new Workbasket('1', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
new Links({ 'href': 'someurl' }, { 'href': 'someurl' }, { 'href': 'someurl' }));
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [AngularSvgIconModule, HttpClientModule, HttpModule, JsonpModule],
declarations: [DistributionTargetsComponent, SpinnerComponent, GeneralMessageModalComponent, FilterComponent, SelectWorkBasketPipe, IconTypeComponent, DualListComponent],
declarations: [DistributionTargetsComponent, SpinnerComponent, GeneralMessageModalComponent,
FilterComponent, SelectWorkBasketPipe, IconTypeComponent, DualListComponent],
providers: [WorkbasketService, AlertService]
})
.compileComponents();
@ -70,7 +72,10 @@ describe('DistributionTargetsComponent', () => {
})
spyOn(workbasketService, 'getWorkBasketsDistributionTargets').and.callFake(() => {
return Observable.of(new WorkbasketDistributionTargetsResource(
{ 'distributionTargets': new Array<WorkbasketSummary>(new WorkbasketSummary('id2', '', '', '', '', '', '', '', '', '', '', '', new Links({ 'href': 'someurl' }))) }, new Links({ 'href': 'someurl' })))
{
'distributionTargets': new Array<WorkbasketSummary>(
new WorkbasketSummary('id2', '', '', '', '', '', '', '', '', '', '', '', new Links({ 'href': 'someurl' })))
}, new Links({ 'href': 'someurl' })))
})
fixture.detectChanges();
@ -95,13 +100,13 @@ describe('DistributionTargetsComponent', () => {
expect(component.distributionTargetsRight.length).toBe(1);
component.distributionTargetsLeft.forEach(leftElement => {
component.distributionTargetsRight.forEach(rightElement => {
if (leftElement.workbasketId === rightElement.workbasketId) repeteadElemens = true;
if (leftElement.workbasketId === rightElement.workbasketId) { repeteadElemens = true };
})
})
expect(repeteadElemens).toBeFalsy();
});
it('should filter left list and keep selected elements as selected', () => {
component.performFilter({filterBy:new FilterModel(), side: Side.LEFT});
component.performFilter({ filterBy: new FilterModel(), side: Side.LEFT });
component.distributionTargetsLeft = new Array<WorkbasketSummary>(
new WorkbasketSummary('id1', '', '', '', '', '', '', '', '', '', '', '', new Links({ 'href': 'someurl' }))
)
@ -111,8 +116,10 @@ describe('DistributionTargetsComponent', () => {
expect(component.distributionTargetsRight[0].workbasketId).toBe('id2');
});
it('should reset distribution target and distribution target selected on reset', () => {
component.distributionTargetsLeft.push(new WorkbasketSummary('id4', '', '', '', '', '', '', '', '', '', '', '', new Links({ 'href': 'someurl' })));
component.distributionTargetsRight.push(new WorkbasketSummary('id5', '', '', '', '', '', '', '', '', '', '', '', new Links({ 'href': 'someurl' })));
component.distributionTargetsLeft.push(
new WorkbasketSummary('id4', '', '', '', '', '', '', '', '', '', '', '', new Links({ 'href': 'someurl' })));
component.distributionTargetsRight.push(
new WorkbasketSummary('id5', '', '', '', '', '', '', '', '', '', '', '', new Links({ 'href': 'someurl' })));
expect(component.distributionTargetsLeft.length).toBe(3);
expect(component.distributionTargetsRight.length).toBe(2);
@ -139,6 +146,6 @@ describe('DistributionTargetsComponent', () => {
expect(component.distributionTargetsSelected.length).toBe(2);
expect(component.distributionTargetsSelectedClone.length).toBe(2);
expect(component.distributionTargetsLeft.length).toBe(1);
});
});

View File

@ -1,4 +1,4 @@
import { Component, OnInit, Input } from '@angular/core';
import { Component, OnInit, Input, OnDestroy } from '@angular/core';
import { Workbasket } from '../../../model/workbasket';
import { WorkbasketSummary } from '../../../model/workbasket-summary';
import { WorkbasketAccessItems } from '../../../model/workbasket-access-items';
@ -8,7 +8,7 @@ import { TREE_ACTIONS, KEYS, IActionMapping, ITreeOptions } from 'angular-tree-c
import { WorkbasketService } from '../../../services/workbasket.service';
import { AlertService, AlertModel, AlertType } from '../../../services/alert.service';
import { Subscription } from 'rxjs';
import { Subscription } from 'rxjs/Subscription';
import { element } from 'protractor';
import { WorkbasketSummaryResource } from '../../../model/workbasket-summary-resource';
import { WorkbasketDistributionTargetsResource } from '../../../model/workbasket-distribution-targets-resource';
@ -22,7 +22,7 @@ export enum Side {
templateUrl: './distribution-targets.component.html',
styleUrls: ['./distribution-targets.component.scss']
})
export class DistributionTargetsComponent implements OnInit {
export class DistributionTargetsComponent implements OnInit, OnDestroy {
@Input()
workbasket: Workbasket;
@ -39,9 +39,9 @@ export class DistributionTargetsComponent implements OnInit {
distributionTargetsSelectedClone: Array<WorkbasketSummary>;
requestInProgress: boolean = false;
requestInProgressLeft: boolean = false;
requestInProgressRight: boolean = false;
requestInProgress = false;
requestInProgressLeft = false;
requestInProgressRight = false;
modalErrorMessage: string;
side = Side;
@ -49,27 +49,30 @@ export class DistributionTargetsComponent implements OnInit {
ngOnInit() {
this.onRequest(undefined);
this.distributionTargetsSubscription = this.workbasketService.getWorkBasketsDistributionTargets(this.workbasket._links.distributionTargets.href).subscribe((distributionTargetsSelectedResource: WorkbasketDistributionTargetsResource) => {
this.distributionTargetsSelectedResource = distributionTargetsSelectedResource;
this.distributionTargetsSelected = distributionTargetsSelectedResource._embedded ? distributionTargetsSelectedResource._embedded.distributionTargets : [];
this.distributionTargetsSelectedClone = Object.assign([], this.distributionTargetsSelected);
this.workbasketSubscription = this.workbasketService.getWorkBasketsSummary().subscribe((distributionTargetsAvailable: WorkbasketSummaryResource) => {
this.distributionTargetsLeft = Object.assign([], distributionTargetsAvailable._embedded.workbaskets);
this.distributionTargetsRight = Object.assign([], distributionTargetsAvailable._embedded.workbaskets);
this.distributionTargetsClone = Object.assign([], distributionTargetsAvailable._embedded.workbaskets);
this.onRequest(undefined, true);
});
});
this.distributionTargetsSubscription = this.workbasketService.getWorkBasketsDistributionTargets(
this.workbasket._links.distributionTargets.href).subscribe(
(distributionTargetsSelectedResource: WorkbasketDistributionTargetsResource) => {
this.distributionTargetsSelectedResource = distributionTargetsSelectedResource;
this.distributionTargetsSelected = distributionTargetsSelectedResource._embedded ?
distributionTargetsSelectedResource._embedded.distributionTargets : [];
this.distributionTargetsSelectedClone = Object.assign([], this.distributionTargetsSelected);
this.workbasketSubscription = this.workbasketService.getWorkBasketsSummary().subscribe(
(distributionTargetsAvailable: WorkbasketSummaryResource) => {
this.distributionTargetsLeft = Object.assign([], distributionTargetsAvailable._embedded.workbaskets);
this.distributionTargetsRight = Object.assign([], distributionTargetsAvailable._embedded.workbaskets);
this.distributionTargetsClone = Object.assign([], distributionTargetsAvailable._embedded.workbaskets);
this.onRequest(undefined, true);
});
});
}
moveDistributionTargets(side: number) {
if (side === Side.LEFT) {
let itemsSelected = this.getSelectedItems(this.distributionTargetsLeft, this.distributionTargetsRight)
const itemsSelected = this.getSelectedItems(this.distributionTargetsLeft, this.distributionTargetsRight)
this.distributionTargetsSelected = this.distributionTargetsSelected.concat(itemsSelected);
this.distributionTargetsRight = this.distributionTargetsRight.concat(itemsSelected);
}
else {
let itemsSelected = this.getSelectedItems(this.distributionTargetsRight, this.distributionTargetsLeft);
} else {
const itemsSelected = this.getSelectedItems(this.distributionTargetsRight, this.distributionTargetsLeft);
this.distributionTargetsSelected = this.removeSeletedItems(this.distributionTargetsSelected, itemsSelected);
this.distributionTargetsRight = this.removeSeletedItems(this.distributionTargetsRight, itemsSelected);
this.distributionTargetsLeft = this.distributionTargetsLeft.concat(itemsSelected);
@ -78,20 +81,22 @@ export class DistributionTargetsComponent implements OnInit {
onSave() {
this.requestInProgress = true;
this.workbasketService.updateWorkBasketsDistributionTargets(this.distributionTargetsSelectedResource._links.self.href, this.getSeletedIds()).subscribe(response => {
this.requestInProgress = false;
this.distributionTargetsSelected = response._embedded ? response._embedded.distributionTargets : [];
this.distributionTargetsSelectedClone = Object.assign([], this.distributionTargetsSelected);
this.distributionTargetsClone = Object.assign([], this.distributionTargetsLeft);
this.alertService.triggerAlert(new AlertModel(AlertType.SUCCESS, `Workbasket ${this.workbasket.name} Access items were saved successfully`));
return true;
},
error => {
this.modalErrorMessage = error.message;
this.workbasketService.updateWorkBasketsDistributionTargets(
this.distributionTargetsSelectedResource._links.self.href, this.getSeletedIds()).subscribe(response => {
this.requestInProgress = false;
return false;
}
)
this.distributionTargetsSelected = response._embedded ? response._embedded.distributionTargets : [];
this.distributionTargetsSelectedClone = Object.assign([], this.distributionTargetsSelected);
this.distributionTargetsClone = Object.assign([], this.distributionTargetsLeft);
this.alertService.triggerAlert(new AlertModel(AlertType.SUCCESS,
`Workbasket ${this.workbasket.name} Access items were saved successfully`));
return true;
},
error => {
this.modalErrorMessage = error.message;
this.requestInProgress = false;
return false;
}
)
return false;
}
@ -122,12 +127,12 @@ export class DistributionTargetsComponent implements OnInit {
}
private getSelectedItems(originList: any, destinationList: any): Array<any> {
return originList.filter((element: any) => { return (element.selected === true) });
return originList.filter((item: any) => { return (item.selected === true) });
}
private removeSeletedItems(originList: any, selectedItemList) {
for (let index = originList.length - 1; index >= 0; index--) {
if (selectedItemList.some(elementToRemove => { return originList[index].workbasketId === elementToRemove.workbasketId })) {
if (selectedItemList.some(itemToRemove => { return originList[index].workbasketId === itemToRemove.workbasketId })) {
originList.splice(index, 1);
}
}
@ -145,14 +150,14 @@ export class DistributionTargetsComponent implements OnInit {
}
private getSeletedIds(): Array<string> {
let distributionTargetsSelelected: Array<string> = [];
this.distributionTargetsSelected.forEach(element => {
distributionTargetsSelelected.push(element.workbasketId);
const distributionTargetsSelelected: Array<string> = [];
this.distributionTargetsSelected.forEach(item => {
distributionTargetsSelelected.push(item.workbasketId);
})
return distributionTargetsSelelected;
}
private ngOnDestroy(): void {
ngOnDestroy(): void {
if (this.distributionTargetsSubscription) { this.distributionTargetsSubscription.unsubscribe(); }
if (this.workbasketSubscription) { this.workbasketSubscription.unsubscribe(); }
if (this.workbasketFilterSubscription) { this.workbasketFilterSubscription.unsubscribe(); }

View File

@ -11,20 +11,22 @@ import { Side } from '../distribution-targets.component';
})
export class DualListComponent implements OnInit {
constructor() { }
ngOnInit() {
this.sideNumber = this.side === Side.LEFT ? 0 : 1;
}
@Input() distributionTargets: Array<WorkbasketSummary>;
@Output() distributionTargetsChange = new EventEmitter<Array<WorkbasketSummary>>();
@Input() distributionTargetsSelected: Array<WorkbasketSummary>;
@Output() performDualListFilter = new EventEmitter<{ filterBy: FilterModel, side: Side }>();
@Input() requestInProgress: boolean = false;
@Input() requestInProgress = false;
@Input() side: Side;
sideNumber: number = 0;
sideNumber = 0;
toggleDtl = false;
constructor() { }
ngOnInit() {
this.sideNumber = this.side === Side.LEFT ? 0 : 1;
}
selectAll(selected: boolean) {
this.distributionTargets.forEach((element: any) => {
@ -32,9 +34,7 @@ export class DualListComponent implements OnInit {
});
}
performAvailableFilter(filterModel: FilterModel) {
this.performDualListFilter.emit({ filterBy: filterModel, side: this.side });
}
}

View File

@ -23,7 +23,8 @@ describe('InformationComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [WorkbasketInformationComponent, IconTypeComponent, MapValuesPipe, RemoveNoneTypePipe, SpinnerComponent, GeneralMessageModalComponent],
declarations: [WorkbasketInformationComponent, IconTypeComponent, MapValuesPipe,
RemoveNoneTypePipe, SpinnerComponent, GeneralMessageModalComponent],
imports: [FormsModule, AngularSvgIconModule, HttpClientModule, HttpModule, RouterTestingModule],
providers: [WorkbasketService, AlertService]
@ -44,7 +45,9 @@ describe('InformationComponent', () => {
});
it('should create a panel with heading and form with all fields', async(() => {
component.workbasket = new Workbasket('id', 'created', 'keyModified', 'domain', 'type', 'modified', 'name', 'description', 'owner', 'custom1', 'custom2', 'custom3', 'custom4', 'orgLevel1', 'orgLevel2', 'orgLevel3', 'orgLevel4', null);
component.workbasket = new Workbasket('id', 'created', 'keyModified', 'domain', 'type',
'modified', 'name', 'description', 'owner', 'custom1', 'custom2', 'custom3', 'custom4',
'orgLevel1', 'orgLevel2', 'orgLevel3', 'orgLevel4', null);
fixture.detectChanges();
expect(debugElement.querySelector('#wb-information')).toBeDefined();
expect(debugElement.querySelector('#wb-information > .panel-heading > h4').textContent).toBe('name');
@ -67,7 +70,8 @@ describe('InformationComponent', () => {
it('should create a copy of workbasket when workbasket is selected', () => {
expect(component.workbasketClone).toBeUndefined();
component.workbasket = new Workbasket('id', 'created', 'keyModified', 'domain', 'type', 'modified', 'name', 'description', 'owner', 'custom1', 'custom2', 'custom3', 'custom4', 'orgLevel1', 'orgLevel2', 'orgLevel3', 'orgLevel4', null);
component.workbasket = new Workbasket('id', 'created', 'keyModified', 'domain', 'type', 'modified', 'name', 'description',
'owner', 'custom1', 'custom2', 'custom3', 'custom4', 'orgLevel1', 'orgLevel2', 'orgLevel3', 'orgLevel4', null);
component.ngOnInit();
fixture.detectChanges();
expect(component.workbasket.workbasketId).toEqual(component.workbasketClone.workbasketId);
@ -76,12 +80,12 @@ describe('InformationComponent', () => {
it('should reset requestInProgress after saving request is done', fakeAsync(() => {
component.workbasket = new Workbasket('id', 'created', 'keyModified', 'domain', 'type', 'modified', 'name', 'description',
'owner', 'custom1', 'custom2', 'custom3', 'custom4', 'orgLevel1', 'orgLevel2',
'orgLevel3', 'orgLevel4', new Links({'href': 'someUrl'}));
'orgLevel3', 'orgLevel4', new Links({ 'href': 'someUrl' }));
spyOn(workbasketService, 'updateWorkbasket').and.returnValue(Observable.of(component.workbasket));
spyOn(workbasketService, 'triggerWorkBasketSaved').and.returnValue(Observable.of(component.workbasket));
component.onSave();
expect(component.modalSpinner).toBeTruthy();
expect(component.modalErrorMessage).toBeUndefined
expect(component.modalErrorMessage).toBeUndefined();
expect(component.requestInProgress).toBeFalsy();
}));
@ -89,7 +93,7 @@ describe('InformationComponent', () => {
it('should trigger triggerWorkBasketSaved method after saving request is done', () => {
component.workbasket = new Workbasket('id', 'created', 'keyModified', 'domain', 'type', 'modified', 'name', 'description',
'owner', 'custom1', 'custom2', 'custom3', 'custom4', 'orgLevel1', 'orgLevel2',
'orgLevel3', 'orgLevel4', new Links({'href': 'someUrl'}));
'orgLevel3', 'orgLevel4', new Links({ 'href': 'someUrl' }));
spyOn(workbasketService, 'updateWorkbasket').and.returnValue(Observable.of(component.workbasket));
spyOn(workbasketService, 'triggerWorkBasketSaved').and.returnValue(Observable.of(component.workbasket));
component.onSave();

View File

@ -1,27 +1,27 @@
import { Component, OnInit, Input, Output } from '@angular/core';
import { Component, OnInit, Input, Output, OnDestroy } from '@angular/core';
import { Workbasket } from '../../../model/workbasket';
import { WorkbasketService } from '../../../services/workbasket.service';
import { IconTypeComponent, ICONTYPES } from '../../../shared/type-icon/icon-type.component';
import { Subscription } from 'rxjs';
import { Subscription } from 'rxjs/Subscription';
import { AlertService, AlertModel, AlertType } from '../../../services/alert.service';
import { ActivatedRoute, Params, Router, NavigationStart } from '@angular/router';
@Component({
selector: 'workbasket-information',
selector: 'taskana-workbasket-information',
templateUrl: './workbasket-information.component.html',
styleUrls: ['./workbasket-information.component.scss']
})
export class WorkbasketInformationComponent implements OnInit {
export class WorkbasketInformationComponent implements OnInit, OnDestroy {
@Input()
workbasket: Workbasket;
workbasketClone: Workbasket;
allTypes: Map<string, string>;
requestInProgress: boolean = false;
modalSpinner: boolean = false;
requestInProgress = false;
modalSpinner = false;
modalErrorMessage: string;
modalTitle: string = 'There was error while saving your workbasket';
modalTitle = 'There was error while saving your workbasket';
private workbasketSubscription: Subscription;
private routeSubscription: Subscription;
@ -52,7 +52,7 @@ export class WorkbasketInformationComponent implements OnInit {
workbasketUpdated => {
this.afterRequest();
this.workbasket = workbasketUpdated;
this.workbasketClone = {...this.workbasket};
this.workbasketClone = { ...this.workbasket };
this.alertService.triggerAlert(new AlertModel(AlertType.SUCCESS, `Workbasket ${workbasketUpdated.key} was saved successfully`))
},
error => {
@ -67,16 +67,16 @@ export class WorkbasketInformationComponent implements OnInit {
this.workbasket = { ...this.workbasketClone };
}
private beforeRequest(){
private beforeRequest() {
this.requestInProgress = true;
this.modalSpinner = true;
this.modalErrorMessage = undefined;
}
private afterRequest(){
private afterRequest() {
this.requestInProgress = false;
this.workbasketService.triggerWorkBasketSaved();
}
private checkForChanges() {
@ -89,7 +89,7 @@ export class WorkbasketInformationComponent implements OnInit {
}
private ngOnDestroy() {
ngOnDestroy() {
if (this.workbasketSubscription) { this.workbasketSubscription.unsubscribe(); }
if (this.routeSubscription) { this.routeSubscription.unsubscribe(); }
}

View File

@ -1,6 +1,6 @@
<div class="container-scrollable" >
<taskana-spinner [isRunning]="requestInProgress" class = "centered-horizontally"></taskana-spinner>
<app-no-access *ngIf="!requestInProgress && (!hasPermission || !workbasket && selectedId)" ></app-no-access>
<taskana-no-access *ngIf="!requestInProgress && (!hasPermission || !workbasket && selectedId)" ></taskana-no-access>
<div id ="workbasket-details" *ngIf="workbasket && !requestInProgress">
<ul class="nav nav-tabs" role="tablist">
<li *ngIf="showDetail" class="visible-xs visible-sm hidden">
@ -18,7 +18,7 @@
</ul>
<div class="tab-content">
<div role="tabpanel" class="tab-pane active" id="work-baskets">
<workbasket-information [workbasket]="workbasket"></workbasket-information>
<taskana-workbasket-information [workbasket]="workbasket"></taskana-workbasket-information>
</div>
<div role="tabpanel" class="tab-pane inactive" id="access-items">
<taskana-workbasket-access-items [workbasket]="workbasket"></taskana-workbasket-access-items>

View File

@ -49,13 +49,16 @@ describe('WorkbasketDetailsComponent', () => {
let debugElement;
let masterAndDetailService;
let workbasketService;
let workbasket = new Workbasket('1', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', new Links({ 'href': 'someurl' }, { 'href': 'someurl' }, { 'href': 'someurl' }));
const workbasket = new Workbasket('1', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
new Links({ 'href': 'someurl' }, { 'href': 'someurl' }, { 'href': 'someurl' }));
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [RouterTestingModule, FormsModule, AngularSvgIconModule, HttpClientModule, HttpModule],
declarations: [WorkbasketDetailsComponent, NoAccessComponent, WorkbasketInformationComponent, SpinnerComponent, IconTypeComponent, MapValuesPipe, RemoveNoneTypePipe, AlertComponent, GeneralMessageModalComponent, AccessItemsComponent, DistributionTargetsComponent, FilterComponent, DualListComponent, SelectWorkBasketPipe],
declarations: [WorkbasketDetailsComponent, NoAccessComponent, WorkbasketInformationComponent, SpinnerComponent,
IconTypeComponent, MapValuesPipe, RemoveNoneTypePipe, AlertComponent, GeneralMessageModalComponent, AccessItemsComponent,
DistributionTargetsComponent, FilterComponent, DualListComponent, SelectWorkBasketPipe],
providers: [WorkbasketService, MasterAndDetailService, PermissionService, AlertService]
})
.compileComponents();
@ -72,12 +75,22 @@ describe('WorkbasketDetailsComponent', () => {
spyOn(workbasketService, 'getSelectedWorkBasket').and.callFake(() => { return Observable.of('id1') })
spyOn(workbasketService, 'getWorkBasketsSummary').and.callFake(() => {
return Observable.of(new WorkbasketSummaryResource(
{ 'workbaskets': new Array<WorkbasketSummary>(new WorkbasketSummary('id1', '', '', '', '', '', '', '', '', '', '', '', new Links({ 'href': 'someurl' }))) }, new Links({ 'href': 'someurl' })))
{
'workbaskets': new Array<WorkbasketSummary>(
new WorkbasketSummary('id1', '', '', '', '', '', '', '', '', '', '', '',
new Links({ 'href': 'someurl' })))
}, new Links({ 'href': 'someurl' })))
})
spyOn(workbasketService, 'getWorkBasket').and.callFake(() => { return Observable.of(workbasket) })
spyOn(workbasketService, 'getWorkBasketAccessItems').and.callFake(() => { return Observable.of(new WorkbasketAccessItemsResource({ 'accessItems': new Array<WorkbasketAccessItems>() }, new Links({ 'href': 'url' }))) })
spyOn(workbasketService, 'getWorkBasketsDistributionTargets').and.callFake(() => { return Observable.of(new WorkbasketSummaryResource({ 'workbaskets': new Array<WorkbasketSummary>() }, new Links({ 'href': 'url' }))) })
spyOn(workbasketService, 'getWorkBasketAccessItems').and.callFake(() => {
return Observable.of(new WorkbasketAccessItemsResource(
{ 'accessItems': new Array<WorkbasketAccessItems>() }, new Links({ 'href': 'url' })))
})
spyOn(workbasketService, 'getWorkBasketsDistributionTargets').and.callFake(() => {
return Observable.of(new WorkbasketSummaryResource(
{ 'workbaskets': new Array<WorkbasketSummary>() }, new Links({ 'href': 'url' })))
})
});
@ -89,20 +102,20 @@ describe('WorkbasketDetailsComponent', () => {
expect(component).toBeTruthy();
});
it('should has created app-no-access if workbasket is not defined', () => {
it('should has created taskana-no-access if workbasket is not defined', () => {
expect(component.workbasket).toBeUndefined();
expect(debugElement.querySelector('app-no-access')).toBeTruthy;
expect(debugElement.querySelector('taskana-no-access')).toBeTruthy();
});
it('should has created workbasket-details if workbasket is defined and app-no-access should dissapear', () => {
it('should has created taskana-workbasket-details if workbasket is defined and taskana-no-access should dissapear', () => {
expect(component.workbasket).toBeUndefined();
expect(debugElement.querySelector('app-no-access')).toBeTruthy;
expect(debugElement.querySelector('taskana-no-access')).toBeTruthy();
component.workbasket = workbasket;
fixture.detectChanges();
expect(debugElement.querySelector('app-no-access')).toBeFalsy;
expect(debugElement.querySelector('worbasket-details')).toBeTruthy;
expect(debugElement.querySelector('taskana-no-access')).toBeFalsy();
expect(debugElement.querySelector('taskana-workbasket-information')).toBeTruthy();
});

View File

@ -1,26 +1,26 @@
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
import { Component, OnInit, Input, Output, EventEmitter, OnDestroy } from '@angular/core';
import { Workbasket } from '../../model/workbasket';
import { WorkbasketService } from '../../services/workbasket.service'
import { MasterAndDetailService } from '../../services/master-and-detail.service'
import { ActivatedRoute, Params, Router, NavigationStart } from '@angular/router';
import { PermissionService } from '../../services/permission.service';
import { Subscription } from 'rxjs';
import { Subscription } from 'rxjs/Subscription';
import { WorkbasketSummary } from '../../model/workbasket-summary';
import { WorkbasketSummaryResource } from '../../model/workbasket-summary-resource';
@Component({
selector: 'workbasket-details',
selector: 'taskana-workbasket-details',
templateUrl: './workbasket-details.component.html',
styleUrls: ['./workbasket-details.component.scss']
})
export class WorkbasketDetailsComponent implements OnInit {
export class WorkbasketDetailsComponent implements OnInit, OnDestroy {
selectedId: number = -1;
workbasket: Workbasket;
showDetail: boolean = false;
hasPermission: boolean = true;
requestInProgress: boolean = false;
selectedId = -1;
showDetail = false;
hasPermission = true;
requestInProgress = false;
private workbasketSelectedSubscription: Subscription;
private workbasketSubscription: Subscription;
@ -44,7 +44,7 @@ export class WorkbasketDetailsComponent implements OnInit {
});
this.routeSubscription = this.route.params.subscribe(params => {
let id = params['id'];
const id = params['id'];
if (id && id !== '') {
this.selectedId = id;
this.service.selectWorkBasket(id);
@ -71,7 +71,7 @@ export class WorkbasketDetailsComponent implements OnInit {
private getWorkbasketInformation(workbasketIdSelected: string) {
this.service.getWorkBasketsSummary().subscribe((workbasketSummary: WorkbasketSummaryResource) => {
let workbasketSummarySelected = this.getWorkbasketSummaryById(workbasketSummary._embedded.workbaskets, workbasketIdSelected);
const workbasketSummarySelected = this.getWorkbasketSummaryById(workbasketSummary._embedded.workbaskets, workbasketIdSelected);
if (workbasketSummarySelected && workbasketSummarySelected._links) {
this.workbasketSubscription = this.service.getWorkBasket(workbasketSummarySelected._links.self.href).subscribe(workbasket => {
this.workbasket = workbasket;

View File

@ -20,7 +20,7 @@ import { Links } from '../../model/links';
@Component({
selector: 'dummy-detail',
selector: 'taskana-dummy-detail',
template: 'dummydetail'
})
export class DummyDetailComponent {
@ -37,8 +37,8 @@ export class FilterComponent {
const workbasketSummaryResource: WorkbasketSummaryResource = new WorkbasketSummaryResource({
'workbaskets': new Array<WorkbasketSummary>(
new WorkbasketSummary("1", "key1", "NAME1", "description 1", "owner 1", "", "", "PERSONAL", "", "", "", ""),
new WorkbasketSummary("2", "key2", "NAME2", "description 2", "owner 2", "", "", "GROUP", "", "", "", ""))
new WorkbasketSummary('1', 'key1', 'NAME1', 'description 1', 'owner 1', '', '', 'PERSONAL', '', '', '', ''),
new WorkbasketSummary('2', 'key2', 'NAME2', 'description 2', 'owner 2', '', '', 'GROUP', '', '', '', ''))
}, new Links({ 'href': 'url' }));
@ -55,7 +55,8 @@ describe('WorkbasketListComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [WorkbasketListComponent, DummyDetailComponent, SpinnerComponent, FilterComponent, RemoveNoneTypePipe, IconTypeComponent, SortComponent, MapValuesPipe],
declarations: [WorkbasketListComponent, DummyDetailComponent, SpinnerComponent, FilterComponent,
RemoveNoneTypePipe, IconTypeComponent, SortComponent, MapValuesPipe],
imports: [
AngularSvgIconModule,
HttpModule,
@ -93,15 +94,16 @@ describe('WorkbasketListComponent', () => {
})
});
it('should have wb-action-toolbar, wb-search-bar, wb-list-container, wb-pagination, collapsedMenufilterWb and taskana-filter created in the html', () => {
expect(debugElement.querySelector('#wb-action-toolbar')).toBeDefined();
expect(debugElement.querySelector('#wb-search-bar')).toBeDefined();
expect(debugElement.querySelector('#wb-pagination')).toBeDefined();
expect(debugElement.querySelector('#wb-list-container')).toBeDefined();
expect(debugElement.querySelector('#collapsedMenufilterWb')).toBeDefined();
expect(debugElement.querySelector('taskana-filter')).toBeDefined();
expect(debugElement.querySelectorAll('#wb-list-container > li').length).toBe(3);
});
it('should have wb-action-toolbar, wb-search-bar, wb-list-container, wb-pagination,' +
' collapsedMenufilterWb and taskana-filter created in the html', () => {
expect(debugElement.querySelector('#wb-action-toolbar')).toBeDefined();
expect(debugElement.querySelector('#wb-search-bar')).toBeDefined();
expect(debugElement.querySelector('#wb-pagination')).toBeDefined();
expect(debugElement.querySelector('#wb-list-container')).toBeDefined();
expect(debugElement.querySelector('#collapsedMenufilterWb')).toBeDefined();
expect(debugElement.querySelector('taskana-filter')).toBeDefined();
expect(debugElement.querySelectorAll('#wb-list-container > li').length).toBe(3);
});
it('should have two workbasketsummary rows created with the second one selected.', () => {
expect(debugElement.querySelectorAll('#wb-list-container > li').length).toBe(3);
@ -110,8 +112,10 @@ describe('WorkbasketListComponent', () => {
});
it('should have two workbasketsummary rows created with two different icons: user and users', () => {
expect(debugElement.querySelectorAll('#wb-list-container > li')[1].querySelector('svg-icon').getAttribute('ng-reflect-src')).toBe('./assets/icons/user.svg');
expect(debugElement.querySelectorAll('#wb-list-container > li')[2].querySelector('svg-icon').getAttribute('ng-reflect-src')).toBe('./assets/icons/users.svg');
expect(debugElement.querySelectorAll('#wb-list-container > li')[1]
.querySelector('svg-icon').getAttribute('ng-reflect-src')).toBe('./assets/icons/user.svg');
expect(debugElement.querySelectorAll('#wb-list-container > li')[2]
.querySelector('svg-icon').getAttribute('ng-reflect-src')).toBe('./assets/icons/users.svg');
});
it('should have rendered sort by: name, id, description, owner and type', () => {
@ -124,10 +128,11 @@ describe('WorkbasketListComponent', () => {
});
it('should have performRequest with forced = true after performFilter is triggered', (() => {
let type = 'PERSONAL', name = 'someName', description = 'someDescription', owner = 'someOwner', key = 'someKey';
let filter = new FilterModel(type, name, description, owner, key);
const type = 'PERSONAL', name = 'someName', description = 'someDescription', owner = 'someOwner', key = 'someKey';
const filter = new FilterModel(type, name, description, owner, key);
component.performFilter(filter);
expect(workbasketService.getWorkBasketsSummary).toHaveBeenCalledWith(true, 'key', 'asc', undefined, name, description, undefined, owner, type, undefined, key);
expect(workbasketService.getWorkBasketsSummary).toHaveBeenCalledWith(true, 'key', 'asc', undefined,
name, description, undefined, owner, type, undefined, key);
}));

View File

@ -1,4 +1,4 @@
import { Component, OnInit, EventEmitter } from '@angular/core';
import { Component, OnInit, EventEmitter, OnDestroy } from '@angular/core';
import { WorkbasketSummaryResource } from '../../model/workbasket-summary-resource';
import { WorkbasketSummary } from '../../model/workbasket-summary';
import { WorkbasketService } from '../../services/workbasket.service'
@ -8,18 +8,16 @@ import { Direction, SortingModel } from '../../shared/sort/sort.component'
import { Router, ActivatedRoute } from '@angular/router';
@Component({
selector: 'workbasket-list',
outputs: ['selectedWorkbasket'],
selector: 'taskana-workbasket-list',
templateUrl: './workbasket-list.component.html',
styleUrls: ['./workbasket-list.component.scss']
})
export class WorkbasketListComponent implements OnInit {
public selectedWorkbasket: EventEmitter<WorkbasketSummary> = new EventEmitter();
export class WorkbasketListComponent implements OnInit, OnDestroy {
newWorkbasket: WorkbasketSummary;
selectedId: string = undefined;
workbaskets: Array<WorkbasketSummary> = [];
requestInProgress: boolean = false;
requestInProgress = false;
sort: SortingModel = new SortingModel();
filterBy: FilterModel = new FilterModel();
@ -33,7 +31,7 @@ export class WorkbasketListComponent implements OnInit {
ngOnInit() {
this.requestInProgress = true;
this.workBasketSummarySubscription = this.workbasketService.getWorkBasketsSummary().subscribe(resultList => {
this.workbaskets = resultList._embedded.workbaskets;
this.workbaskets = resultList._embedded ? resultList._embedded.workbaskets : [];
this.requestInProgress = false;
});
@ -48,18 +46,18 @@ export class WorkbasketListComponent implements OnInit {
selectWorkbasket(id: string) {
this.selectedId = id;
if(!this.selectedId) {
if (!this.selectedId) {
this.router.navigate(['/workbaskets']);
return
return
}
this.router.navigate([{outlets: { detail: [this.selectedId] } }], { relativeTo: this.route });
this.router.navigate([{ outlets: { detail: [this.selectedId] } }], { relativeTo: this.route });
}
performSorting(sort: SortingModel) {
this.sort = sort;
this.performRequest();
}
performFilter(filterBy: FilterModel) {
@ -81,27 +79,28 @@ export class WorkbasketListComponent implements OnInit {
private performRequest(): void {
this.requestInProgress = true;
this.workbaskets = [];
this.workbasketServiceSubscription.add(this.workbasketService.getWorkBasketsSummary(true, this.sort.sortBy, this.sort.sortDirection, undefined,
this.workbasketServiceSubscription.add(this.workbasketService.getWorkBasketsSummary(true, this.sort.sortBy,
this.sort.sortDirection, undefined,
this.filterBy.name, this.filterBy.description, undefined, this.filterBy.owner,
this.filterBy.type, undefined, this.filterBy.key).subscribe(resultList => {
this.workbaskets = resultList._embedded? resultList._embedded.workbaskets:[];
this.workbaskets = resultList._embedded ? resultList._embedded.workbaskets : [];
this.requestInProgress = false;
this.unSelectWorkbasket();
}));
}
private unSelectWorkbasket() : void{
if (!this.workbaskets.find( wb => wb.workbasketId === this.selectedId)){
private unSelectWorkbasket(): void {
if (!this.workbaskets.find(wb => wb.workbasketId === this.selectedId)) {
this.selectWorkbasket(undefined);
}
}
private ngOnDestroy() {
ngOnDestroy() {
this.workBasketSummarySubscription.unsubscribe();
this.workbasketServiceSubscription.unsubscribe();
this.workbasketServiceSavedSubscription.unsubscribe();
}
}

View File

@ -8,38 +8,40 @@ import { HttpModule } from '@angular/http';
import { HttpClientModule } from '@angular/common/http';
describe('NoAccessComponent', () => {
let component: NoAccessComponent;
let fixture: ComponentFixture<NoAccessComponent>;
let debugElement;
let component: NoAccessComponent;
let fixture: ComponentFixture<NoAccessComponent>;
let debugElement;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports:[RouterTestingModule, AngularSvgIconModule, HttpModule, HttpClientModule],
declarations: [ NoAccessComponent ]
})
.compileComponents();
}));
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [RouterTestingModule, AngularSvgIconModule, HttpModule, HttpClientModule],
declarations: [NoAccessComponent]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(NoAccessComponent);
component = fixture.componentInstance;
debugElement = fixture.debugElement.nativeElement;
});
beforeEach(() => {
fixture = TestBed.createComponent(NoAccessComponent);
component = fixture.componentInstance;
debugElement = fixture.debugElement.nativeElement;
});
afterEach(() =>{
document.body.removeChild(debugElement);
});
afterEach(() => {
document.body.removeChild(debugElement);
});
it('should create', () => {
expect(component).toBeTruthy();
});
it('should create', () => {
expect(component).toBeTruthy();
});
it('should have a back button with the following classes "btn btn-default back-button pull-left visible-xs visible-sm hidden blue"', () => {
expect(debugElement.querySelector('button').attributes.class.value).toBe('btn btn-default back-button pull-left visible-xs visible-sm hidden blue');
});
it('should have a back button with the following classes "btn btn-default back-button' +
'pull-left visible-xs visible-sm hidden blue"', () => {
expect(debugElement.querySelector('button').attributes.class.value)
.toBe('btn btn-default back-button pull-left visible-xs visible-sm hidden blue');
});
it('should have a div with title and svg', () => {
expect(debugElement.querySelector('div.center-block.no-access > h3' ).textContent).toBeDefined();
expect(debugElement.querySelector('div.center-block.no-access > svg-icon' ).attributes.src.value).toBe('./assets/icons/noaccess.svg');
});
it('should have a div with title and svg', () => {
expect(debugElement.querySelector('div.center-block.no-access > h3').textContent).toBeDefined();
expect(debugElement.querySelector('div.center-block.no-access > svg-icon').attributes.src.value).toBe('./assets/icons/noaccess.svg');
});
});

View File

@ -1,9 +1,9 @@
import { Component, OnInit } from '@angular/core';
import {Router, ActivatedRoute} from '@angular/router';
import { Router, ActivatedRoute } from '@angular/router';
import { RouterTestingModule } from '@angular/router/testing';
@Component({
selector: 'app-no-access',
selector: 'taskana-no-access',
templateUrl: './no-access.component.html',
styleUrls: ['./no-access.component.scss']
})

View File

@ -102,7 +102,7 @@
/*
*Remove bootstrap cols padding for master and detail component
*/
.no-gutter > master-and-detail > [class*='col-'] {
.no-gutter > taskana-master-and-detail > [class*='col-'] {
padding-right: 0;
padding-left: 0;
}
@ -229,7 +229,7 @@ li > div.row > dl {
margin-top: 4px;
}
workbasket-information, taskana-workbasket-access-items, taskana-workbaskets-distribution-targets {
taskana-workbasket-information, taskana-workbasket-access-items, taskana-workbaskets-distribution-targets {
&> .panel{
border: none;
box-shadow: none;

View File

@ -7,11 +7,11 @@
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="taskana.ico">
<link rel="icon" type="image/x-icon" href="./taskana.ico">
</head>
<body>
<app-root></app-root>
<taskana-root></taskana-root>
</body>

View File

@ -1,130 +1,126 @@
{
"rulesDirectory": [
"node_modules/codelyzer"
],
"rules": {
"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,
"static-before-instance",
"variables-before-functions"
],
"no-arg": true,
"no-bitwise": true,
"no-console": [
true,
"debug",
"info",
"time",
"timeEnd",
"trace"
],
"no-construct": true,
"no-debugger": true,
"no-empty": false,
"no-empty-interface": true,
"no-eval": true,
"no-inferrable-types": [
true,
"ignore-params"
],
"no-shadowed-variable": true,
"no-string-literal": false,
"no-string-throw": true,
"no-switch-case-fall-through": true,
"no-trailing-whitespace": 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": [
"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",
"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
}
}
"rulesDirectory": [
"node_modules/codelyzer"
],
"rules": {
"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,
"tab"
],
"interface-over-type-literal": true,
"label-position": true,
"max-line-length": [
true,
140
],
"member-access": false,
"member-ordering": [
true,
"static-before-instance",
"variables-before-functions"
],
"no-arg": true,
"no-bitwise": true,
"no-console": [
true,
"debug",
"info",
"time",
"timeEnd",
"trace"
],
"no-construct": true,
"no-debugger": true,
"no-empty": false,
"no-empty-interface": true,
"no-eval": true,
"no-inferrable-types": [
true,
"ignore-params"
],
"no-shadowed-variable": true,
"no-string-literal": false,
"no-string-throw": true,
"no-switch-case-fall-through": true,
"no-trailing-whitespace": 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": [
"always"
],
"triple-equals": [
true,
"allow-null-check"
],
"typedef-whitespace": [
true,
{
"call-signature": "nospace",
"index-signature": "nospace",
"parameter": "nospace",
"property-declaration": "nospace",
"variable-declaration": "nospace"
}
],
"unified-signatures": true,
"variable-name": false,
"whitespace": [
true,
"check-branch",
"check-decl",
"check-operator",
"check-separator",
"check-type"
],
"directive-selector": [
true,
"attribute",
"taskana",
"camelCase"
],
"component-selector": [
true,
"element",
"taskana",
"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
}
}