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

@ -23,7 +23,10 @@
"./assets/_site.scss",
"./assets/_forms.scss"
],
"scripts": ["../node_modules/jquery/dist/jquery.min.js","../node_modules/bootstrap/dist/js/bootstrap.min.js"],
"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",
@ -31,20 +34,12 @@
}
}
],
"e2e": {
"protractor": {
"config": "./protractor.conf.js"
}
},
"lint": [
{
"project": "src/tsconfig.app.json"
},
{
"project": "src/tsconfig.spec.json"
},
{
"project": "e2e/tsconfig.e2e.json"
}
],
"test": {

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,7 +8,7 @@ import { Router, Routes } from '@angular/router';
describe('AppComponent', () => {
var app, fixture, debugElement;
let app, fixture, debugElement;
const routes: Routes = [
{ path: 'categories', component: AppComponent }

View File

@ -3,7 +3,7 @@ import { environment } from '../environments/environment';
import { Router, ActivatedRoute, NavigationStart } from '@angular/router';
@Component({
selector: 'app-root',
selector: 'taskana-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
@ -13,7 +13,7 @@ export class AppComponent implements OnInit{
adminUrl: string = environment.taskanaAdminUrl;
monitorUrl: string = environment.taskanaMonitorUrl;
workplaceUrl: string = environment.taskanaWorkplaceUrl;
workbasketsRoute : boolean = true;
workbasketsRoute = true;
constructor(private route: ActivatedRoute, private router: Router) {
}

View File

@ -1,5 +1,5 @@
import { Links } from "./links";
import { WorkbasketAccessItems } from "./workbasket-access-items";
import { Links } from './links';
import { WorkbasketAccessItems } from './workbasket-access-items';
export class WorkbasketAccessItemsResource {
constructor(

View File

@ -1,4 +1,4 @@
import { Links } from "./links";
import { Links } from './links';
export class WorkbasketAccessItems {
constructor(

View File

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

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

View File

@ -3,13 +3,14 @@ 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',

View File

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

View File

@ -10,7 +10,7 @@ export class MasterAndDetailService {
constructor() { }
setShowDetail(newValue: boolean) {
this.showDetail.next(newValue)
this.showDetail.next(newValue);
}
getShowDetail() {

View File

@ -7,7 +7,7 @@ import { HttpClientTestingModule, HttpTestingController } from '@angular/common/
describe('WorkbasketService ', () => {
var workbasketService, httpClient;
let workbasketService, httpClient;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [HttpClientModule, HttpClientTestingModule],
@ -27,26 +27,27 @@ describe('WorkbasketService ', () => {
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));
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));
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));
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));
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,8 +18,6 @@ export class WorkbasketService {
public workBasketSelected = new Subject<string>();
public workBasketSaved = new Subject<number>();
constructor(private httpClient: HttpClient) { }
// Sorting
readonly SORTBY = 'sortBy';
readonly ORDER = 'order';
@ -39,13 +37,15 @@ export class WorkbasketService {
httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/hal+json',
'Content-Type': 'application/json',
'Authorization': 'Basic VEVBTUxFQURfMTpURUFNTEVBRF8x'
})
};
private workbasketSummaryRef: Observable<WorkbasketSummaryResource>;
constructor(private httpClient: HttpClient) { }
// #region "REST calls"
// GET
getWorkBasketsSummary(forceRequest: boolean = false,
@ -63,7 +63,8 @@ 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,
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);
}
@ -106,13 +107,12 @@ 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"
selectWorkBasket(id: string) {
this.workBasketSelected.next(id);
@ -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}&` : '';

View File

@ -23,9 +23,7 @@ export class FilterModel {
})
export class FilterComponent {
constructor() {
this.allTypes = IconTypeComponent.allTypes;
}
allTypes: Map<string, string>;
filter: FilterModel = new FilterModel();
@ -35,6 +33,12 @@ export class FilterComponent{
@Output()
performFilter = new EventEmitter<FilterModel>();
toggleDropDown = false;
constructor() {
this.allTypes = IconTypeComponent.allTypes;
}
selectType(type: ICONTYPES) {
this.filter.type = type;
}

View File

@ -12,10 +12,10 @@ export class GeneralMessageModalComponent implements OnChanges {
@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,7 +9,7 @@ import { HttpClientModule } from '@angular/common/http';
import { MasterAndDetailService } from '../../services/master-and-detail.service'
@Component({
selector: 'dummy-master',
selector: 'taskana-dummy-master',
template: 'dummymaster'
})
export class DummyMasterComponent {
@ -17,7 +17,7 @@ export class DummyMasterComponent {
}
@Component({
selector: 'dummy-detail',
selector: 'taskana-dummy-detail',
template: 'dummydetail'
})
export class DummyDetailComponent {
@ -26,10 +26,11 @@ export class DummyDetailComponent {
describe('MasterAndDetailComponent ', () => {
var component, fixture, debugElement, location, router;
let component, fixture, debugElement, location, router;
const routes: Routes = [
{ path: 'workbaskets',
{
path: 'workbaskets',
component: MasterAndDetailComponent,
children: [
{

View File

@ -3,7 +3,7 @@ import { Router, Routes, ActivatedRoute, NavigationStart, RouterEvent } from '
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'],
@ -39,7 +39,7 @@ export class MasterAndDetailComponent implements OnInit{
}
private checkUrl(url: string): Boolean {
for(let routeDetail of this.detailRoutes){
for (const routeDetail of this.detailRoutes) {
if (url.indexOf(routeDetail) !== -1) {
return true;
}

View File

@ -21,14 +21,16 @@ 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() {
}

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;

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,13 +32,17 @@ 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)),
@ -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,8 +24,8 @@ 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;
@ -34,7 +34,8 @@ export class AccessItemsComponent implements OnInit {
constructor(private workbasketService: WorkbasketService, private alertService: AlertService) { }
ngOnInit() {
this.accessItemsubscription = this.workbasketService.getWorkBasketAccessItems(this.workbasket._links.accessItems.href).subscribe( (accessItemsResource: WorkbasketAccessItemsResource) =>{
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);
@ -61,10 +62,12 @@ export class AccessItemsComponent implements OnInit {
onSave(): boolean {
this.requestInProgress = true;
this.workbasketService.updateWorkBasketAccessItem(this.accessItemsResource._links.self.href , this.accessItems).subscribe(response =>{
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.alertService.triggerAlert(new AlertModel(
AlertType.SUCCESS, `Workbasket ${this.workbasket.name} Access items were saved successfully`));
this.requestInProgress = false;
return true;
},
@ -76,17 +79,15 @@ export class AccessItemsComponent implements OnInit {
return false;
}
setValue() { debugger; }
private cloneAccessItems(inputaccessItem): Array<WorkbasketAccessItems> {
let accessItemClone = new Array<WorkbasketAccessItems>();
const accessItemClone = new Array<WorkbasketAccessItems>();
inputaccessItem.forEach(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,7 +100,7 @@ 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();
@ -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);

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,11 +49,15 @@ export class DistributionTargetsComponent implements OnInit {
ngOnInit() {
this.onRequest(undefined);
this.distributionTargetsSubscription = this.workbasketService.getWorkBasketsDistributionTargets(this.workbasket._links.distributionTargets.href).subscribe((distributionTargetsSelectedResource: WorkbasketDistributionTargetsResource) => {
this.distributionTargetsSubscription = this.workbasketService.getWorkBasketsDistributionTargets(
this.workbasket._links.distributionTargets.href).subscribe(
(distributionTargetsSelectedResource: WorkbasketDistributionTargetsResource) => {
this.distributionTargetsSelectedResource = distributionTargetsSelectedResource;
this.distributionTargetsSelected = distributionTargetsSelectedResource._embedded ? distributionTargetsSelectedResource._embedded.distributionTargets : [];
this.distributionTargetsSelected = distributionTargetsSelectedResource._embedded ?
distributionTargetsSelectedResource._embedded.distributionTargets : [];
this.distributionTargetsSelectedClone = Object.assign([], this.distributionTargetsSelected);
this.workbasketSubscription = this.workbasketService.getWorkBasketsSummary().subscribe((distributionTargetsAvailable: WorkbasketSummaryResource) => {
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);
@ -64,12 +68,11 @@ export class DistributionTargetsComponent implements OnInit {
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,12 +81,14 @@ export class DistributionTargetsComponent implements OnInit {
onSave() {
this.requestInProgress = true;
this.workbasketService.updateWorkBasketsDistributionTargets(this.distributionTargetsSelectedResource._links.self.href, this.getSeletedIds()).subscribe(response => {
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`));
this.alertService.triggerAlert(new AlertModel(AlertType.SUCCESS,
`Workbasket ${this.workbasket.name} Access items were saved successfully`));
return true;
},
error => {
@ -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);
@ -81,7 +85,7 @@ describe('InformationComponent', () => {
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();
}));

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;
@ -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,7 +94,8 @@ describe('WorkbasketListComponent', () => {
})
});
it('should have wb-action-toolbar, wb-search-bar, wb-list-container, wb-pagination, collapsedMenufilterWb and taskana-filter created in the html', () => {
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();
@ -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;
});
@ -81,7 +79,8 @@ 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 : [];
@ -97,7 +96,7 @@ export class WorkbasketListComponent implements OnInit {
}
}
private ngOnDestroy() {
ngOnDestroy() {
this.workBasketSummarySubscription.unsubscribe();
this.workbasketServiceSubscription.unsubscribe();
this.workbasketServiceSavedSubscription.unsubscribe();

View File

@ -34,8 +34,10 @@ describe('NoAccessComponent', () => {
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', () => {

View File

@ -3,7 +3,7 @@ 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

@ -19,7 +19,7 @@
"import-spacing": true,
"indent": [
true,
"spaces"
"tab"
],
"interface-over-type-literal": true,
"label-position": true,
@ -91,7 +91,6 @@
"variable-declaration": "nospace"
}
],
"typeof-compare": true,
"unified-signatures": true,
"variable-name": false,
"whitespace": [
@ -105,13 +104,13 @@
"directive-selector": [
true,
"attribute",
"app",
"taskana",
"camelCase"
],
"component-selector": [
true,
"element",
"app",
"taskana",
"kebab-case"
],
"use-input-property-decorator": true,
@ -122,9 +121,6 @@
"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
"directive-class-suffix": true
}
}