diff --git a/admin/src/app/app.module.ts b/admin/src/app/app.module.ts index 85c80c615..fe69bb21d 100644 --- a/admin/src/app/app.module.ts +++ b/admin/src/app/app.module.ts @@ -21,10 +21,10 @@ import { CategorieslistComponent } from './categorieslist/categorieslist.compone import { CategoriestreeComponent } from './categoriestree/categoriestree.component'; import { CategoryeditorComponent } from './categoryeditor/categoryeditor.component'; import { CategoriesadministrationComponent } from './categoriesadministration/categoriesadministration.component'; -import { WorkbasketAuthorizationComponent } from './workbasket-authorization/workbasket-authorization.component'; import { WorkbasketDistributiontargetsComponent } from './workbasket-distributiontargets/workbasket-distributiontargets.component'; import { WorkbasketDetailsComponent } from './workbasket/details/workbasket-details.component'; import { WorkbasketInformationComponent } from './workbasket/details/information/workbasket-information.component'; +import { AuthorizationsComponent } from './workbasket/details/authorizations/authorizations.component'; import { NoAccessComponent } from './workbasket/noAccess/no-access.component'; import { SpinnerComponent } from './shared/spinner/spinner.component'; import { FilterComponent } from './shared/filter/filter.component'; @@ -70,7 +70,7 @@ const DECLARATIONS = [ CategoriestreeComponent, CategoryeditorComponent, CategoriesadministrationComponent, - WorkbasketAuthorizationComponent, + AuthorizationsComponent, WorkbasketDetailsComponent, WorkbasketDistributiontargetsComponent, MasterAndDetailComponent, diff --git a/admin/src/app/model/workbasket-authorization.ts b/admin/src/app/model/workbasket-authorization.ts index cb9e57948..1e9f041a8 100644 --- a/admin/src/app/model/workbasket-authorization.ts +++ b/admin/src/app/model/workbasket-authorization.ts @@ -1,21 +1,27 @@ -export class WorkbasketAuthorization { - id: string; - workbasketId: string; - userId: string; - groupId: string; - read: boolean; - open: boolean; - append: boolean; - transfer: boolean; - distribute: boolean; +import { Links } from "./links"; - constructor(id: string, - workbasketId: string, - userId: string, - groupId: string, - read: boolean, - open: boolean, - append: boolean, - transfer: boolean, - distribute: boolean) { } +export class WorkbasketAuthorization { + constructor( + public accessItemId: string = '', + public workbasketId: string = '', + public accessId: string = '', + public permRead: boolean = false, + public permOpen: boolean = false, + public permAppend: boolean = false, + public permTransfer: boolean = false, + public permDistribute: boolean = false, + public permCustom1: boolean = false, + public permCustom2: boolean = false, + public permCustom3: boolean = false, + public permCustom4: boolean = false, + public permCustom5: boolean = false, + public permCustom6: boolean = false, + public permCustom7: boolean = false, + public permCustom8: boolean = false, + public permCustom9: boolean = false, + public permCustom10: boolean = false, + public permCustom11: boolean = false, + public permCustom12: boolean = false, + public links: Array = undefined + ) { } } \ No newline at end of file diff --git a/admin/src/app/model/workbasket.ts b/admin/src/app/model/workbasket.ts index 58daa5b3e..b272230cb 100644 --- a/admin/src/app/model/workbasket.ts +++ b/admin/src/app/model/workbasket.ts @@ -3,23 +3,23 @@ import { Links } from './links'; export class Workbasket { constructor( public workbasketId: string, - public created: string, - public key: string, - public domain: string, - public type: string, - public modified: string, - public name: string, - public description: string, - public owner: string, - public custom1: string, - public custom2: string, - public custom3: string, - public custom4: string, - public orgLevel1: string, - public orgLevel2: string, - public orgLevel3: string, - public orgLevel4: string, - public links: Array){} + 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: Array = undefined){} public static equals(org: Workbasket, comp: Workbasket): boolean { if (org.workbasketId !== comp.workbasketId) { return false; } diff --git a/admin/src/app/services/workbasket.service.ts b/admin/src/app/services/workbasket.service.ts index 6efb40f2c..83152a099 100644 --- a/admin/src/app/services/workbasket.service.ts +++ b/admin/src/app/services/workbasket.service.ts @@ -95,7 +95,7 @@ export class WorkbasketService { return this.httpClient.delete(environment.taskanaRestUrl + '/v1/workbaskets/' + id, this.httpOptions); } // GET - getAllWorkBasketAuthorizations(id: String): Observable { + getWorkBasketAuthorizations(id: String): Observable { return this.httpClient.get(environment.taskanaRestUrl + '/v1/workbaskets/' + id + '/authorizations', this.httpOptions); } // POST @@ -104,11 +104,11 @@ export class WorkbasketService { } // PUT updateWorkBasketAuthorization(workbasketAuthorization: WorkbasketAuthorization): Observable { - return this.httpClient.put(environment.taskanaRestUrl + '/v1/workbaskets/authorizations/' + workbasketAuthorization.id, workbasketAuthorization, this.httpOptions) + return this.httpClient.put(environment.taskanaRestUrl + '/v1/workbaskets/authorizations/' + workbasketAuthorization.accessId, workbasketAuthorization, this.httpOptions) } // DELETE deleteWorkBasketAuthorization(workbasketAuthorization: WorkbasketAuthorization) { - return this.httpClient.delete(environment.taskanaRestUrl + '/v1/workbaskets/authorizations/' + workbasketAuthorization.id, this.httpOptions); + return this.httpClient.delete(environment.taskanaRestUrl + '/v1/workbaskets/authorizations/' + workbasketAuthorization.accessId, this.httpOptions); } //#endregion diff --git a/admin/src/app/workbasket-authorization/workbasket-authorization.component.css b/admin/src/app/workbasket-authorization/workbasket-authorization.component.css deleted file mode 100644 index e69de29bb..000000000 diff --git a/admin/src/app/workbasket-authorization/workbasket-authorization.component.html b/admin/src/app/workbasket-authorization/workbasket-authorization.component.html deleted file mode 100644 index d051b08a8..000000000 --- a/admin/src/app/workbasket-authorization/workbasket-authorization.component.html +++ /dev/null @@ -1,98 +0,0 @@ - diff --git a/admin/src/app/workbasket-authorization/workbasket-authorization.component.spec.ts b/admin/src/app/workbasket-authorization/workbasket-authorization.component.spec.ts deleted file mode 100644 index 5a0344de0..000000000 --- a/admin/src/app/workbasket-authorization/workbasket-authorization.component.spec.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; - -import { WorkbasketAuthorizationComponent } from './workbasket-authorization.component'; - -describe('WorkbasketAuthorizationComponent', () => { - let component: WorkbasketAuthorizationComponent; - let fixture: ComponentFixture; - - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [ WorkbasketAuthorizationComponent ] - }) - .compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(WorkbasketAuthorizationComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - xit('should be created', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/admin/src/app/workbasket-authorization/workbasket-authorization.component.ts b/admin/src/app/workbasket-authorization/workbasket-authorization.component.ts deleted file mode 100644 index 517ba2478..000000000 --- a/admin/src/app/workbasket-authorization/workbasket-authorization.component.ts +++ /dev/null @@ -1,100 +0,0 @@ -import { Component, OnInit, Input } from '@angular/core'; -import { ActivatedRoute, Params } from '@angular/router'; -import { WorkbasketService } from '../services/workbasket.service'; -import { WorkbasketAuthorization } from '../model/workbasket-authorization'; -import { WorkbasketSummary } from '../model/workbasketSummary'; - -@Component({ - selector: 'app-workbasket-authorization', - templateUrl: './workbasket-authorization.component.html', - styleUrls: ['./workbasket-authorization.component.css'] -}) -export class WorkbasketAuthorizationComponent implements OnInit { - - @Input() - workbasket: WorkbasketSummary; - - // workbasketAuthorization: WorkbasketAuthorization = this.getEmptyObject(); - // selected: WorkbasketAuthorization = this.getEmptyObject(); - // editing: WorkbasketAuthorization = this.getEmptyObject(); - // isEditing: boolean = false; - - // constructor(private service: WorkbasketService, private route: ActivatedRoute) { } - - // workbasketAuthorizations: WorkbasketAuthorization[]; - - ngOnInit() { - // this.route.params.switchMap((params: Params) => this.service.getAllWorkBasketAuthorizations(params['id'])) - // .subscribe(resultList => { - // this.workbasketAuthorizations = resultList; - // }); - } - - // getEmptyObject() { - // return new WorkbasketAuthorization("", "", "", "", false, false, false, false, false); - // } - - // onDelete(workbasket: WorkbasketAuthorization) { - // this.service.deleteWorkBasketAuthorization(workbasket).subscribe(result => { - // var index = this.workbasketAuthorizations.indexOf(workbasket); - // if (index > -1) { - // this.workbasketAuthorizations.splice(index, 1); - // } - // }); - // } - - // onAdd() { - // console.log(this.workbasketAuthorization); - // this.workbasketAuthorization.workbasketId = this.workbasket.id; - // this.service.createWorkBasketAuthorization(this.workbasketAuthorization).subscribe(result => { - // this.workbasketAuthorizations.push(result); - // this.onClear(); - // }); - // } - - // onEdit(workbasketAuthorizations: WorkbasketAuthorization) { - // this.editing = { ...workbasketAuthorizations }; - // this.isEditing = true; - // } - - // onSelect(workbasketAuthorizations: WorkbasketAuthorization) { - // if (!this.isEditing) { - // this.selected = workbasketAuthorizations; - // } - // } - - // onClear() { - // this.workbasketAuthorization.id = ""; - // this.workbasketAuthorization.workbasketId = ""; - // this.workbasketAuthorization.userId = ""; - // this.workbasketAuthorization.groupId = ""; - // this.workbasketAuthorization.read = false; - // this.workbasketAuthorization.open = false; - // this.workbasketAuthorization.append = false; - // this.workbasketAuthorization.transfer = false; - // this.workbasketAuthorization.distribute = false; - // } - - // onSave() { - // if (this.isEditing) { - // this.service.updateWorkBasketAuthorization(this.editing).subscribe(result => { - // this.selected.id = result.id; - // this.selected.workbasketId = result.workbasketId; - // this.selected.userId = result.userId; - // this.selected.groupId = result.groupId; - // this.selected.read = result.read; - // this.selected.open = result.open; - // this.selected.append = result.append; - // this.selected.transfer = result.transfer; - // this.selected.distribute = result.distribute; - // }); - // } - // this.isEditing = false; - // this.editing = this.getEmptyObject(); - // } - - // onCancel() { - // this.editing = this.getEmptyObject(); - // this.isEditing = false; - // } -} diff --git a/admin/src/app/workbasket/details/authorizations/authorizations.component.html b/admin/src/app/workbasket/details/authorizations/authorizations.component.html new file mode 100644 index 000000000..43f8951d8 --- /dev/null +++ b/admin/src/app/workbasket/details/authorizations/authorizations.component.html @@ -0,0 +1,171 @@ + + +
+
+
+ +
+

{{workbasket.name}}

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AccessIDReadOpenAppendTransferDistributeCustom1Custom2Custom3Custom4Custom5Custom6Custom7Custom8Custom9Custom10Custom11Custom12
+ + + + +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
\ No newline at end of file diff --git a/admin/src/app/workbasket/details/authorizations/authorizations.component.scss b/admin/src/app/workbasket/details/authorizations/authorizations.component.scss new file mode 100644 index 000000000..4c264e507 --- /dev/null +++ b/admin/src/app/workbasket/details/authorizations/authorizations.component.scss @@ -0,0 +1,15 @@ +td > input[type="checkbox"] { + margin-top: 0px; +} +.panel-body { + overflow-x: auto; +} +.text-width{ + min-width: 150px; +} + +td { + &.has-changes { + border-bottom: 1px solid #f0ad4e;; + } +} \ No newline at end of file diff --git a/admin/src/app/workbasket/details/authorizations/authorizations.component.spec.ts b/admin/src/app/workbasket/details/authorizations/authorizations.component.spec.ts new file mode 100644 index 000000000..21a03c3ac --- /dev/null +++ b/admin/src/app/workbasket/details/authorizations/authorizations.component.spec.ts @@ -0,0 +1,44 @@ +import { async, ComponentFixture, TestBed, fakeAsync, tick } from '@angular/core/testing'; +import { WorkbasketService } from '../../../services/workbasket.service'; +import { FormsModule } from '@angular/forms'; +import { AngularSvgIconModule } from 'angular-svg-icon'; +import { HttpClientModule } from '@angular/common/http'; +import { HttpModule, JsonpModule } from '@angular/http'; +import { Workbasket } from 'app/model/workbasket'; +import { SpinnerComponent } from '../../../shared/spinner/spinner.component'; +import { AlertService } from '../../../services/alert.service'; +import { GeneralMessageModalComponent } from '../../../shared/general-message-modal/general-message-modal.component'; +import { Links } from '../../../model/links'; +import { Observable } from 'rxjs/Observable'; +import { AuthorizationsComponent } from './authorizations.component'; +import { WorkbasketAuthorization } from '../../../model/workbasket-authorization'; + +describe('AuthorizationsComponent', () => { + let component: AuthorizationsComponent; + let fixture: ComponentFixture; + let workbasketService; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [SpinnerComponent, AuthorizationsComponent, GeneralMessageModalComponent], + imports: [FormsModule, AngularSvgIconModule, HttpClientModule, HttpModule], + providers: [WorkbasketService, AlertService] + + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(AuthorizationsComponent); + component = fixture.componentInstance; + component.workbasket = new Workbasket('1') + workbasketService = TestBed.get(WorkbasketService); + spyOn(workbasketService, 'getWorkBasketAuthorizations').and.returnValue(Observable.of(new Array(new WorkbasketAuthorization()))); + + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/admin/src/app/workbasket/details/authorizations/authorizations.component.ts b/admin/src/app/workbasket/details/authorizations/authorizations.component.ts new file mode 100644 index 000000000..76e9298c7 --- /dev/null +++ b/admin/src/app/workbasket/details/authorizations/authorizations.component.ts @@ -0,0 +1,91 @@ +import { Component, OnInit, Input } from '@angular/core'; +import { Subscription } from 'rxjs'; + +import { Workbasket } from '../../../model/workbasket'; +import { WorkbasketAuthorization } from '../../../model/workbasket-authorization'; + +import { WorkbasketService } from '../../../services/workbasket.service'; + +@Component({ + selector: 'taskana-workbasket-authorizations', + templateUrl: './authorizations.component.html', + styleUrls: ['./authorizations.component.scss'] +}) +export class AuthorizationsComponent implements OnInit { + + @Input() + workbasket: Workbasket; + + authorizations: Array; + authorizationsClone: Array; + authorizationsResetClone: Array; + newAuthorization: WorkbasketAuthorization = new WorkbasketAuthorization(); + authorizationState: Array; + requestInProgress: boolean = false; + modalSpinner: boolean = true; + modalTitle: string; + modalErrorMessage: string; + authorizationSubscription: Subscription; + + constructor(private workbasketService: WorkbasketService) { } + + ngOnInit() { + this.authorizationSubscription = this.workbasketService.getWorkBasketAuthorizations(this.workbasket.workbasketId).subscribe( (authorizations: Array) =>{ + this.authorizations = authorizations; + this.authorizationsClone = this.cloneAuthorizations(this.authorizations); + this.authorizationsResetClone = this.cloneAuthorizations(this.authorizations); + }) + } + + addAuthorization(){ + this.authorizations.push({...this.newAuthorization}); + this.authorizationsClone.push({...this.newAuthorization}); + this.authorizationState.push(false); + this.newAuthorization = new WorkbasketAuthorization(); + } + + authorizationToggle(index: number) { + this.checkAuthorizationState(index); + } + + clear() { + this.authorizations = this.cloneAuthorizations(this.authorizationsResetClone); + this.authorizationsClone = this.cloneAuthorizations(this.authorizationsResetClone); + } + + remove(index: number) { + this.authorizations.splice(index,1); + this.authorizationsClone.splice(index,1); + } + + save(index: number) { + + } + + private resetAuthorizationsState() { + this.authorizationState = new Array(this.authorizations.length); + } + + private checkAuthorizationState(index: number) { + this.authorizationState[index] = false; + Object.keys(this.authorizations[index]).forEach(key =>{ + if(this.authorizations[index][key]!== this.authorizationsClone[index][key]){ + this.authorizationState[index] = true; + return; + } + }); + } + + private cloneAuthorizations(inputAuthorization): Array{ + let authorizationClone = new Array(); + inputAuthorization.forEach(authorization => { + authorizationClone.push({... authorization}); + }); + this.resetAuthorizationsState(); + return authorizationClone; + } + + private ngOnDestroy(): void { + if (this.authorizationSubscription) { this.authorizationSubscription.unsubscribe(); } + } +} diff --git a/admin/src/app/workbasket/details/information/workbasket-information.component.spec.ts b/admin/src/app/workbasket/details/information/workbasket-information.component.spec.ts index 26ae5f17c..7672e31d7 100644 --- a/admin/src/app/workbasket/details/information/workbasket-information.component.spec.ts +++ b/admin/src/app/workbasket/details/information/workbasket-information.component.spec.ts @@ -56,8 +56,8 @@ describe('InformationComponent', () => { })); it('selectType should set workbasket.type to personal with 0 and group in other case', () => { - component.workbasket = new Workbasket(null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null); - expect(component.workbasket.type).toEqual(null); + component.workbasket = new Workbasket('id1'); + expect(component.workbasket.type).toEqual(undefined); component.selectType(ICONTYPES.PERSONAL); expect(component.workbasket.type).toEqual('PERSONAL'); component.selectType(ICONTYPES.GROUP); diff --git a/admin/src/app/workbasket/details/workbasket-details.component.html b/admin/src/app/workbasket/details/workbasket-details.component.html index 9a4fce303..2b36c3a86 100644 --- a/admin/src/app/workbasket/details/workbasket-details.component.html +++ b/admin/src/app/workbasket/details/workbasket-details.component.html @@ -21,10 +21,10 @@
- +
- +
diff --git a/admin/src/app/workbasket/details/workbasket-details.component.scss b/admin/src/app/workbasket/details/workbasket-details.component.scss index f10b5ec33..d8ee75cf4 100644 --- a/admin/src/app/workbasket/details/workbasket-details.component.scss +++ b/admin/src/app/workbasket/details/workbasket-details.component.scss @@ -1,8 +1,11 @@ .nav.nav-tabs { & > li { - & > a{ + & > a { min-height: 56px; padding-top: 17px; + &.has-changes{ + border-bottom: solid #f0ad4e; + } } &:first-child > a{ diff --git a/admin/src/app/workbasket/details/workbasket-details.component.spec.ts b/admin/src/app/workbasket/details/workbasket-details.component.spec.ts index deb391aeb..4f430b41b 100644 --- a/admin/src/app/workbasket/details/workbasket-details.component.spec.ts +++ b/admin/src/app/workbasket/details/workbasket-details.component.spec.ts @@ -2,6 +2,7 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { WorkbasketDetailsComponent } from './workbasket-details.component'; import { NoAccessComponent } from '../noAccess/no-access.component'; import { WorkbasketInformationComponent } from './information/workbasket-information.component'; +import { AuthorizationsComponent } from './authorizations/authorizations.component'; import { Workbasket } from 'app/model/workbasket'; import { Observable } from 'rxjs/Observable'; import { SpinnerComponent } from '../../shared/spinner/spinner.component'; @@ -34,7 +35,7 @@ describe('WorkbasketDetailsComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ imports:[RouterTestingModule, FormsModule, AngularSvgIconModule, HttpClientModule, HttpModule], - declarations: [ WorkbasketDetailsComponent, NoAccessComponent, WorkbasketInformationComponent, SpinnerComponent, IconTypeComponent, MapValuesPipe, RemoveNoneTypePipe, AlertComponent, GeneralMessageModalComponent ], + declarations: [ WorkbasketDetailsComponent, NoAccessComponent, WorkbasketInformationComponent, SpinnerComponent, IconTypeComponent, MapValuesPipe, RemoveNoneTypePipe, AlertComponent, GeneralMessageModalComponent, AuthorizationsComponent ], providers:[WorkbasketService, MasterAndDetailService, PermissionService, AlertService] }) .compileComponents(); @@ -50,7 +51,7 @@ describe('WorkbasketDetailsComponent', () => { spyOn(masterAndDetailService, 'getShowDetail').and.returnValue(Observable.of(true)); spyOn(workbasketService,'getSelectedWorkBasket').and.returnValue(Observable.of('id1')); spyOn(workbasketService,'getWorkBasketsSummary').and.returnValue(Observable.of(new Array(new WorkbasketSummary('id1','','','','','','','','','','','',new Array( new Links('self', 'someurl')))))); - spyOn(workbasketService,'getWorkBasket').and.returnValue(Observable.of(new Workbasket('id1',null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null))); + spyOn(workbasketService,'getWorkBasket').and.returnValue(Observable.of(new Workbasket('id1'))); }); afterEach(() =>{ @@ -70,7 +71,7 @@ describe('WorkbasketDetailsComponent', () => { expect(component.workbasket).toBeUndefined(); expect(debugElement.querySelector('app-no-access')).toBeTruthy; - component.workbasket = new Workbasket(null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null); + component.workbasket = new Workbasket('id1'); fixture.detectChanges(); expect(debugElement.querySelector('app-no-access')).toBeFalsy; @@ -80,7 +81,7 @@ describe('WorkbasketDetailsComponent', () => { it('should show back button with classes "visible-xs visible-sm hidden" when showDetail property is true', () => { - component.workbasket = new Workbasket('id1',null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null); + component.workbasket = new Workbasket('id1'); component.ngOnInit(); fixture.detectChanges(); expect(debugElement.querySelector('.visible-xs.visible-sm.hidden > a').textContent).toBe('Back'); diff --git a/admin/src/app/workbasket/list/workbasket-list.component.html b/admin/src/app/workbasket/list/workbasket-list.component.html index 4f892061b..68cc97aec 100644 --- a/admin/src/app/workbasket/list/workbasket-list.component.html +++ b/admin/src/app/workbasket/list/workbasket-list.component.html @@ -1,6 +1,6 @@