parent
95d614c2d7
commit
ead7b9a3a0
|
@ -1,3 +1,4 @@
|
|||
taskana.roles.user = group1 | group2|teamlead_1 |teamlead_2 |user_1_1| user_1_1| user_1_2| user_2_1| user_2_2| max|elena|simone
|
||||
taskana.roles.Admin=name=konrad,Organisation=novatec|admin
|
||||
taskana.roles.businessadmin=max|Moritz|businessadmin
|
||||
taskana.domains=DOMAIN_A,DOMAIN_B,DOMAIN_C
|
||||
|
|
|
@ -10,6 +10,7 @@ import org.springframework.http.HttpStatus;
|
|||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.transaction.interceptor.TransactionInterceptor;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
|
@ -62,22 +63,33 @@ public class ClassificationDefinitionController {
|
|||
@PostMapping(path = "/import")
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public ResponseEntity<String> importClassifications(
|
||||
@RequestBody List<ClassificationResource> classificationResources) throws NotAuthorizedException,
|
||||
ClassificationNotFoundException, ConcurrencyException, ClassificationAlreadyExistException,
|
||||
DomainNotFoundException {
|
||||
@RequestBody List<ClassificationResource> classificationResources) {
|
||||
Map<String, String> systemIds = classificationService.createClassificationQuery()
|
||||
.list()
|
||||
.stream()
|
||||
.collect(Collectors.toMap(i -> i.getKey() + "|||" + i.getDomain(), ClassificationSummary::getId));
|
||||
|
||||
for (ClassificationResource classificationResource : classificationResources) {
|
||||
Classification classification = classificationMapper.toModel(classificationResource);
|
||||
if (systemIds.containsKey(classificationResource.key + "|||" + classificationResource.domain)) {
|
||||
classificationService.updateClassification(classification);
|
||||
try {
|
||||
for (ClassificationResource classificationResource : classificationResources) {
|
||||
if (systemIds.containsKey(classificationResource.key + "|||" + classificationResource.domain)) {
|
||||
classificationService.updateClassification(classificationMapper.toModel(classificationResource));
|
||||
|
||||
} else {
|
||||
classificationService.createClassification(classification);
|
||||
} else {
|
||||
classificationResource.classificationId = null;
|
||||
classificationService.createClassification(classificationMapper.toModel(classificationResource));
|
||||
}
|
||||
}
|
||||
} catch (NotAuthorizedException e) {
|
||||
TransactionInterceptor.currentTransactionStatus().setRollbackOnly();
|
||||
return new ResponseEntity<>(HttpStatus.UNAUTHORIZED);
|
||||
} catch (ClassificationNotFoundException | DomainNotFoundException e) {
|
||||
TransactionInterceptor.currentTransactionStatus().setRollbackOnly();
|
||||
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
|
||||
} catch (ClassificationAlreadyExistException e) {
|
||||
TransactionInterceptor.currentTransactionStatus().setRollbackOnly();
|
||||
return new ResponseEntity<>(HttpStatus.CONFLICT);
|
||||
//TODO why is this occuring???
|
||||
} catch (ConcurrencyException e) {
|
||||
}
|
||||
|
||||
return new ResponseEntity<>(HttpStatus.OK);
|
||||
|
|
|
@ -20,6 +20,7 @@ import org.springframework.web.bind.annotation.RequestParam;
|
|||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import pro.taskana.Workbasket;
|
||||
import pro.taskana.WorkbasketAccessItem;
|
||||
import pro.taskana.WorkbasketQuery;
|
||||
import pro.taskana.WorkbasketService;
|
||||
import pro.taskana.WorkbasketSummary;
|
||||
|
@ -83,10 +84,9 @@ public class WorkbasketDefinitionController {
|
|||
* we want to have an option to import all settings at once. When a logical equal (key and domain are equal)
|
||||
* workbasket already exists an update will be executed. Otherwise a new workbasket will be created.
|
||||
*
|
||||
* @param definitions
|
||||
* the list of workbasket definitions which will be imported to the current system.
|
||||
* @param definitions the list of workbasket definitions which will be imported to the current system.
|
||||
* @return Return answer is determined by the status code: 200 - all good 400 - list state error (referring to non
|
||||
* existing id's) 401 - not authorized
|
||||
* existing id's) 401 - not authorized
|
||||
*/
|
||||
@PostMapping(path = "/import")
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
|
@ -107,16 +107,23 @@ public class WorkbasketDefinitionController {
|
|||
for (WorkbasketDefinition definition : definitions) {
|
||||
WorkbasketResource res = definition.workbasketResource;
|
||||
Workbasket workbasket;
|
||||
String oldId = res.workbasketId;
|
||||
if (systemIds.containsKey(logicalId(res))) {
|
||||
String oldId = res.workbasketId;
|
||||
res.workbasketId = systemIds.get(logicalId(res));
|
||||
workbasket = workbasketService.updateWorkbasket(
|
||||
workbasketMapper.toModel(res));
|
||||
res.workbasketId = oldId;
|
||||
} else {
|
||||
res.workbasketId = null;
|
||||
workbasket = workbasketService.createWorkbasket(
|
||||
workbasketMapper.toModel(res));
|
||||
}
|
||||
res.workbasketId = oldId;
|
||||
|
||||
// Since we would have a n² runtime when doing a lookup and updating the access items we decided to
|
||||
// simply delete all existing accessItems and create new ones.
|
||||
for (WorkbasketAccessItem accessItem : workbasketService.getWorkbasketAccessItems(workbasket.getId())) {
|
||||
workbasketService.deleteWorkbasketAccessItem(accessItem.getId());
|
||||
}
|
||||
for (WorkbasketAccessItemResource authorization : definition.authorizations) {
|
||||
workbasketService.createWorkbasketAccessItem(
|
||||
workbasketAccessItemMapper.toModel(authorization));
|
||||
|
@ -132,8 +139,7 @@ public class WorkbasketDefinitionController {
|
|||
if (idConversion.containsKey(oldId)) {
|
||||
distributionTargets.add(idConversion.get(oldId));
|
||||
} else {
|
||||
throw new WorkbasketNotFoundException(
|
||||
oldId,
|
||||
throw new InvalidWorkbasketException(
|
||||
String.format(
|
||||
"invalid import state: Workbasket '%s' does not exist in the given import list",
|
||||
oldId));
|
||||
|
|
|
@ -3557,6 +3557,11 @@
|
|||
"schema-utils": "0.4.5"
|
||||
}
|
||||
},
|
||||
"file-saver": {
|
||||
"version": "1.3.3",
|
||||
"resolved": "https://registry.npmjs.org/file-saver/-/file-saver-1.3.3.tgz",
|
||||
"integrity": "sha1-zdTETTqiZOrC9o7BZbx5HDSvEjI="
|
||||
},
|
||||
"file-uri-to-path": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
|
||||
|
@ -4192,7 +4197,8 @@
|
|||
"jsbn": {
|
||||
"version": "0.1.1",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"json-schema": {
|
||||
"version": "0.2.3",
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
"@angular/platform-browser": "5.2.1",
|
||||
"@angular/platform-browser-dynamic": "5.2.1",
|
||||
"@angular/router": "5.2.1",
|
||||
"file-saver": "1.3.3",
|
||||
"angular-svg-icon": "5.0.0",
|
||||
"angular-tree-component": "7.0.1",
|
||||
"bootstrap": "3.3.7",
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
<div class="classification-list-full-height">
|
||||
<ul id="cl-list-container" class="list-group footer-space">
|
||||
<li id="cl-action-toolbar" class="list-group-item tab-align">
|
||||
<div class="row">
|
||||
<div class="col-xs-9">
|
||||
<taskana-import-export-component [currentSelection]="'classifications'"></taskana-import-export-component>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<taskana-spinner [isRunning]="requestInProgress" class="centered-horizontally"></taskana-spinner>
|
||||
|
||||
</ul>
|
||||
<ul id="wb-pagination" class="pagination vertical-center">
|
||||
<li>
|
||||
<a href="#" aria-label="Previous">
|
||||
<span aria-hidden="true">«</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="">1</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="">2</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="">3</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="">4</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="">5</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#" aria-label="Next">
|
||||
<span aria-hidden="true">»</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
|
@ -0,0 +1,22 @@
|
|||
.classification-list-full-height {
|
||||
height: calc(100vh - 55px);
|
||||
}
|
||||
|
||||
.row.list-group {
|
||||
margin-left: 2px;
|
||||
}
|
||||
|
||||
.list-group > li {
|
||||
border-left: none;
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
a > label {
|
||||
height: 2em;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.tab-align {
|
||||
border-bottom: 1px solid #ddd;
|
||||
padding-bottom: 12px;
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { ClassificationListComponent } from './classification-list.component';
|
||||
import {ImportExportComponent} from '../../../import-export/import-export.component';
|
||||
import {SpinnerComponent} from '../../../../shared/spinner/spinner.component';
|
||||
import {WorkbasketService} from '../../../../services/workbasket/workbasket.service';
|
||||
import {HttpClient, HttpClientModule} from '@angular/common/http';
|
||||
import {WorkbasketDefinitionService} from '../../../../services/workbasket/workbasketDefinition.service';
|
||||
import {AlertService} from '../../../../services/alert/alert.service';
|
||||
import {ClassificationService} from '../../../../services/classification/classification.service';
|
||||
|
||||
describe('ClassificationListComponent', () => {
|
||||
let component: ClassificationListComponent;
|
||||
let fixture: ComponentFixture<ClassificationListComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ ClassificationListComponent, ImportExportComponent, SpinnerComponent],
|
||||
imports: [HttpClientModule],
|
||||
providers: [WorkbasketService, HttpClient, WorkbasketDefinitionService, AlertService, ClassificationService]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(ClassificationListComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,17 @@
|
|||
import {Component, OnInit} from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'taskana-classification-list',
|
||||
templateUrl: './classification-list.component.html',
|
||||
styleUrls: ['./classification-list.component.scss']
|
||||
})
|
||||
export class ClassificationListComponent implements OnInit {
|
||||
|
||||
requestInProgress = false;
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
<input #selectedFile type="file" (change)="onSelectFile($event)"
|
||||
style="position:absolute;display:none;"/>
|
||||
<button class="btn btn-default glyphicon glyphicon-upload" type="button" title="Import" style="top: -0.5px;"
|
||||
(click)="selectedFile.click()"></button>
|
||||
|
||||
<div class="dropdown" style="display: inline">
|
||||
<button type="button" title="Export" class="btn btn-default dropdown-toggle"
|
||||
data-toggle="dropdown" aria-haspopup="true" aria-expanded="true"
|
||||
(click)="updateDomains()">
|
||||
<span class="glyphicon glyphicon-download"></span>
|
||||
</button>
|
||||
|
||||
<ul class="dropdown-menu">
|
||||
<li>
|
||||
<a class="dropdown-item" (click)="exportAll()"><label>All Domains</label></a>
|
||||
</li>
|
||||
<div role="separator" class="divider"></div>
|
||||
<li *ngFor="let domain of (this.currentSelection === 'workbaskets' ? workbasketDomains : classificationDomains)">
|
||||
<a class="dropdown-item"
|
||||
(click)="exportByDomain(domain)"><label>{{domain === '' ? 'Master' : domain}}</label></a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
|
@ -0,0 +1,32 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { ImportExportComponent } from './import-export.component';
|
||||
import {WorkbasketService} from '../../services/workbasket/workbasket.service';
|
||||
import {ClassificationService} from '../../services/classification/classification.service';
|
||||
import {WorkbasketDefinitionService} from '../../services/workbasket/workbasketDefinition.service';
|
||||
import {AlertService} from '../../services/alert/alert.service';
|
||||
import {HttpClient, HttpClientModule} from '@angular/common/http';
|
||||
|
||||
describe('ImportExportComponent', () => {
|
||||
let component: ImportExportComponent;
|
||||
let fixture: ComponentFixture<ImportExportComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ ImportExportComponent],
|
||||
imports: [HttpClientModule],
|
||||
providers: [WorkbasketService, ClassificationService, WorkbasketDefinitionService, AlertService]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(ImportExportComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,61 @@
|
|||
import {Component, Input, OnInit} from '@angular/core';
|
||||
import {HttpClient} from '@angular/common/http';
|
||||
import {ActivatedRoute, Router} from '@angular/router';
|
||||
import {WorkbasketService} from '../../services/workbasket/workbasket.service';
|
||||
import {ClassificationService} from '../../services/classification/classification.service';
|
||||
import {WorkbasketDefinitionService} from '../../services/workbasket/workbasketDefinition.service';
|
||||
|
||||
@Component({
|
||||
selector: 'taskana-import-export-component',
|
||||
templateUrl: './import-export.component.html',
|
||||
styleUrls: ['./import-export.component.scss']
|
||||
})
|
||||
export class ImportExportComponent implements OnInit {
|
||||
|
||||
@Input() currentSelection: string;
|
||||
workbasketDomains: string[];
|
||||
classificationDomains: string[];
|
||||
|
||||
constructor(private workbasketService: WorkbasketService, private workbasketDefinitionService: WorkbasketDefinitionService,
|
||||
private classificationService: ClassificationService) {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
|
||||
updateDomains() {
|
||||
this.workbasketService.getWorkbasketDomains().subscribe(
|
||||
data => this.workbasketDomains = data
|
||||
);
|
||||
this.classificationService.getClassificationDomains().subscribe(
|
||||
data => this.classificationDomains = data
|
||||
);
|
||||
}
|
||||
|
||||
onSelectFile(event) {
|
||||
const file = event.srcElement.files[0];
|
||||
const reader = new FileReader();
|
||||
if (this.currentSelection === 'workbaskets') {
|
||||
reader.onload = <Event>(e) => this.workbasketDefinitionService.importWorkbasketDefinitions(e.target.result);
|
||||
} else {
|
||||
reader.onload = <Event>(e) => this.classificationService.importClassifications(e.target.result);
|
||||
}
|
||||
reader.readAsText(file);
|
||||
}
|
||||
|
||||
exportAll() {
|
||||
if (this.currentSelection === 'workbaskets') {
|
||||
this.workbasketDefinitionService.exportAllWorkbaskets();
|
||||
} else {
|
||||
this.classificationService.exportAllClassifications();
|
||||
}
|
||||
}
|
||||
|
||||
exportByDomain(domain: string) {
|
||||
if (this.currentSelection === 'workbaskets') {
|
||||
this.workbasketDefinitionService.exportWorkbasketsByDomain(domain);
|
||||
} else {
|
||||
this.classificationService.exportClassificationsByDomain(domain);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -22,6 +22,20 @@ import { RemoveNoneTypePipe } from 'app/pipes/removeNoneType/remove-none-type.pi
|
|||
import { ErrorModalService } from 'app/services/errorModal/error-modal.service';
|
||||
import { SavingWorkbasketService, SavingInformation } from 'app/services/saving-workbaskets/saving-workbaskets.service';
|
||||
import { AlertService } from 'app/services/alert/alert.service';
|
||||
import {Component} from '@angular/core';
|
||||
import {Routes} from '@angular/router';
|
||||
|
||||
@Component({
|
||||
selector: 'taskana-dummy-detail',
|
||||
template: 'dummydetail'
|
||||
})
|
||||
export class DummyDetailComponent {
|
||||
}
|
||||
|
||||
const routes: Routes = [
|
||||
{ path: ':id', component: DummyDetailComponent, outlet: 'detail' },
|
||||
{ path: 'someNewId', component: DummyDetailComponent }
|
||||
];
|
||||
|
||||
describe('InformationComponent', () => {
|
||||
let component: WorkbasketInformationComponent;
|
||||
|
@ -31,8 +45,8 @@ describe('InformationComponent', () => {
|
|||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [WorkbasketInformationComponent, IconTypeComponent, MapValuesPipe,
|
||||
RemoveNoneTypePipe, SpinnerComponent, GeneralMessageModalComponent],
|
||||
imports: [FormsModule, AngularSvgIconModule, HttpClientModule, HttpModule, RouterTestingModule],
|
||||
RemoveNoneTypePipe, SpinnerComponent, GeneralMessageModalComponent, DummyDetailComponent],
|
||||
imports: [FormsModule, AngularSvgIconModule, HttpClientModule, HttpModule, RouterTestingModule.withRoutes(routes)],
|
||||
providers: [WorkbasketService, AlertService, SavingWorkbasketService, ErrorModalService]
|
||||
|
||||
})
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<li id="wb-action-toolbar" class="list-group-item tab-align">
|
||||
<div class="row">
|
||||
<div class="col-xs-9">
|
||||
<taskana-import-export-component [currentSelection]="'workbaskets'"></taskana-import-export-component>
|
||||
<button type="button" (click)="addWorkbasket()" data-toggle="tooltip" title="Add" class="btn btn-default">
|
||||
<span class="glyphicon glyphicon-plus green" aria-hidden="true"></span>
|
||||
</button>
|
||||
|
@ -30,4 +31,4 @@
|
|||
<div class="row">
|
||||
<taskana-filter target="wb-filter-bar" (performFilter)="filtering($event)"></taskana-filter>
|
||||
</div>
|
||||
</li>
|
||||
</li>
|
||||
|
|
|
@ -25,6 +25,9 @@ import { ErrorModalService } from 'app/services/errorModal/error-modal.service';
|
|||
import { WorkbasketService } from 'app/services/workbasket/workbasket.service';
|
||||
import { RequestInProgressService } from 'app/services/requestInProgress/request-in-progress.service';
|
||||
import { AlertService } from 'app/services/alert/alert.service';
|
||||
import {ImportExportComponent} from '../../../../import-export/import-export.component';
|
||||
import {ClassificationService} from '../../../../../services/classification/classification.service';
|
||||
import {WorkbasketDefinitionService} from '../../../../../services/workbasket/workbasketDefinition.service';
|
||||
|
||||
@Component({
|
||||
selector: 'taskana-dummy-detail',
|
||||
|
@ -48,8 +51,9 @@ describe('WorkbasketListToolbarComponent', () => {
|
|||
imports: [FormsModule, ReactiveFormsModule, AngularSvgIconModule, HttpModule,
|
||||
HttpClientModule, RouterTestingModule.withRoutes(routes)],
|
||||
declarations: [WorkbasketListToolbarComponent, SortComponent,
|
||||
FilterComponent, IconTypeComponent, DummyDetailComponent, MapValuesPipe],
|
||||
providers: [ErrorModalService, WorkbasketService, RequestInProgressService, AlertService]
|
||||
FilterComponent, IconTypeComponent, DummyDetailComponent, MapValuesPipe, ImportExportComponent],
|
||||
providers: [ErrorModalService, WorkbasketService, RequestInProgressService, AlertService,
|
||||
ClassificationService, WorkbasketDefinitionService]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
|
|
@ -27,6 +27,9 @@ import { SortComponent } from 'app/shared/sort/sort.component';
|
|||
|
||||
import { RemoveNoneTypePipe } from 'app/pipes/removeNoneType/remove-none-type.pipe';
|
||||
import { MapValuesPipe } from 'app/pipes/mapValues/map-values.pipe';
|
||||
import {ClassificationService} from '../../../../services/classification/classification.service';
|
||||
import {WorkbasketDefinitionService} from '../../../../services/workbasket/workbasketDefinition.service';
|
||||
import {ImportExportComponent} from '../../../import-export/import-export.component';
|
||||
|
||||
|
||||
@Component({
|
||||
|
@ -66,14 +69,15 @@ describe('WorkbasketListComponent', () => {
|
|||
TestBed.configureTestingModule({
|
||||
|
||||
declarations: [WorkbasketListComponent, DummyDetailComponent, SpinnerComponent, FilterComponent, WorkbasketListToolbarComponent,
|
||||
RemoveNoneTypePipe, IconTypeComponent, SortComponent, MapValuesPipe],
|
||||
RemoveNoneTypePipe, IconTypeComponent, SortComponent, MapValuesPipe, ImportExportComponent],
|
||||
imports: [
|
||||
AngularSvgIconModule,
|
||||
HttpModule,
|
||||
HttpClientModule,
|
||||
RouterTestingModule.withRoutes(routes)
|
||||
],
|
||||
providers: [WorkbasketService, ErrorModalService, RequestInProgressService, AlertService]
|
||||
providers: [WorkbasketService, ErrorModalService, RequestInProgressService, AlertService,
|
||||
ClassificationService, WorkbasketDefinitionService]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ import { WorkbasketListComponent } from './administration/workbasket/master/list
|
|||
import { WorkbasketDetailsComponent } from './administration/workbasket/details/workbasket-details.component';
|
||||
import { MasterAndDetailComponent } from './shared/masterAndDetail/master-and-detail.component';
|
||||
import { NoAccessComponent } from './administration/workbasket/details/noAccess/no-access.component';
|
||||
import {ClassificationListComponent} from './administration/classification/master/list/classification-list.component';
|
||||
|
||||
const appRoutes: Routes = [
|
||||
{
|
||||
|
@ -29,15 +30,15 @@ const appRoutes: Routes = [
|
|||
]
|
||||
},
|
||||
{
|
||||
path: 'clasifications',
|
||||
component: MasterAndDetailComponent,
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
component: WorkbasketListComponent,
|
||||
outlet: 'detail'
|
||||
}
|
||||
]
|
||||
path: 'classifications',
|
||||
component: MasterAndDetailComponent,
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
component: ClassificationListComponent,
|
||||
outlet: 'master'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '',
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<a routerLink="/workbaskets" aria-controls="Work baskets" routerLinkActive="active">Workbaskets</a>
|
||||
</li>
|
||||
<li role="presentation" class="{{workbasketsRoute? 'inactive' : 'active'}}" role="tab" data-toggle="tab">
|
||||
<a routerLink="/clasifications" aria-controls="Clasifications" routerLinkActive="active">Clasifications</a>
|
||||
<a routerLink="/classifications" aria-controls="Classifications" routerLinkActive="active">Classifications</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
@ -48,4 +48,4 @@
|
|||
<taskana-spinner [isRunning]="requestInProgress" isModal="true"></taskana-spinner>
|
||||
<taskana-alert></taskana-alert>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -56,6 +56,10 @@ import { SavingWorkbasketService } from './services/saving-workbaskets/saving-wo
|
|||
import { MapValuesPipe } from './pipes/mapValues/map-values.pipe';
|
||||
import { RemoveNoneTypePipe } from './pipes/removeNoneType/remove-none-type.pipe';
|
||||
import { SelectWorkBasketPipe } from './pipes/selectedWorkbasket/seleted-workbasket.pipe';
|
||||
import {ClassificationListComponent} from './administration/classification/master/list/classification-list.component';
|
||||
import {ClassificationService} from './services/classification/classification.service';
|
||||
import {WorkbasketDefinitionService} from './services/workbasket/workbasketDefinition.service';
|
||||
import {ImportExportComponent} from './administration/import-export/import-export.component';
|
||||
|
||||
const MODULES = [
|
||||
BrowserModule,
|
||||
|
@ -89,7 +93,9 @@ const DECLARATIONS = [
|
|||
DualListComponent,
|
||||
MapValuesPipe,
|
||||
RemoveNoneTypePipe,
|
||||
SelectWorkBasketPipe
|
||||
SelectWorkBasketPipe,
|
||||
ClassificationListComponent,
|
||||
ImportExportComponent
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
|
@ -99,6 +105,8 @@ const DECLARATIONS = [
|
|||
WorkbasketService,
|
||||
MasterAndDetailService,
|
||||
PermissionService,
|
||||
ClassificationService,
|
||||
WorkbasketDefinitionService,
|
||||
{
|
||||
provide: HTTP_INTERCEPTORS,
|
||||
useClass: HttpClientInterceptor,
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
export class Classification {
|
||||
constructor(public classificationId: string,
|
||||
public key: string,
|
||||
public parentId: string,
|
||||
public category: string,
|
||||
public domain: string,
|
||||
public isValidInDomain: boolean,
|
||||
public created: string,
|
||||
public modifies: string,
|
||||
public name: string,
|
||||
public description: string,
|
||||
public priority: number,
|
||||
public serviceLevel: string,
|
||||
public applicationEntryPoint: string,
|
||||
public custom1: string,
|
||||
public custom2: string,
|
||||
public custom3: string,
|
||||
public custom4: string,
|
||||
public custom5: string,
|
||||
public custom6: string,
|
||||
public custom7: string,
|
||||
public custom8: string) {
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
import {WorkbasketAccessItems} from './workbasket-access-items';
|
||||
import {Workbasket} from './workbasket';
|
||||
|
||||
export class WorkbasketDefinition {
|
||||
constructor(distributionTargets: string[],
|
||||
workbasketAccessItems: WorkbasketAccessItems[],
|
||||
workbasket: Workbasket) {
|
||||
}
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
import {Injectable} from '@angular/core';
|
||||
import {HttpClient, HttpHeaders} from '@angular/common/http';
|
||||
import {Observable} from 'rxjs/Observable';
|
||||
import {environment} from '../../../environments/environment';
|
||||
import {DatePipe} from '@angular/common';
|
||||
import {AlertService} from '../alert/alert.service';
|
||||
import {Classification} from '../../models/classification';
|
||||
import {AlertModel, AlertType} from '../../models/alert';
|
||||
import {saveAs} from 'file-saver/FileSaver';
|
||||
|
||||
@Injectable()
|
||||
export class ClassificationService {
|
||||
|
||||
httpOptions = {
|
||||
headers: new HttpHeaders({
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': 'Basic VEVBTUxFQURfMTpURUFNTEVBRF8x'
|
||||
})
|
||||
};
|
||||
|
||||
constructor(private httpClient: HttpClient, private alertService: AlertService) {
|
||||
}
|
||||
|
||||
// GET
|
||||
getClassificationDomains(): Observable<string[]> {
|
||||
return this.httpClient.get<string[]>(environment.taskanaRestUrl + '/v1/classifications/domains', this.httpOptions);
|
||||
}
|
||||
|
||||
// GET
|
||||
exportAllClassifications() {
|
||||
this.httpClient.get<Classification[]>(environment.taskanaRestUrl + '/v1/classificationdefinitions', this.httpOptions)
|
||||
.subscribe(
|
||||
response => saveAs(new Blob([JSON.stringify(response)], {type: 'text/plain;charset=utf-8'}), this.generateName())
|
||||
);
|
||||
}
|
||||
|
||||
// GET
|
||||
exportClassificationsByDomain(domain: string) {
|
||||
this.httpClient.get<Classification[]>(environment.taskanaRestUrl + '/v1/classificationdefinitions?domain=' + domain, this.httpOptions)
|
||||
.subscribe(
|
||||
response => saveAs(new Blob([JSON.stringify(response)], {type: 'text/plain;charset=utf-8'}), this.generateName(domain))
|
||||
);
|
||||
}
|
||||
|
||||
// POST
|
||||
// TODO handle error
|
||||
importClassifications(classifications: any) {
|
||||
console.log('importing classifications');
|
||||
this.httpClient.post(environment.taskanaRestUrl + '/v1/classificationdefinitions/import',
|
||||
JSON.parse(classifications), this.httpOptions).subscribe(
|
||||
classificationsUpdated => this.alertService.triggerAlert(new AlertModel(AlertType.SUCCESS, 'Import was successful')),
|
||||
error => this.alertService.triggerAlert(new AlertModel(AlertType.DANGER, 'Import was not successful'))
|
||||
);
|
||||
}
|
||||
|
||||
private generateName(domain = ''): string {
|
||||
const dateFormat = 'yyyy-MM-ddTHH:mm:ss';
|
||||
const dateLocale = 'en-US';
|
||||
const datePipe = new DatePipe(dateLocale);
|
||||
const date = datePipe.transform(Date.now(), dateFormat) + 'Z';
|
||||
return 'Classifications_' + date + '.json';
|
||||
}
|
||||
}
|
|
@ -113,6 +113,11 @@ export class WorkbasketService {
|
|||
return this.httpClient.put<WorkbasketDistributionTargetsResource>(url, distributionTargetsIds, this.httpOptions);
|
||||
}
|
||||
|
||||
// GET
|
||||
getWorkbasketDomains() {
|
||||
return this.httpClient.get<string[]>(environment.taskanaRestUrl + '/v1/workbaskets/domains', this.httpOptions);
|
||||
}
|
||||
|
||||
// #endregion
|
||||
// #region "Service extras"
|
||||
selectWorkBasket(id: string) {
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
import {Injectable} from '@angular/core';
|
||||
import {HttpClient, HttpHeaders} from '@angular/common/http';
|
||||
import {environment} from '../../../environments/environment';
|
||||
import {saveAs} from 'file-saver/FileSaver';
|
||||
import {DatePipe} from '@angular/common';
|
||||
import {AlertService} from '../alert/alert.service';
|
||||
import {WorkbasketDefinition} from '../../models/workbasket-definition';
|
||||
import {AlertModel, AlertType} from '../../models/alert';
|
||||
|
||||
|
||||
@Injectable()
|
||||
export class WorkbasketDefinitionService {
|
||||
url: string = environment.taskanaRestUrl + '/v1/workbasketdefinitions';
|
||||
|
||||
httpOptions = {
|
||||
headers: new HttpHeaders({
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': 'Basic VEVBTUxFQURfMTpURUFNTEVBRF8x'
|
||||
})
|
||||
};
|
||||
|
||||
|
||||
constructor(private httpClient: HttpClient, private alertService: AlertService) {
|
||||
}
|
||||
|
||||
// GET
|
||||
exportAllWorkbaskets() {
|
||||
this.httpClient.get<WorkbasketDefinition[]>(this.url, this.httpOptions).subscribe(
|
||||
response => saveAs(new Blob([JSON.stringify(response)], {type: 'text/plain;charset=utf-8'}), this.generateName())
|
||||
);
|
||||
}
|
||||
|
||||
// GET
|
||||
exportWorkbasketsByDomain(domain: string) {
|
||||
this.httpClient.get<WorkbasketDefinition[]>(this.url + '?' + 'domain=' + domain, this.httpOptions).subscribe(
|
||||
response => {
|
||||
saveAs(new Blob([JSON.stringify(response)], {type: 'text/plain;charset=utf-8'}), this.generateName(domain));
|
||||
console.log(response);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// POST
|
||||
// TODO handle error
|
||||
importWorkbasketDefinitions(workbasketDefinitions: any) {
|
||||
console.log('importing workbaskets');
|
||||
this.httpClient.post(environment.taskanaRestUrl + '/v1/workbasketdefinitions/import',
|
||||
JSON.parse(workbasketDefinitions), this.httpOptions).subscribe(
|
||||
workbasketsUpdated => this.alertService.triggerAlert(new AlertModel(AlertType.SUCCESS, 'Import was successful')),
|
||||
error => this.alertService.triggerAlert(new AlertModel(AlertType.DANGER, 'Import was not successful'))
|
||||
);
|
||||
}
|
||||
|
||||
private generateName(domain = ''): string {
|
||||
const dateFormat = 'yyyy-MM-ddTHH:mm:ss';
|
||||
const dateLocale = 'en-US';
|
||||
const datePipe = new DatePipe(dateLocale);
|
||||
const date = datePipe.transform(Date.now(), dateFormat) + 'Z';
|
||||
return 'Workbaskets_' + date + '.json';
|
||||
}
|
||||
|
||||
}
|
|
@ -9,7 +9,7 @@ import { MasterAndDetailService } from 'app/services/masterAndDetail/master-and-
|
|||
|
||||
})
|
||||
export class MasterAndDetailComponent implements OnInit {
|
||||
private detailRoutes: Array<string> = ['/workbaskets/(detail', 'clasifications'];
|
||||
private detailRoutes: Array<string> = ['/workbaskets/(detail', 'classifications'];
|
||||
private sub: any;
|
||||
|
||||
showDetail: Boolean = false;
|
||||
|
|
Loading…
Reference in New Issue