TSK-747 add new history screen

This commit is contained in:
Martin Rojas Miguel Angel 2018-12-04 12:01:23 +01:00 committed by Holger Hagen
parent ebc2a5327f
commit 3819b4c5b2
89 changed files with 4781 additions and 6675 deletions

View File

@ -35,42 +35,6 @@
<spring.ldap.version>2.3.2.RELEASE</spring.ldap.version> <spring.ldap.version>2.3.2.RELEASE</spring.ldap.version>
</properties> </properties>
<profiles>
<profile>
<id>history.plugin</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<properties>
<build.profile.id>history.plugin</build.profile.id>
</properties>
<dependencies>
<dependency>
<groupId>pro.taskana.simplehistory</groupId>
<artifactId>taskana-simplehistory-provider</artifactId>
<version>0.0.6</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.0</version>
<configuration>
<includes>
<include>**/*Plugin*Test.java</include>
</includes>
<excludes>
<exclude>**/Test/*.java</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>pro.taskana</groupId> <groupId>pro.taskana</groupId>
@ -82,6 +46,11 @@
<artifactId>taskana-history-rest-spring</artifactId> <artifactId>taskana-history-rest-spring</artifactId>
<version>${project.version}</version> <version>${project.version}</version>
</dependency> </dependency>
<dependency>
<groupId>pro.taskana.simplehistory</groupId>
<artifactId>taskana-simplehistory-provider</artifactId>
<version>0.0.6</version>
</dependency>
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId> <artifactId>spring-boot-starter-web</artifactId>

View File

@ -732,6 +732,20 @@ include::../../../{snippets}/GetCurrentUserInfoDocTest/http-response.adoc[]
include::../../../{snippets}/GetCurrentUserInfoDocTest/response-fields.adoc[] include::../../../{snippets}/GetCurrentUserInfoDocTest/response-fields.adoc[]
=== History-Provider-Is-Enabled
This resource returns if history provider is enabled.
include::../../../{snippets}/GetHistoryProviderIsEnabled/http-request.adoc[]
==== Example Response
include::../../../{snippets}/GetHistoryProviderIsEnabled/http-response.adoc[]
==== Response Structure
include::../../../{snippets}/GetHistoryProviderIsEnabled/response-fields.adoc[]
[[resource-subsets]] [[resource-subsets]]
== Resource-Subsets == Resource-Subsets

View File

@ -129,4 +129,14 @@ public class TaskanaEngineControllerRestDocumentation {
.andDo(MockMvcRestDocumentation.document("GetCurrentUserInfoDocTest", .andDo(MockMvcRestDocumentation.document("GetCurrentUserInfoDocTest",
responseFields(currentUserInfoFieldDescriptors))); responseFields(currentUserInfoFieldDescriptors)));
} }
@Test
public void getHistoryProviderIsEnabled() throws Exception {
this.mockMvc.perform(RestDocumentationRequestBuilders
.get("http://127.0.0.1:" + port + "/v1/history-provider-enabled")
.accept("application/json")
.header("Authorization", "Basic dGVhbWxlYWRfMTp0ZWFtbGVhZF8x"))
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(MockMvcRestDocumentation.document("GetHistoryProviderIsEnabled"));
}
} }

View File

@ -1,5 +1,3 @@
SET SCHEMA TASKANA;
INSERT INTO HISTORY_EVENTS (BUSINESS_PROCESS_ID, PARENT_BUSINESS_PROCESS_ID, TASK_ID, EVENT_TYPE, CREATED, USER_ID, DOMAIN, WORKBASKET_KEY, POR_COMPANY, POR_SYSTEM, POR_INSTANCE, POR_TYPE, POR_VALUE, TASK_CLASSIFICATION_KEY, TASK_CLASSIFICATION_CATEGORY, ATTACHMENT_CLASSIFICATION_KEY, COMMENT, OLD_VALUE, NEW_VALUE, CUSTOM_1, CUSTOM_2, CUSTOM_3, CUSTOM_4, OLD_DATA, NEW_DATA) VALUES INSERT INTO HISTORY_EVENTS (BUSINESS_PROCESS_ID, PARENT_BUSINESS_PROCESS_ID, TASK_ID, EVENT_TYPE, CREATED, USER_ID, DOMAIN, WORKBASKET_KEY, POR_COMPANY, POR_SYSTEM, POR_INSTANCE, POR_TYPE, POR_VALUE, TASK_CLASSIFICATION_KEY, TASK_CLASSIFICATION_CATEGORY, ATTACHMENT_CLASSIFICATION_KEY, COMMENT, OLD_VALUE, NEW_VALUE, CUSTOM_1, CUSTOM_2, CUSTOM_3, CUSTOM_4, OLD_DATA, NEW_DATA) VALUES
-- BUSINESS_PROCESS_ID, PARENT_BUSINESS_PROCESS_ID, TASK_ID, EVENT_TYPE, CREATED, USER_ID, DOMAIN, WORKBASKET_KEY, POR_COMPANY , POR_SYSTEM, POR_INSTANCE , POR_TYPE , POR_VALUE , TASK_CLASSIFICATION_KEY, TASK_CLASSIFICATION_CATEGORY , ATTACHMENT_CLASSIFICATION_KEY , COMMENT , OLD_VALUE , NEW_VALUE , CUSTOM_1 , CUSTOM_2 , CUSTOM_3 , CUSTOM_4 , OLD_DATA , NEW_DATA -- BUSINESS_PROCESS_ID, PARENT_BUSINESS_PROCESS_ID, TASK_ID, EVENT_TYPE, CREATED, USER_ID, DOMAIN, WORKBASKET_KEY, POR_COMPANY , POR_SYSTEM, POR_INSTANCE , POR_TYPE , POR_VALUE , TASK_CLASSIFICATION_KEY, TASK_CLASSIFICATION_CATEGORY , ATTACHMENT_CLASSIFICATION_KEY , COMMENT , OLD_VALUE , NEW_VALUE , CUSTOM_1 , CUSTOM_2 , CUSTOM_3 , CUSTOM_4 , OLD_DATA , NEW_DATA
('BPI:01' ,'', 'TKI:000000000000000000000000000000000000', 'CREATE', CURRENT_TIMESTAMP, 'USER_2_2', 'DOMAIN_B', 'WBI:100000000000000000000000000000000001', '00' , 'PASystem', '00' , 'VNR' , '11223344', 'L140101' , 'TASK' ,'' , 'this task has been created' ,'old_val' ,'new_val' ,'custom1' ,'custom2' , 'custom3' ,'custom4' ,'123' ,'456'), ('BPI:01' ,'', 'TKI:000000000000000000000000000000000000', 'CREATE', CURRENT_TIMESTAMP, 'USER_2_2', 'DOMAIN_B', 'WBI:100000000000000000000000000000000001', '00' , 'PASystem', '00' , 'VNR' , '11223344', 'L140101' , 'TASK' ,'' , 'this task has been created' ,'old_val' ,'new_val' ,'custom1' ,'custom2' , 'custom3' ,'custom4' ,'123' ,'456'),

View File

@ -71,6 +71,11 @@ public class TaskanaEngineController {
return new ResponseEntity<>(resource, HttpStatus.OK); return new ResponseEntity<>(resource, HttpStatus.OK);
} }
@GetMapping(path = "/v1/history-provider-enabled", produces = {MediaType.APPLICATION_JSON_VALUE})
public ResponseEntity<Boolean> getIsHistoryProviderEnabled() {
return new ResponseEntity<>(taskanaEngineImpl.getHistoryEventProducer().isEnabled(), HttpStatus.OK);
}
/** /**
* Get the current application version. * Get the current application version.
* *

9372
web/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -13,15 +13,15 @@
}, },
"private": true, "private": true,
"dependencies": { "dependencies": {
"@angular/animations": "6.0.9", "@angular/animations": "7.1.3",
"@angular/common": "6.0.9", "@angular/common": "7.1.3",
"@angular/compiler": "6.0.9", "@angular/compiler": "7.1.3",
"@angular/core": "6.0.9", "@angular/core": "7.1.3",
"@angular/forms": "6.0.9", "@angular/forms": "7.1.3",
"@angular/http": "6.0.9", "@angular/http": "7.1.3",
"@angular/platform-browser": "6.0.9", "@angular/platform-browser": "7.1.3",
"@angular/platform-browser-dynamic": "6.0.9", "@angular/platform-browser-dynamic": "7.1.3",
"@angular/router": "6.0.9", "@angular/router": "7.1.3",
"ajv": "6.5.2", "ajv": "6.5.2",
"angular-svg-icon": "6.0.0", "angular-svg-icon": "6.0.0",
"angular-tree-component": "7.1.0", "angular-tree-component": "7.1.0",
@ -36,22 +36,22 @@
"ng2-charts": "1.6.0", "ng2-charts": "1.6.0",
"ngx-bootstrap": "3.2.0", "ngx-bootstrap": "3.2.0",
"ngx-infinite-scroll": "6.0.1", "ngx-infinite-scroll": "6.0.1",
"node-sass": "4.9.2", "node-sass": "^4.11.0",
"popper.js": "1.14.3", "popper.js": "1.14.3",
"rxjs": "6.2.2", "rxjs": "6.3.3",
"zone.js": "0.8.26" "zone.js": "0.8.26"
}, },
"devDependencies": { "devDependencies": {
"@angular-devkit/build-angular": "0.6.8", "@angular-devkit/build-angular": "^0.13.2",
"@angular/cli": "6.0.8", "@angular/cli": "7.1.3",
"@angular/compiler-cli": "6.0.9", "@angular/compiler-cli": "^7.2.5",
"@types/jasmine": "2.8.4", "@types/jasmine": "2.8.4",
"@types/node": "9.3.0", "@types/node": "9.3.0",
"codelyzer": "4.4.2", "codelyzer": "4.4.2",
"hoek": "5.0.3", "hoek": "5.0.3",
"jasmine-core": "2.9.1", "jasmine-core": "2.9.1",
"jasmine-spec-reporter": "4.2.1", "jasmine-spec-reporter": "4.2.1",
"karma": "3.1.1", "karma": "^4.0.0",
"karma-chrome-launcher": "2.2.0", "karma-chrome-launcher": "2.2.0",
"karma-cli": "1.0.1", "karma-cli": "1.0.1",
"karma-coverage-istanbul-reporter": "1.3.3", "karma-coverage-istanbul-reporter": "1.3.3",
@ -64,6 +64,6 @@
"ts-mockito": "2.3.0", "ts-mockito": "2.3.0",
"ts-node": "4.1.0", "ts-node": "4.1.0",
"tslint": "5.9.1", "tslint": "5.9.1",
"typescript": "2.7.2" "typescript": "3.1.6"
} }
} }

View File

@ -165,16 +165,13 @@
data-target="#myModal"> data-target="#myModal">
Belonging groups Belonging groups
</button> </button>
<div class="modal" id="myModal"> <div class="modal" id="myModal">
<div class="modal-dialog"> <div class="modal-dialog">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header">
<h4 class="modal-title">Belonging groups</h4> <h4 class="modal-title">Belonging groups</h4>
<button type="button" class="close" data-dismiss="modal">&times;</button> <button type="button" class="close" data-dismiss="modal">&times;</button>
</div> </div>
<div class="modal-body"> <div class="modal-body">
<ul *ngIf="belongingGroups !== undefined && belongingGroups.length > 0 " class="list-group"> <ul *ngIf="belongingGroups !== undefined && belongingGroups.length > 0 " class="list-group">
<li *ngFor="let group of belongingGroups" class="list-group-item">{{group.name}}</li> <li *ngFor="let group of belongingGroups" class="list-group-item">{{group.name}}</li>
@ -182,17 +179,15 @@
<p *ngIf="belongingGroups === undefined || belongingGroups.length === 0">The user is not associated to <p *ngIf="belongingGroups === undefined || belongingGroups.length === 0">The user is not associated to
any groups</p> any groups</p>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="button" class="btn btn-danger" data-dismiss="modal">Close</button> <button type="button" class="btn btn-danger" data-dismiss="modal">Close</button>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div class="pull-right btn-group"> <div class="pull-right btn-group">
<button *ngIf="AccessItemsForm" type="button" (click)="revokeAccess()" class="btn btn-default" data-toggle="tooltip" title="Revoke access" <button *ngIf="AccessItemsForm" type="button" (click)="revokeAccess()" class="btn btn-default" data-toggle="tooltip"
[disabled]=isGroup> title="Revoke access" [disabled]=isGroup>
<span class="material-icons md-20 red">clear</span> <span class="material-icons md-20 red">clear</span>
</button> </button>
</div> </div>

View File

@ -11,8 +11,8 @@ import { AccessItemWorkbasket } from 'app/models/access-item-workbasket';
import { AccessIdsService } from '../../shared/services/access-ids/access-ids.service'; import { AccessIdsService } from '../../shared/services/access-ids/access-ids.service';
import { SortingModel } from 'app/models/sorting'; import { SortingModel } from 'app/models/sorting';
import { RequestInProgressService } from '../../services/requestInProgress/request-in-progress.service'; import { RequestInProgressService } from '../../services/requestInProgress/request-in-progress.service';
import { ErrorModalService } from 'app/services/errorModal/error-modal.service'; import { GeneralModalService } from 'app/services/general-modal/general-modal.service';
import { ErrorModel } from 'app/models/modal-error'; import { MessageModal } from 'app/models/message-modal';
import { RemoveConfirmationService } from 'app/services/remove-confirmation/remove-confirmation.service'; import { RemoveConfirmationService } from 'app/services/remove-confirmation/remove-confirmation.service';
import { AlertModel, AlertType } from 'app/models/alert'; import { AlertModel, AlertType } from 'app/models/alert';
import { AlertService } from 'app/services/alert/alert.service'; import { AlertService } from 'app/services/alert/alert.service';
@ -78,7 +78,7 @@ export class AccessItemsManagementComponent implements OnInit, OnDestroy {
private requestInProgressService: RequestInProgressService, private requestInProgressService: RequestInProgressService,
private removeConfirmationService: RemoveConfirmationService, private removeConfirmationService: RemoveConfirmationService,
private alertService: AlertService, private alertService: AlertService,
private errorModalService: ErrorModalService) { } private generalModalService: GeneralModalService) { }
ngOnInit() { ngOnInit() {
} }
@ -101,8 +101,8 @@ export class AccessItemsManagementComponent implements OnInit, OnDestroy {
}, },
error => { error => {
this.requestInProgressService.setRequestInProgress(false); this.requestInProgressService.setRequestInProgress(false);
this.errorModalService.triggerError( this.generalModalService.triggerMessage(
new ErrorModel( new MessageModal(
'There was error while retrieving your access ids with groups', 'There was error while retrieving your access ids with groups',
error error
) )
@ -136,8 +136,8 @@ export class AccessItemsManagementComponent implements OnInit, OnDestroy {
}, },
error => { error => {
this.requestInProgressService.setRequestInProgress(false); this.requestInProgressService.setRequestInProgress(false);
this.errorModalService.triggerError( this.generalModalService.triggerMessage(
new ErrorModel( new MessageModal(
'There was error while retrieving your access items', 'There was error while retrieving your access items',
error error
) )
@ -172,8 +172,8 @@ export class AccessItemsManagementComponent implements OnInit, OnDestroy {
}, },
error => { error => {
this.requestInProgressService.setRequestInProgress(false); this.requestInProgressService.setRequestInProgress(false);
this.errorModalService.triggerError( this.generalModalService.triggerMessage(
new ErrorModel( new MessageModal(
`You can't delete a group`, `You can't delete a group`,
error error
) )

View File

@ -6,7 +6,7 @@ import { WorkbasketDetailsComponent } from 'app/administration/workbasket/detail
import { MasterAndDetailComponent } from 'app/shared/master-and-detail/master-and-detail.component'; import { MasterAndDetailComponent } from 'app/shared/master-and-detail/master-and-detail.component';
import { ClassificationListComponent } from 'app/administration/classification/master/list/classification-list.component'; import { ClassificationListComponent } from 'app/administration/classification/master/list/classification-list.component';
import { ClassificationDetailsComponent } from 'app/administration/classification/details/classification-details.component'; import { ClassificationDetailsComponent } from 'app/administration/classification/details/classification-details.component';
import { DomainGuard } from 'app/guards/domain-guard'; import { DomainGuard } from 'app/guards/domain.guard';
import { AccessItemsManagementComponent } from './access-items-management/access-items-management.component'; import { AccessItemsManagementComponent } from './access-items-management/access-items-management.component';
const routes: Routes = [ const routes: Routes = [

View File

@ -21,6 +21,7 @@ import {ClassificationListComponent} from './classification/master/list/classifi
import {ClassificationDetailsComponent} from './classification/details/classification-details.component'; import {ClassificationDetailsComponent} from './classification/details/classification-details.component';
import {ImportExportComponent} from './components/import-export/import-export.component'; import {ImportExportComponent} from './components/import-export/import-export.component';
import {ClassificationTypesSelectorComponent} from 'app/shared/classification-types-selector/classification-types-selector.component'; import {ClassificationTypesSelectorComponent} from 'app/shared/classification-types-selector/classification-types-selector.component';
/** /**
* Services * Services
*/ */

View File

@ -32,6 +32,8 @@
</div> </div>
<div class="panel-body"> <div class="panel-body">
<form #ClassificationForm="ngForm"> <form #ClassificationForm="ngForm">
<div class="row">
<div class="col-md-6"> <div class="col-md-6">
<div class="form-group required"> <div class="form-group required">
<label for="classification-key" class="control-label">Key</label> <label for="classification-key" class="control-label">Key</label>
@ -51,8 +53,8 @@
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="classification-domain" class="control-label">Domain</label> <label for="classification-domain" class="control-label">Domain</label>
<input type="text" disabled #domain="ngModel" class="form-control" id="classification-domain" placeholder="Domain" <input type="text" disabled #domain="ngModel" class="form-control" id="classification-domain"
[(ngModel)]="classification.domain" name="classification.domain"> placeholder="Domain" [(ngModel)]="classification.domain" name="classification.domain">
<a *ngIf="!masterDomainSelected()" (click)="validChanged()"> <a *ngIf="!masterDomainSelected()" (click)="validChanged()">
<label> <label>
@ -62,13 +64,19 @@
</label> </label>
</a> </a>
</div> </div>
<div class="form-group required btn-group"> <div class="row">
<div class="form-group col-xs-6">
<label for="classification-priority" class="control-label">Priority</label>
<taskana-number-picker [(ngModel)]="classification.priority" name="classification.priority"></taskana-number-picker>
</div>
<div class="form-group required btn-group col-xs-6">
<label for="classification-category" class="control-label">Category</label> <label for="classification-category" class="control-label">Category</label>
<div class="dropdown clearfix "> <div class="dropdown clearfix ">
<button class="btn btn-default" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true"> <button class="btn btn-default" type="button" data-toggle="dropdown" aria-haspopup="true"
aria-expanded="true">
<span class="text-top"> <span class="text-top">
<svg-icon class="blue fa-fw" src="{{getCategoryIcon(classification.category).name}}" data-toggle="tooltip" <svg-icon class="blue fa-fw" src="{{getCategoryIcon(classification.category).name}}"
[title]="getCategoryIcon(classification.category).text"></svg-icon> data-toggle="tooltip" [title]="getCategoryIcon(classification.category).text"></svg-icon>
</span> </span>
{{classification.category}} {{classification.category}}
<span class="caret"></span> <span class="caret"></span>
@ -87,12 +95,8 @@
</div> </div>
</div> </div>
</div> </div>
<div class="col-md-6">
<div class="form-group">
<label for="classification-priority" class="control-label">Priority</label>
<input type="text" class="form-control" id="classification-priority" placeholder="Priority" [(ngModel)]="classification.priority"
name="classification.priority">
</div> </div>
<div class="col-md-6">
<div class="form-group"> <div class="form-group">
<label for="classification-service-level" class="control-label">Service Level</label> <label for="classification-service-level" class="control-label">Service Level</label>
<input type="text" class="form-control" id="classification-service-level" placeholder="Service Level" <input type="text" class="form-control" id="classification-service-level" placeholder="Service Level"
@ -109,6 +113,8 @@
[(ngModel)]="classification.description" name="classification.description"></textarea> [(ngModel)]="classification.description" name="classification.description"></textarea>
</div> </div>
</div> </div>
</div>
<div class="row">
<div class="col-md-6"> <div class="col-md-6">
<div *ngIf="custom1Field.visible" class="form-group"> <div *ngIf="custom1Field.visible" class="form-group">
<label for="classification-custom-1" class="control-label">{{custom1Field.field}}</label> <label for="classification-custom-1" class="control-label">{{custom1Field.field}}</label>
@ -153,6 +159,7 @@
[(ngModel)]="classification.custom8" name="classification.custom8"> [(ngModel)]="classification.custom8" name="classification.custom8">
</div> </div>
</div> </div>
</div>
</form> </form>
</div> </div>
</div> </div>

View File

@ -21,7 +21,7 @@ import { MasterAndDetailService } from 'app/services/masterAndDetail/master-and-
import { RequestInProgressService } from 'app/services/requestInProgress/request-in-progress.service'; import { RequestInProgressService } from 'app/services/requestInProgress/request-in-progress.service';
import { ClassificationsService } from 'app/services/classifications/classifications.service'; import { ClassificationsService } from 'app/services/classifications/classifications.service';
import { TreeNodeModel } from 'app/models/tree-node'; import { TreeNodeModel } from 'app/models/tree-node';
import { ErrorModalService } from 'app/services/errorModal/error-modal.service'; import { GeneralModalService } from 'app/services/general-modal/general-modal.service';
import { AlertService } from 'app/services/alert/alert.service'; import { AlertService } from 'app/services/alert/alert.service';
import { TreeService } from 'app/services/tree/tree.service'; import { TreeService } from 'app/services/tree/tree.service';
import { CustomFieldsService } from 'app/services/custom-fields/custom-fields.service'; import { CustomFieldsService } from 'app/services/custom-fields/custom-fields.service';
@ -52,7 +52,7 @@ describe('ClassificationDetailsComponent', () => {
testBed.configureTestingModule({ testBed.configureTestingModule({
imports: [FormsModule, HttpClientModule, RouterTestingModule.withRoutes(routes), AngularSvgIconModule], imports: [FormsModule, HttpClientModule, RouterTestingModule.withRoutes(routes), AngularSvgIconModule],
declarations: [ClassificationDetailsComponent, DummyDetailComponent], declarations: [ClassificationDetailsComponent, DummyDetailComponent],
providers: [MasterAndDetailService, RequestInProgressService, ClassificationsService, HttpClient, ErrorModalService, AlertService, providers: [MasterAndDetailService, RequestInProgressService, ClassificationsService, HttpClient, GeneralModalService, AlertService,
TreeService, ClassificationCategoriesService, CustomFieldsService, ImportExportService] TreeService, ClassificationCategoriesService, CustomFieldsService, ImportExportService]
}) })
}; };

View File

@ -4,7 +4,7 @@ import { Subscription } from 'rxjs';
import { ClassificationDefinition } from 'app/models/classification-definition'; import { ClassificationDefinition } from 'app/models/classification-definition';
import { ACTION } from 'app/models/action'; import { ACTION } from 'app/models/action';
import { ErrorModel } from 'app/models/modal-error'; import { MessageModal } from 'app/models/message-modal';
import { AlertModel, AlertType } from 'app/models/alert'; import { AlertModel, AlertType } from 'app/models/alert';
import { highlight } from 'app/shared/animations/validation.animation'; import { highlight } from 'app/shared/animations/validation.animation';
@ -12,7 +12,7 @@ import { TaskanaDate } from 'app/shared/util/taskana.date';
import { ClassificationsService } from 'app/services/classifications/classifications.service'; import { ClassificationsService } from 'app/services/classifications/classifications.service';
import { MasterAndDetailService } from 'app/services/masterAndDetail/master-and-detail.service'; import { MasterAndDetailService } from 'app/services/masterAndDetail/master-and-detail.service';
import { ErrorModalService } from 'app/services/errorModal/error-modal.service'; import { GeneralModalService } from 'app/services/general-modal/general-modal.service';
import { RequestInProgressService } from 'app/services/requestInProgress/request-in-progress.service'; import { RequestInProgressService } from 'app/services/requestInProgress/request-in-progress.service';
import { AlertService } from 'app/services/alert/alert.service'; import { AlertService } from 'app/services/alert/alert.service';
import { TreeService } from 'app/services/tree/tree.service'; import { TreeService } from 'app/services/tree/tree.service';
@ -74,7 +74,7 @@ export class ClassificationDetailsComponent implements OnInit, OnDestroy {
private route: ActivatedRoute, private route: ActivatedRoute,
private router: Router, private router: Router,
private masterAndDetailService: MasterAndDetailService, private masterAndDetailService: MasterAndDetailService,
private errorModalService: ErrorModalService, private generalModalService: GeneralModalService,
private requestInProgressService: RequestInProgressService, private requestInProgressService: RequestInProgressService,
private alertService: AlertService, private alertService: AlertService,
private treeService: TreeService, private treeService: TreeService,
@ -176,7 +176,7 @@ export class ClassificationDetailsComponent implements OnInit, OnDestroy {
this.afterRequest(); this.afterRequest();
}, },
error => { error => {
this.errorModalService.triggerError(new ErrorModel('There was an error creating a classification', error)) this.generalModalService.triggerMessage(new MessageModal('There was an error creating a classification', error))
this.afterRequest(); this.afterRequest();
}); });
} else { } else {
@ -188,7 +188,7 @@ export class ClassificationDetailsComponent implements OnInit, OnDestroy {
this.alertService.triggerAlert(new AlertModel(AlertType.SUCCESS, `Classification ${classification.key} was saved successfully`)); this.alertService.triggerAlert(new AlertModel(AlertType.SUCCESS, `Classification ${classification.key} was saved successfully`));
this.cloneClassification(classification); this.cloneClassification(classification);
}, error => { }, error => {
this.errorModalService.triggerError(new ErrorModel('There was error while saving your classification', error)) this.generalModalService.triggerMessage(new MessageModal('There was error while saving your classification', error))
this.afterRequest(); this.afterRequest();
}) })
} }
@ -263,7 +263,7 @@ export class ClassificationDetailsComponent implements OnInit, OnDestroy {
private checkDomainAndRedirect() { private checkDomainAndRedirect() {
this.domainSubscription = this.domainService.getSelectedDomain().subscribe(domain => { this.domainSubscription = this.domainService.getSelectedDomain().subscribe(domain => {
if (this.classification && this.classification.domain !== domain) { if (domain !== '' && this.classification && this.classification.domain !== domain) {
this.backClicked(); this.backClicked();
} }
}); });
@ -271,8 +271,8 @@ export class ClassificationDetailsComponent implements OnInit, OnDestroy {
private removeClassificationConfirmation() { private removeClassificationConfirmation() {
if (!this.classification || !this.classification.classificationId) { if (!this.classification || !this.classification.classificationId) {
this.errorModalService.triggerError( this.generalModalService.triggerMessage(
new ErrorModel('There is no classification selected', 'Please check if you are creating a classification')); new MessageModal('There is no classification selected', 'Please check if you are creating a classification'));
return false; return false;
} }
this.requestInProgressService.setRequestInProgress(true); this.requestInProgressService.setRequestInProgress(true);
@ -288,7 +288,7 @@ export class ClassificationDetailsComponent implements OnInit, OnDestroy {
this.router.navigate(['administration/classifications']); this.router.navigate(['administration/classifications']);
this.alertService.triggerAlert(new AlertModel(AlertType.SUCCESS, `Classification ${key} was removed successfully`)) this.alertService.triggerAlert(new AlertModel(AlertType.SUCCESS, `Classification ${key} was removed successfully`))
}, error => { }, error => {
this.errorModalService.triggerError(new ErrorModel('There was error while removing your classification', error)) this.generalModalService.triggerMessage(new MessageModal('There was error while removing your classification', error))
this.afterRequest(); this.afterRequest();
}) })
} }

View File

@ -18,7 +18,7 @@ import { AlertService } from 'app/services/alert/alert.service';
import { ClassificationsService } from 'app/services/classifications/classifications.service'; import { ClassificationsService } from 'app/services/classifications/classifications.service';
import { ClassificationDefinitionService } from 'app/administration/services/classification-definition/classification-definition.service'; import { ClassificationDefinitionService } from 'app/administration/services/classification-definition/classification-definition.service';
import { DomainService } from 'app/services/domain/domain.service'; import { DomainService } from 'app/services/domain/domain.service';
import { ErrorModalService } from 'app/services/errorModal/error-modal.service'; import { GeneralModalService } from 'app/services/general-modal/general-modal.service';
import { RequestInProgressService } from 'app/services/requestInProgress/request-in-progress.service'; import { RequestInProgressService } from 'app/services/requestInProgress/request-in-progress.service';
import { configureTests } from 'app/app.test.configuration'; import { configureTests } from 'app/app.test.configuration';
import { import {
@ -55,7 +55,7 @@ describe('ClassificationListComponent', () => {
imports: [HttpClientModule, RouterTestingModule.withRoutes(routes), FormsModule, AngularSvgIconModule], imports: [HttpClientModule, RouterTestingModule.withRoutes(routes), FormsModule, AngularSvgIconModule],
providers: [ providers: [
HttpClient, WorkbasketDefinitionService, AlertService, ClassificationsService, DomainService, ClassificationDefinitionService, HttpClient, WorkbasketDefinitionService, AlertService, ClassificationsService, DomainService, ClassificationDefinitionService,
ErrorModalService, RequestInProgressService, ClassificationCategoriesService, TreeService, ImportExportService GeneralModalService, RequestInProgressService, ClassificationCategoriesService, TreeService, ImportExportService
] ]
}) })
}; };

View File

@ -6,7 +6,7 @@ import { ClassificationDefinitionService } from 'app/administration/services/cla
import { WorkbasketDefinitionService } from '../../services/workbasket-definition/workbasket-definition.service'; import { WorkbasketDefinitionService } from '../../services/workbasket-definition/workbasket-definition.service';
import { AlertService } from 'app/services/alert/alert.service'; import { AlertService } from 'app/services/alert/alert.service';
import { HttpClientModule } from '@angular/common/http'; import { HttpClientModule } from '@angular/common/http';
import { ErrorModalService } from 'app/services/errorModal/error-modal.service'; import { GeneralModalService } from 'app/services/general-modal/general-modal.service';
import { AngularSvgIconModule } from 'angular-svg-icon'; import { AngularSvgIconModule } from 'angular-svg-icon';
import { configureTests } from 'app/app.test.configuration'; import { configureTests } from 'app/app.test.configuration';
import { ImportExportService } from 'app/administration/services/import-export/import-export.service'; import { ImportExportService } from 'app/administration/services/import-export/import-export.service';
@ -22,7 +22,7 @@ describe('ImportExportComponent', () => {
declarations: [ImportExportComponent], declarations: [ImportExportComponent],
imports: [HttpClientModule, AngularSvgIconModule], imports: [HttpClientModule, AngularSvgIconModule],
providers: [WorkbasketService, ClassificationDefinitionService, WorkbasketDefinitionService, AlertService, providers: [WorkbasketService, ClassificationDefinitionService, WorkbasketDefinitionService, AlertService,
ErrorModalService, ImportExportService] GeneralModalService, ImportExportService]
}) })
}; };
configureTests(configure).then(testBed => { configureTests(configure).then(testBed => {

View File

@ -3,8 +3,8 @@ import { ClassificationDefinitionService } from 'app/administration/services/cla
import { WorkbasketDefinitionService } from 'app/administration/services/workbasket-definition/workbasket-definition.service'; import { WorkbasketDefinitionService } from 'app/administration/services/workbasket-definition/workbasket-definition.service';
import { DomainService } from 'app/services/domain/domain.service'; import { DomainService } from 'app/services/domain/domain.service';
import { TaskanaType } from 'app/models/taskana-type'; import { TaskanaType } from 'app/models/taskana-type';
import { ErrorModel } from 'app/models/modal-error'; import { MessageModal } from 'app/models/message-modal';
import { ErrorModalService } from 'app/services/errorModal/error-modal.service'; import { GeneralModalService } from 'app/services/general-modal/general-modal.service';
import { environment } from 'environments/environment'; import { environment } from 'environments/environment';
import { AlertService } from 'app/services/alert/alert.service'; import { AlertService } from 'app/services/alert/alert.service';
import { AlertModel, AlertType } from 'app/models/alert'; import { AlertModel, AlertType } from 'app/models/alert';
@ -30,7 +30,7 @@ export class ImportExportComponent implements OnInit {
private domainService: DomainService, private domainService: DomainService,
private workbasketDefinitionService: WorkbasketDefinitionService, private workbasketDefinitionService: WorkbasketDefinitionService,
private classificationDefinitionService: ClassificationDefinitionService, private classificationDefinitionService: ClassificationDefinitionService,
private errorModalService: ErrorModalService, private generalModalService: GeneralModalService,
private alertService: AlertService, private alertService: AlertService,
public uploadservice: UploadService, public uploadservice: UploadService,
private importExportService: ImportExportService) { private importExportService: ImportExportService) {
@ -84,7 +84,7 @@ export class ImportExportComponent implements OnInit {
break; break;
default: default:
file.value = ''; file.value = '';
this.errorModalService.triggerError(new ErrorModel(undefined, this.generalModalService.triggerMessage(new MessageModal(undefined,
`This file format is not allowed! Please use a .json file.`)); `This file format is not allowed! Please use a .json file.`));
} }
return check; return check;
@ -117,8 +117,8 @@ export class ImportExportComponent implements OnInit {
} }
private errorHandler(title = 'Import was not successful', message) { private errorHandler(title = 'Import was not successful', message) {
this.errorModalService.triggerError( this.generalModalService.triggerMessage(
new ErrorModel( new MessageModal(
title, title,
message message
) )

View File

@ -15,7 +15,7 @@ import { ICONTYPES } from 'app/models/type';
import { AccessItemsComponent } from './access-items.component'; import { AccessItemsComponent } from './access-items.component';
import { ErrorModalService } from 'app/services/errorModal/error-modal.service'; import { GeneralModalService } from 'app/services/general-modal/general-modal.service';
import { SavingWorkbasketService } from 'app/administration/services/saving-workbaskets/saving-workbaskets.service'; import { SavingWorkbasketService } from 'app/administration/services/saving-workbaskets/saving-workbaskets.service';
import { WorkbasketService } from 'app/services/workbasket/workbasket.service'; import { WorkbasketService } from 'app/services/workbasket/workbasket.service';
import { AlertService } from 'app/services/alert/alert.service'; import { AlertService } from 'app/services/alert/alert.service';
@ -35,7 +35,7 @@ describe('AccessItemsComponent', () => {
testBed.configureTestingModule({ testBed.configureTestingModule({
declarations: [AccessItemsComponent], declarations: [AccessItemsComponent],
imports: [FormsModule, AngularSvgIconModule, HttpClientModule, ReactiveFormsModule], imports: [FormsModule, AngularSvgIconModule, HttpClientModule, ReactiveFormsModule],
providers: [WorkbasketService, AlertService, ErrorModalService, SavingWorkbasketService, RequestInProgressService, providers: [WorkbasketService, AlertService, GeneralModalService, SavingWorkbasketService, RequestInProgressService,
CustomFieldsService, AccessIdsService, FormsValidatorService] CustomFieldsService, AccessIdsService, FormsValidatorService]
}) })
}; };

View File

@ -5,12 +5,12 @@ import { FormBuilder, Validators, FormArray } from '@angular/forms';
import { Workbasket } from 'app/models/workbasket'; import { Workbasket } from 'app/models/workbasket';
import { WorkbasketAccessItems } from 'app/models/workbasket-access-items'; import { WorkbasketAccessItems } from 'app/models/workbasket-access-items';
import { WorkbasketAccessItemsResource } from 'app/models/workbasket-access-items-resource'; import { WorkbasketAccessItemsResource } from 'app/models/workbasket-access-items-resource';
import { ErrorModel } from 'app/models/modal-error'; import { MessageModal } from 'app/models/message-modal';
import { ACTION } from 'app/models/action'; import { ACTION } from 'app/models/action';
import { AlertModel, AlertType } from 'app/models/alert'; import { AlertModel, AlertType } from 'app/models/alert';
import { SavingWorkbasketService, SavingInformation } from 'app/administration/services/saving-workbaskets/saving-workbaskets.service'; import { SavingWorkbasketService, SavingInformation } from 'app/administration/services/saving-workbaskets/saving-workbaskets.service';
import { ErrorModalService } from 'app/services/errorModal/error-modal.service'; import { GeneralModalService } from 'app/services/general-modal/general-modal.service';
import { WorkbasketService } from 'app/services/workbasket/workbasket.service'; import { WorkbasketService } from 'app/services/workbasket/workbasket.service';
import { AlertService } from 'app/services/alert/alert.service'; import { AlertService } from 'app/services/alert/alert.service';
import { RequestInProgressService } from 'app/services/requestInProgress/request-in-progress.service'; import { RequestInProgressService } from 'app/services/requestInProgress/request-in-progress.service';
@ -80,7 +80,7 @@ export class AccessItemsComponent implements OnChanges, OnDestroy {
constructor( constructor(
private workbasketService: WorkbasketService, private workbasketService: WorkbasketService,
private alertService: AlertService, private alertService: AlertService,
private errorModalService: ErrorModalService, private generalModalService: GeneralModalService,
private savingWorkbaskets: SavingWorkbasketService, private savingWorkbaskets: SavingWorkbasketService,
private requestInProgressService: RequestInProgressService, private requestInProgressService: RequestInProgressService,
private customFieldsService: CustomFieldsService, private customFieldsService: CustomFieldsService,
@ -181,7 +181,7 @@ export class AccessItemsComponent implements OnChanges, OnDestroy {
AlertType.SUCCESS, `Workbasket ${this.workbasket.name} Access items were saved successfully`)); AlertType.SUCCESS, `Workbasket ${this.workbasket.name} Access items were saved successfully`));
this.requestInProgressService.setRequestInProgress(false); this.requestInProgressService.setRequestInProgress(false);
}, error => { }, error => {
this.errorModalService.triggerError(new ErrorModel(`There was error while saving your workbasket's access items`, error)) this.generalModalService.triggerMessage(new MessageModal(`There was error while saving your workbasket's access items`, error))
this.requestInProgressService.setRequestInProgress(false); this.requestInProgressService.setRequestInProgress(false);
}) })
} }

View File

@ -14,7 +14,7 @@ import { WorkbasketDistributionTargetsResource } from 'app/models/workbasket-dis
import { WorkbasketService } from 'app/services/workbasket/workbasket.service'; import { WorkbasketService } from 'app/services/workbasket/workbasket.service';
import { AlertService } from 'app/services/alert/alert.service'; import { AlertService } from 'app/services/alert/alert.service';
import { ErrorModalService } from 'app/services/errorModal/error-modal.service'; import { GeneralModalService } from 'app/services/general-modal/general-modal.service';
import { SavingWorkbasketService, SavingInformation } from 'app/administration/services/saving-workbaskets/saving-workbaskets.service'; import { SavingWorkbasketService, SavingInformation } from 'app/administration/services/saving-workbaskets/saving-workbaskets.service';
import { RequestInProgressService } from 'app/services/requestInProgress/request-in-progress.service'; import { RequestInProgressService } from 'app/services/requestInProgress/request-in-progress.service';
@ -36,7 +36,7 @@ describe('DistributionTargetsComponent', () => {
testBed.configureTestingModule({ testBed.configureTestingModule({
imports: [AngularSvgIconModule, HttpClientModule, InfiniteScrollModule], imports: [AngularSvgIconModule, HttpClientModule, InfiniteScrollModule],
declarations: [DistributionTargetsComponent, DualListComponent], declarations: [DistributionTargetsComponent, DualListComponent],
providers: [WorkbasketService, AlertService, SavingWorkbasketService, ErrorModalService, RequestInProgressService, providers: [WorkbasketService, AlertService, SavingWorkbasketService, GeneralModalService, RequestInProgressService,
] ]
}) })
}; };

View File

@ -5,14 +5,14 @@ import { Workbasket } from 'app/models/workbasket';
import { WorkbasketSummary } from 'app/models/workbasket-summary'; import { WorkbasketSummary } from 'app/models/workbasket-summary';
import { WorkbasketSummaryResource } from 'app/models/workbasket-summary-resource'; import { WorkbasketSummaryResource } from 'app/models/workbasket-summary-resource';
import { WorkbasketDistributionTargetsResource } from 'app/models/workbasket-distribution-targets-resource'; import { WorkbasketDistributionTargetsResource } from 'app/models/workbasket-distribution-targets-resource';
import { ErrorModel } from 'app/models/modal-error'; import { MessageModal } from 'app/models/message-modal';
import { ACTION } from 'app/models/action'; import { ACTION } from 'app/models/action';
import { AlertModel, AlertType } from 'app/models/alert'; import { AlertModel, AlertType } from 'app/models/alert';
import { WorkbasketService } from 'app/services/workbasket/workbasket.service'; import { WorkbasketService } from 'app/services/workbasket/workbasket.service';
import { AlertService } from 'app/services/alert/alert.service'; import { AlertService } from 'app/services/alert/alert.service';
import { SavingWorkbasketService, SavingInformation } from 'app/administration/services/saving-workbaskets/saving-workbaskets.service'; import { SavingWorkbasketService, SavingInformation } from 'app/administration/services/saving-workbaskets/saving-workbaskets.service';
import { ErrorModalService } from 'app/services/errorModal/error-modal.service'; import { GeneralModalService } from 'app/services/general-modal/general-modal.service';
import { RequestInProgressService } from 'app/services/requestInProgress/request-in-progress.service'; import { RequestInProgressService } from 'app/services/requestInProgress/request-in-progress.service';
import { TaskanaQueryParameters } from 'app/shared/util/query-parameters'; import { TaskanaQueryParameters } from 'app/shared/util/query-parameters';
import { Page } from 'app/models/page'; import { Page } from 'app/models/page';
@ -69,7 +69,7 @@ export class DistributionTargetsComponent implements OnChanges, OnDestroy {
private workbasketService: WorkbasketService, private workbasketService: WorkbasketService,
private alertService: AlertService, private alertService: AlertService,
private savingWorkbaskets: SavingWorkbasketService, private savingWorkbaskets: SavingWorkbasketService,
private errorModalService: ErrorModalService, private generalModalService: GeneralModalService,
private requestInProgressService: RequestInProgressService, private requestInProgressService: RequestInProgressService,
private orientationService: OrientationService) { } private orientationService: OrientationService) { }
@ -121,7 +121,7 @@ export class DistributionTargetsComponent implements OnChanges, OnDestroy {
return true; return true;
}, },
error => { error => {
this.errorModalService.triggerError(new ErrorModel(`There was error while saving your workbasket's distribution targets`, error)) this.generalModalService.triggerMessage(new MessageModal(`There was error while saving your workbasket's distribution targets`, error))
this.requestInProgressService.setRequestInProgress(false); this.requestInProgressService.setRequestInProgress(false);
return false; return false;
} }

View File

@ -14,7 +14,7 @@ import { ICONTYPES } from 'app/models/type';
import { ACTION } from 'app/models/action'; import { ACTION } from 'app/models/action';
import { Links } from 'app/models/links'; import { Links } from 'app/models/links';
import { ErrorModalService } from 'app/services/errorModal/error-modal.service'; import { GeneralModalService } from 'app/services/general-modal/general-modal.service';
import { SavingWorkbasketService } from 'app/administration/services/saving-workbaskets/saving-workbaskets.service'; import { SavingWorkbasketService } from 'app/administration/services/saving-workbaskets/saving-workbaskets.service';
import { AlertService } from 'app/services/alert/alert.service'; import { AlertService } from 'app/services/alert/alert.service';
import { RequestInProgressService } from 'app/services/requestInProgress/request-in-progress.service'; import { RequestInProgressService } from 'app/services/requestInProgress/request-in-progress.service';
@ -47,7 +47,7 @@ describe('WorkbasketInformationComponent', () => {
AngularSvgIconModule, AngularSvgIconModule,
HttpClientModule, HttpClientModule,
RouterTestingModule.withRoutes(routes)], RouterTestingModule.withRoutes(routes)],
providers: [WorkbasketService, AlertService, SavingWorkbasketService, ErrorModalService, RequestInProgressService, providers: [WorkbasketService, AlertService, SavingWorkbasketService, GeneralModalService, RequestInProgressService,
CustomFieldsService, FormsValidatorService] CustomFieldsService, FormsValidatorService]
}) })

View File

@ -12,14 +12,14 @@ import { Subscription } from 'rxjs';
import { NgForm } from '@angular/forms'; import { NgForm } from '@angular/forms';
import { ICONTYPES } from 'app/models/type'; import { ICONTYPES } from 'app/models/type';
import { ErrorModel } from 'app/models/modal-error'; import { MessageModal } from 'app/models/message-modal';
import { ACTION } from 'app/models/action'; import { ACTION } from 'app/models/action';
import { Workbasket } from 'app/models/workbasket'; import { Workbasket } from 'app/models/workbasket';
import { AlertModel, AlertType } from 'app/models/alert'; import { AlertModel, AlertType } from 'app/models/alert';
import { TaskanaDate } from 'app/shared/util/taskana.date'; import { TaskanaDate } from 'app/shared/util/taskana.date';
import { AlertService } from 'app/services/alert/alert.service'; import { AlertService } from 'app/services/alert/alert.service';
import { ErrorModalService } from 'app/services/errorModal/error-modal.service'; import { GeneralModalService } from 'app/services/general-modal/general-modal.service';
import { import {
SavingWorkbasketService, SavingWorkbasketService,
SavingInformation SavingInformation
@ -81,7 +81,7 @@ export class WorkbasketInformationComponent
private alertService: AlertService, private alertService: AlertService,
private route: ActivatedRoute, private route: ActivatedRoute,
private router: Router, private router: Router,
private errorModalService: ErrorModalService, private generalModalService: GeneralModalService,
private savingWorkbasket: SavingWorkbasketService, private savingWorkbasket: SavingWorkbasketService,
private requestInProgressService: RequestInProgressService, private requestInProgressService: RequestInProgressService,
private customFieldsService: CustomFieldsService, private customFieldsService: CustomFieldsService,
@ -168,8 +168,8 @@ export class WorkbasketInformationComponent
); );
}, },
error => { error => {
this.errorModalService.triggerError( this.generalModalService.triggerMessage(
new ErrorModel( new MessageModal(
`There was an error removing distribution target for ${ `There was an error removing distribution target for ${
this.workbasket.workbasketId this.workbasket.workbasketId
}.`, }.`,
@ -204,8 +204,8 @@ export class WorkbasketInformationComponent
}, },
error => { error => {
this.afterRequest(); this.afterRequest();
this.errorModalService.triggerError( this.generalModalService.triggerMessage(
new ErrorModel( new MessageModal(
'There was error while saving your workbasket', 'There was error while saving your workbasket',
error error
) )
@ -256,8 +256,8 @@ export class WorkbasketInformationComponent
} }
}, },
error => { error => {
this.errorModalService.triggerError( this.generalModalService.triggerMessage(
new ErrorModel('There was an error creating a workbasket', error) new MessageModal('There was an error creating a workbasket', error)
); );
this.requestInProgressService.setRequestInProgress(false); this.requestInProgressService.setRequestInProgress(false);
} }
@ -279,8 +279,8 @@ export class WorkbasketInformationComponent
this.requestInProgressService.setRequestInProgress(false); this.requestInProgressService.setRequestInProgress(false);
this.workbasketService.triggerWorkBasketSaved(); this.workbasketService.triggerWorkBasketSaved();
if (response) { if (response) {
this.errorModalService.triggerError( this.generalModalService.triggerMessage(
new ErrorModel('There was an error marking workbasket for deletion', new MessageModal('There was an error marking workbasket for deletion',
'It not possible to mark the workbasket for deletion, It has been deleted.') 'It not possible to mark the workbasket for deletion, It has been deleted.')
); );
} else { } else {

View File

@ -20,7 +20,7 @@ import { WorkbasketService } from 'app/services/workbasket/workbasket.service';
import { MasterAndDetailService } from 'app/services/masterAndDetail/master-and-detail.service'; import { MasterAndDetailService } from 'app/services/masterAndDetail/master-and-detail.service';
import { AlertService } from 'app/services/alert/alert.service'; import { AlertService } from 'app/services/alert/alert.service';
import { SavingWorkbasketService } from 'app/administration/services/saving-workbaskets/saving-workbaskets.service'; import { SavingWorkbasketService } from 'app/administration/services/saving-workbaskets/saving-workbaskets.service';
import { ErrorModalService } from 'app/services/errorModal/error-modal.service'; import { GeneralModalService } from 'app/services/general-modal/general-modal.service';
import { RequestInProgressService } from 'app/services/requestInProgress/request-in-progress.service'; import { RequestInProgressService } from 'app/services/requestInProgress/request-in-progress.service';
import { CustomFieldsService } from 'app/services/custom-fields/custom-fields.service'; import { CustomFieldsService } from 'app/services/custom-fields/custom-fields.service';
import { configureTests } from 'app/app.test.configuration'; import { configureTests } from 'app/app.test.configuration';
@ -62,7 +62,7 @@ describe('WorkbasketDetailsComponent', () => {
declarations: [WorkbasketDetailsComponent, WorkbasketInformationComponent, declarations: [WorkbasketDetailsComponent, WorkbasketInformationComponent,
AccessItemsComponent, AccessItemsComponent,
DistributionTargetsComponent, DualListComponent, DummyDetailComponent], DistributionTargetsComponent, DualListComponent, DummyDetailComponent],
providers: [WorkbasketService, MasterAndDetailService, ErrorModalService, RequestInProgressService, providers: [WorkbasketService, MasterAndDetailService, GeneralModalService, RequestInProgressService,
AlertService, SavingWorkbasketService, CustomFieldsService, ImportExportService] AlertService, SavingWorkbasketService, CustomFieldsService, ImportExportService]
}) })
}; };

View File

@ -4,12 +4,12 @@ import { Subscription } from 'rxjs';
import { Workbasket } from 'app/models/workbasket'; import { Workbasket } from 'app/models/workbasket';
import { ACTION } from 'app/models/action'; import { ACTION } from 'app/models/action';
import { ErrorModel } from '../../../models/modal-error'; import { MessageModal } from '../../../models/message-modal';
import { WorkbasketService } from 'app/services/workbasket/workbasket.service' import { WorkbasketService } from 'app/services/workbasket/workbasket.service'
import { MasterAndDetailService } from 'app/services/masterAndDetail/master-and-detail.service' import { MasterAndDetailService } from 'app/services/masterAndDetail/master-and-detail.service'
import { DomainService } from 'app/services/domain/domain.service'; import { DomainService } from 'app/services/domain/domain.service';
import { ErrorModalService } from '../../../services/errorModal/error-modal.service'; import { GeneralModalService } from '../../../services/general-modal/general-modal.service';
import { ImportExportService } from 'app/administration/services/import-export/import-export.service'; import { ImportExportService } from 'app/administration/services/import-export/import-export.service';
@Component({ @Component({
@ -39,7 +39,7 @@ export class WorkbasketDetailsComponent implements OnInit, OnDestroy {
private router: Router, private router: Router,
private masterAndDetailService: MasterAndDetailService, private masterAndDetailService: MasterAndDetailService,
private domainService: DomainService, private domainService: DomainService,
private errorModalService: ErrorModalService, private generalModalService: GeneralModalService,
private importExportService: ImportExportService) { } private importExportService: ImportExportService) { }
@ -118,15 +118,15 @@ export class WorkbasketDetailsComponent implements OnInit, OnDestroy {
this.requestInProgress = false; this.requestInProgress = false;
this.checkDomainAndRedirect(); this.checkDomainAndRedirect();
}, err => { }, err => {
this.errorModalService.triggerError( this.generalModalService.triggerMessage(
new ErrorModel('An error occurred while fetching the workbasket', err)); new MessageModal('An error occurred while fetching the workbasket', err));
}); });
} }
} }
private checkDomainAndRedirect() { private checkDomainAndRedirect() {
this.domainSubscription = this.domainService.getSelectedDomain().subscribe(domain => { this.domainSubscription = this.domainService.getSelectedDomain().subscribe(domain => {
if (this.workbasket && this.workbasket.domain !== domain) { if (domain !== '' && this.workbasket && this.workbasket.domain !== domain) {
this.backClicked(); this.backClicked();
} }
}); });

View File

@ -1,11 +1,10 @@
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router'; import { RouterModule, Routes } from '@angular/router';
import { AppComponent } from './app.component'; import { BusinessAdminGuard } from './guards/business-admin.guard';
import { MonitorGuard } from './guards/monitor.guard';
import { BusinessAdminGuard } from './guards/business-admin-guard'; import { UserGuard } from './guards/user.guard';
import { MonitorGuard } from './guards/monitor-guard'; import { HistoryGuard } from './guards/history.guard';
import { UserGuard } from './guards/user-guard';
import { NoAccessComponent } from './components/no-access/no-access.component'; import { NoAccessComponent } from './components/no-access/no-access.component';
const appRoutes: Routes = [ const appRoutes: Routes = [
@ -24,6 +23,11 @@ const appRoutes: Routes = [
path: 'workplace', path: 'workplace',
loadChildren: './workplace/workplace.module#WorkplaceModule' loadChildren: './workplace/workplace.module#WorkplaceModule'
}, },
{
canActivate: [HistoryGuard],
path: 'history',
loadChildren: './history/history.module#HistoryModule'
},
{ {
path: 'no-role', path: 'no-role',
component: NoAccessComponent component: NoAccessComponent

View File

@ -2,7 +2,8 @@
<div class="container-fluid container-main" (window:resize)="onResize($event)"> <div class="container-fluid container-main" (window:resize)="onResize($event)">
<div class="row "> <div class="row ">
<router-outlet></router-outlet> <router-outlet></router-outlet>
<taskana-general-message-modal *ngIf="modalErrorMessage" [(message)]="modalErrorMessage" [title]="modalTitle" error="true"></taskana-general-message-modal> <taskana-general-message-modal *ngIf="modalMessage" [(message)]="modalMessage" [title]="modalTitle"
[type]="modalType" error="true"></taskana-general-message-modal>
<taskana-spinner [isRunning]="requestInProgress" isModal=true></taskana-spinner> <taskana-spinner [isRunning]="requestInProgress" isModal=true></taskana-spinner>
<taskana-alert></taskana-alert> <taskana-alert></taskana-alert>
<taskana-remove-confirmation></taskana-remove-confirmation> <taskana-remove-confirmation></taskana-remove-confirmation>

View File

@ -2,9 +2,9 @@ import { Component, OnInit, HostListener, OnDestroy } from '@angular/core';
import { Router, NavigationStart } from '@angular/router'; import { Router, NavigationStart } from '@angular/router';
import { Subscription } from 'rxjs'; import { Subscription } from 'rxjs';
import { ErrorModel } from './models/modal-error'; import { MessageModal } from './models/message-modal';
import { ErrorModalService } from './services/errorModal/error-modal.service'; import { GeneralModalService } from './services/general-modal/general-modal.service';
import { RequestInProgressService } from './services/requestInProgress/request-in-progress.service'; import { RequestInProgressService } from './services/requestInProgress/request-in-progress.service';
import { OrientationService } from './services/orientation/orientation.service'; import { OrientationService } from './services/orientation/orientation.service';
import { SelectedRouteService } from './services/selected-route/selected-route'; import { SelectedRouteService } from './services/selected-route/selected-route';
@ -20,14 +20,15 @@ export class AppComponent implements OnInit, OnDestroy {
workbasketsRoute = true; workbasketsRoute = true;
modalErrorMessage = ''; modalMessage = '';
modalTitle = ''; modalTitle = '';
modalType;
selectedRoute = ''; selectedRoute = '';
requestInProgress = false; requestInProgress = false;
currentProgressValue = 0; currentProgressValue = 0;
errorModalSubscription: Subscription; modalSubscription: Subscription;
requestInProgressSubscription: Subscription; requestInProgressSubscription: Subscription;
selectedRouteSubscription: Subscription; selectedRouteSubscription: Subscription;
routerSubscription: Subscription; routerSubscription: Subscription;
@ -40,7 +41,7 @@ export class AppComponent implements OnInit, OnDestroy {
constructor( constructor(
private router: Router, private router: Router,
private errorModalService: ErrorModalService, private generalModalService: GeneralModalService,
private requestInProgressService: RequestInProgressService, private requestInProgressService: RequestInProgressService,
private orientationService: OrientationService, private orientationService: OrientationService,
private selectedRouteService: SelectedRouteService, private selectedRouteService: SelectedRouteService,
@ -56,15 +57,18 @@ export class AppComponent implements OnInit, OnDestroy {
} }
}) })
this.errorModalSubscription = this.errorModalService.getError().subscribe((error: ErrorModel) => { this.modalSubscription = this.generalModalService.getMessage().subscribe((messageModal: MessageModal) => {
if (typeof error.message === 'string') { if (typeof messageModal.message === 'string') {
this.modalErrorMessage = error.message this.modalMessage = messageModal.message
} else if (error.message.error instanceof ProgressEvent) { } else if (messageModal.message.error instanceof ProgressEvent) {
this.modalErrorMessage = error.message.message; this.modalMessage = messageModal.message.message;
} else { } else {
this.modalErrorMessage = error.message.error ? (error.message.error.error + ' ' + error.message.error.message) : error.message.message; this.modalMessage = messageModal.message.error ?
(messageModal.message.error.error + ' ' + messageModal.message.error.message)
: messageModal.message.message;
} }
this.modalTitle = error.title; this.modalTitle = messageModal.title;
this.modalType = messageModal.type;
}) })
this.requestInProgressSubscription = this.requestInProgressService.getRequestInProgress().subscribe((value: boolean) => { this.requestInProgressSubscription = this.requestInProgressService.getRequestInProgress().subscribe((value: boolean) => {
@ -84,7 +88,7 @@ export class AppComponent implements OnInit, OnDestroy {
ngOnDestroy() { ngOnDestroy() {
if (this.routerSubscription) { this.routerSubscription.unsubscribe(); } if (this.routerSubscription) { this.routerSubscription.unsubscribe(); }
if (this.errorModalSubscription) { this.errorModalSubscription.unsubscribe(); } if (this.modalSubscription) { this.modalSubscription.unsubscribe(); }
if (this.requestInProgressSubscription) { this.requestInProgressSubscription.unsubscribe(); } if (this.requestInProgressSubscription) { this.requestInProgressSubscription.unsubscribe(); }
if (this.selectedRouteSubscription) { this.selectedRouteSubscription.unsubscribe(); } if (this.selectedRouteSubscription) { this.selectedRouteSubscription.unsubscribe(); }
if (this.uploadingFileSubscription) { this.uploadingFileSubscription.unsubscribe(); } if (this.uploadingFileSubscription) { this.uploadingFileSubscription.unsubscribe(); }

View File

@ -18,7 +18,7 @@ import { SharedModule } from 'app/shared/shared.module';
* Services * Services
*/ */
import { ErrorModalService } from 'app/services/errorModal/error-modal.service'; import { GeneralModalService } from 'app/services/general-modal/general-modal.service';
import { RequestInProgressService } from 'app/services/requestInProgress/request-in-progress.service'; import { RequestInProgressService } from 'app/services/requestInProgress/request-in-progress.service';
import { OrientationService } from 'app/services/orientation/orientation.service'; import { OrientationService } from 'app/services/orientation/orientation.service';
import { SelectedRouteService } from 'app/services/selected-route/selected-route'; import { SelectedRouteService } from 'app/services/selected-route/selected-route';
@ -46,10 +46,10 @@ import { NoAccessComponent } from 'app/components/no-access/no-access.component'
/** /**
* Guards * Guards
*/ */
import { DomainGuard } from './guards/domain-guard'; import { DomainGuard } from './guards/domain.guard';
import { BusinessAdminGuard } from './guards/business-admin-guard'; import { BusinessAdminGuard } from './guards/business-admin.guard';
import { MonitorGuard } from './guards/monitor-guard'; import { MonitorGuard } from './guards/monitor.guard';
import { UserGuard } from './guards/user-guard'; import { UserGuard } from './guards/user.guard';
import { APP_BASE_HREF } from '@angular/common'; import { APP_BASE_HREF } from '@angular/common';
@ -88,7 +88,7 @@ export function startupServiceFactory(startupService: StartupService): () => Pro
WindowRefService, WindowRefService,
{ provide: APP_BASE_HREF, useValue: '/' }, { provide: APP_BASE_HREF, useValue: '/' },
DomainService, DomainService,
ErrorModalService, GeneralModalService,
RequestInProgressService, RequestInProgressService,
OrientationService, OrientationService,
SelectedRouteService, SelectedRouteService,

View File

@ -16,7 +16,7 @@ import { DomainServiceMock } from './services/domain/domain.service.mock';
import { CustomFieldsService } from 'app/services/custom-fields/custom-fields.service'; import { CustomFieldsService } from 'app/services/custom-fields/custom-fields.service';
import { RemoveConfirmationService } from 'app/services/remove-confirmation/remove-confirmation.service'; import { RemoveConfirmationService } from 'app/services/remove-confirmation/remove-confirmation.service';
import { AlertService } from './services/alert/alert.service'; import { AlertService } from './services/alert/alert.service';
import { ErrorModalService } from './services/errorModal/error-modal.service'; import { GeneralModalService } from './services/general-modal/general-modal.service';
import { RequestInProgressService } from './services/requestInProgress/request-in-progress.service'; import { RequestInProgressService } from './services/requestInProgress/request-in-progress.service';
import { OrientationService } from './services/orientation/orientation.service'; import { OrientationService } from './services/orientation/orientation.service';
import { SelectedRouteService } from './services/selected-route/selected-route'; import { SelectedRouteService } from './services/selected-route/selected-route';
@ -41,7 +41,7 @@ export const configureTests = (configure: (testBed: TestBed) => void) => {
imports: [BrowserAnimationsModule, SharedModule, FormsModule, ReactiveFormsModule, HttpClientModule, AngularSvgIconModule], imports: [BrowserAnimationsModule, SharedModule, FormsModule, ReactiveFormsModule, HttpClientModule, AngularSvgIconModule],
providers: [{ provide: TaskanaEngineService, useClass: TaskanaEngineServiceMock }, providers: [{ provide: TaskanaEngineService, useClass: TaskanaEngineServiceMock },
{ provide: DomainService, useClass: DomainServiceMock }, CustomFieldsService, RemoveConfirmationService, { provide: DomainService, useClass: DomainServiceMock }, CustomFieldsService, RemoveConfirmationService,
AlertService, ErrorModalService, RequestInProgressService, OrientationService, SelectedRouteService, FormsValidatorService] AlertService, GeneralModalService, RequestInProgressService, OrientationService, SelectedRouteService, FormsValidatorService]
}); });
return testBed.compileComponents().then(() => testBed); return testBed.compileComponents().then(() => testBed);

View File

@ -66,6 +66,9 @@
<div *ngIf="workplaceAccess" class="row menu" [ngClass]="{'selected': selectedRoute.indexOf('workplace') !== -1 || selectedRoute === ''}"> <div *ngIf="workplaceAccess" class="row menu" [ngClass]="{'selected': selectedRoute.indexOf('workplace') !== -1 || selectedRoute === ''}">
<span (click)="toogleNavBar()" routerLink="{{workplaceUrl}}" aria-controls="Workplace" routerLinkActive="active">Workplace</span> <span (click)="toogleNavBar()" routerLink="{{workplaceUrl}}" aria-controls="Workplace" routerLinkActive="active">Workplace</span>
</div> </div>
<div *ngIf="historyAccess" class="row menu" [ngClass]="{'selected': selectedRoute.indexOf('history') !== -1}">
<span (click)="toogleNavBar()" routerLink="{{historyUrl}}" aria-controls="history" routerLinkActive="active">History</span>
</div>
</div> </div>
<div class="nav-version"> <div class="nav-version">
<p id="taskana-version"> Taskana version: {{version}} </p> <p id="taskana-version"> Taskana version: {{version}} </p>

View File

@ -9,10 +9,10 @@ import { NavBarComponent } from './nav-bar.component';
import { UserInformationComponent } from 'app/components/user-information/user-information.component'; import { UserInformationComponent } from 'app/components/user-information/user-information.component';
import { SelectedRouteService } from 'app/services/selected-route/selected-route'; import { SelectedRouteService } from 'app/services/selected-route/selected-route';
import { BusinessAdminGuard } from 'app/guards/business-admin-guard'; import { BusinessAdminGuard } from 'app/guards/business-admin.guard';
import { MonitorGuard } from 'app/guards/monitor-guard'; import { MonitorGuard } from 'app/guards/monitor.guard';
import { WindowRefService } from 'app/services/window/window.service'; import { WindowRefService } from 'app/services/window/window.service';
import { ErrorModalService } from 'app/services/errorModal/error-modal.service'; import { GeneralModalService } from 'app/services/general-modal/general-modal.service';
import { RequestInProgressService } from 'app/services/requestInProgress/request-in-progress.service'; import { RequestInProgressService } from 'app/services/requestInProgress/request-in-progress.service';
import { configureTests } from 'app/app.test.configuration'; import { configureTests } from 'app/app.test.configuration';
@ -41,7 +41,7 @@ describe('NavBarComponent', () => {
BusinessAdminGuard, BusinessAdminGuard,
MonitorGuard, MonitorGuard,
WindowRefService, WindowRefService,
ErrorModalService, GeneralModalService,
RequestInProgressService] RequestInProgressService]
}) })
}; };

View File

@ -3,10 +3,10 @@ import { environment } from 'environments/environment';
import { SelectedRouteService } from 'app/services/selected-route/selected-route'; import { SelectedRouteService } from 'app/services/selected-route/selected-route';
import { Subscription } from 'rxjs'; import { Subscription } from 'rxjs';
import { DomainService } from 'app/services/domain/domain.service'; import { DomainService } from 'app/services/domain/domain.service';
import { BusinessAdminGuard } from 'app/guards/business-admin-guard'; import { BusinessAdminGuard } from 'app/guards/business-admin.guard';
import { MonitorGuard } from 'app/guards/monitor-guard'; import { MonitorGuard } from 'app/guards/monitor.guard';
import { WindowRefService } from 'app/services/window/window.service'; import { WindowRefService } from 'app/services/window/window.service';
import { UserGuard } from 'app/guards/user-guard'; import { UserGuard } from 'app/guards/user.guard';
import { TaskanaEngineService } from '../../services/taskana-engine/taskana-engine.service'; import { TaskanaEngineService } from '../../services/taskana-engine/taskana-engine.service';
import { expandRight } from 'app/shared/animations/expand.animation'; import { expandRight } from 'app/shared/animations/expand.animation';
@Component({ @Component({
@ -27,6 +27,7 @@ export class NavBarComponent implements OnInit, OnDestroy {
titleAccessItems = 'Access items'; titleAccessItems = 'Access items';
titleMonitor = 'Monitor'; titleMonitor = 'Monitor';
titleWorkplace = 'Workplace'; titleWorkplace = 'Workplace';
titleHistory = 'History';
showNavbar = false; showNavbar = false;
domains: Array<string> = []; domains: Array<string> = [];
selectedDomain: string; selectedDomain: string;
@ -35,10 +36,12 @@ export class NavBarComponent implements OnInit, OnDestroy {
adminUrl = './administration'; adminUrl = './administration';
monitorUrl = './monitor'; monitorUrl = './monitor';
workplaceUrl = './workplace'; workplaceUrl = './workplace';
historyUrl = './history';
administrationAccess = false; administrationAccess = false;
monitorAccess = false; monitorAccess = false;
workplaceAccess = false; workplaceAccess = false;
historyAccess = false;
selectedRouteSubscription: Subscription; selectedRouteSubscription: Subscription;
getDomainsSubscription: Subscription; getDomainsSubscription: Subscription;
@ -69,6 +72,11 @@ export class NavBarComponent implements OnInit, OnDestroy {
this.administrationAccess = this.taskanaEngineService.hasRole(BusinessAdminGuard.roles); this.administrationAccess = this.taskanaEngineService.hasRole(BusinessAdminGuard.roles);
this.monitorAccess = this.taskanaEngineService.hasRole(MonitorGuard.roles); this.monitorAccess = this.taskanaEngineService.hasRole(MonitorGuard.roles);
this.workplaceAccess = this.taskanaEngineService.hasRole(UserGuard.roles); this.workplaceAccess = this.taskanaEngineService.hasRole(UserGuard.roles);
this.taskanaEngineService.isHistoryProviderEnabled().subscribe(value => {
this.historyAccess = value;
})
} }
switchDomain(domain) { switchDomain(domain) {
@ -103,6 +111,8 @@ export class NavBarComponent implements OnInit, OnDestroy {
this.title = this.titleWorkplace; this.title = this.titleWorkplace;
} else if (value.indexOf('access-items') === 0) { } else if (value.indexOf('access-items') === 0) {
this.title = this.titleAccessItems; this.title = this.titleAccessItems;
} else if (value.indexOf('history') === 0) {
this.title = this.titleHistory;
} }
} }

View File

@ -1,8 +1,8 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { TaskanaEngineService } from '../../services/taskana-engine/taskana-engine.service'; import { TaskanaEngineService } from '../../services/taskana-engine/taskana-engine.service';
import { BusinessAdminGuard } from 'app/guards/business-admin-guard'; import { BusinessAdminGuard } from 'app/guards/business-admin.guard';
import { MonitorGuard } from 'app/guards/monitor-guard'; import { MonitorGuard } from 'app/guards/monitor.guard';
import { UserGuard } from 'app/guards/user-guard'; import { UserGuard } from 'app/guards/user.guard';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
@Component({ @Component({

View File

@ -1,10 +1,5 @@
import { Observable } from 'rxjs';
import { HttpClient } from '@angular/common/http';
import { CanActivate, Router } from '@angular/router'; import { CanActivate, Router } from '@angular/router';
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { DomainService } from 'app/services/domain/domain.service';
import { ErrorModalService } from 'app/services/errorModal/error-modal.service';
import { ErrorModel } from 'app/models/modal-error';
import { TaskanaEngineService } from 'app/services/taskana-engine/taskana-engine.service'; import { TaskanaEngineService } from 'app/services/taskana-engine/taskana-engine.service';
@Injectable() @Injectable()

View File

@ -2,13 +2,13 @@ import { of } from 'rxjs';
import { CanActivate } from '@angular/router'; import { CanActivate } from '@angular/router';
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { DomainService } from 'app/services/domain/domain.service'; import { DomainService } from 'app/services/domain/domain.service';
import { ErrorModalService } from 'app/services/errorModal/error-modal.service'; import { GeneralModalService } from 'app/services/general-modal/general-modal.service';
import { ErrorModel } from 'app/models/modal-error'; import { MessageModal } from 'app/models/message-modal';
import { map, catchError } from 'rxjs/operators'; import { map, catchError } from 'rxjs/operators';
@Injectable() @Injectable()
export class DomainGuard implements CanActivate { export class DomainGuard implements CanActivate {
constructor(private domainService: DomainService, private errorModalService: ErrorModalService) { } constructor(private domainService: DomainService, private generalModalService: GeneralModalService) { }
canActivate() { canActivate() {
return this.domainService.getDomains().pipe( return this.domainService.getDomains().pipe(
@ -16,7 +16,7 @@ export class DomainGuard implements CanActivate {
return true; return true;
}), }),
catchError(() => { catchError(() => {
this.errorModalService.triggerError(new ErrorModel( this.generalModalService.triggerMessage(new MessageModal(
'There was an error, please contact with your administrator', 'There was an error getting Domains')); 'There was an error, please contact with your administrator', 'There was an error getting Domains'));
return of(false) return of(false)
}) })

View File

@ -0,0 +1,40 @@
import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router } from '@angular/router';
import { Observable, of } from 'rxjs';
import { TaskanaEngineService } from 'app/services/taskana-engine/taskana-engine.service';
import { map, catchError } from 'rxjs/operators';
import { GeneralModalService } from 'app/services/general-modal/general-modal.service';
import { MessageModal } from 'app/models/message-modal';
@Injectable({
providedIn: 'root'
})
export class HistoryGuard implements CanActivate {
constructor(
private taskanaEngineService: TaskanaEngineService,
public router: Router,
public generalModalService: GeneralModalService) { }
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
return this.taskanaEngineService.isHistoryProviderEnabled().pipe(
map(value => {
if (value) {
return value;
}
return this.navigateToWorkplace();
}),
catchError(() => {
this.generalModalService.triggerMessage(new MessageModal(
'There was an error, please contact with your administrator', 'There was an error getting history provider'));
return of(this.navigateToWorkplace());
})
);
}
navigateToWorkplace(): boolean {
this.router.navigate(['workplace']);
return false;
}
}

View File

@ -1,12 +1,6 @@
import { Observable } from 'rxjs';
import { HttpClient } from '@angular/common/http';
import { CanActivate, Router } from '@angular/router'; import { CanActivate, Router } from '@angular/router';
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { DomainService } from 'app/services/domain/domain.service';
import { ErrorModalService } from 'app/services/errorModal/error-modal.service';
import { ErrorModel } from 'app/models/modal-error';
import { TaskanaEngineService } from 'app/services/taskana-engine/taskana-engine.service'; import { TaskanaEngineService } from 'app/services/taskana-engine/taskana-engine.service';
import { WindowRefService } from 'app/services/window/window.service';
@Injectable() @Injectable()
export class MonitorGuard implements CanActivate { export class MonitorGuard implements CanActivate {

View File

@ -0,0 +1,19 @@
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { TaskQueryComponent } from './task-query/task-query.component';
const routes: Routes = [
{
path: '',
component: TaskQueryComponent
},
{
path: '**',
redirectTo: ''
}];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class HistoryRoutingModule { }

View File

@ -0,0 +1,13 @@
import { HistoryModule } from './history.module';
describe('HistoryModule', () => {
let historyModule: HistoryModule;
beforeEach(() => {
historyModule = new HistoryModule();
});
it('should create an instance', () => {
expect(historyModule).toBeTruthy();
});
});

View File

@ -0,0 +1,19 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { HistoryRoutingModule } from './history-routing.module';
import { TaskQueryComponent } from './task-query/task-query.component';
import { SharedModule } from 'app/shared/shared.module';
@NgModule({
imports: [
CommonModule,
HistoryRoutingModule,
SharedModule,
FormsModule,
ReactiveFormsModule
],
declarations: [TaskQueryComponent]
})
export class HistoryModule { }

View File

@ -0,0 +1,15 @@
import { TestBed, inject } from '@angular/core/testing';
import { TaskQueryService } from './task-query.service';
describe('TaskQueryService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [TaskQueryService]
});
});
it('should be created', inject([TaskQueryService], (service: TaskQueryService) => {
expect(service).toBeTruthy();
}));
});

View File

@ -0,0 +1,124 @@
import { Injectable } from '@angular/core';
import { TaskHistoryEventData } from 'app/models/task-history-event';
import { TaskHistoryEventResourceData } from 'app/models/task-history-event-resource';
import { QueryParametersModel } from 'app/models/query-parameters';
import { TaskanaQueryParameters } from 'app/shared/util/query-parameters';
import { Direction } from 'app/models/sorting';
import { Observable, of } from 'rxjs';
import { HttpClient } from '@angular/common/http';
import { environment } from 'environments/environment';
@Injectable({
providedIn: 'root'
})
export class TaskQueryService {
private url = environment.taskanaRestUrl;
constructor(private httpClient: HttpClient) { }
queryTask(
orderBy: string = 'task-id',
sortDirection: string = Direction.ASC,
taskId: string,
parentBPI: string,
BPI: string,
eventType: string,
userId: string,
domain: string,
workbasketKey: string,
porCompany: string,
porSystem: string,
porInstance: string,
porType: string,
porValue: string,
taskClassificationKey: string,
taskClassificationCategory: string,
attachmentClassificationKey: string,
custom1: string,
custom2: string,
custom3: string,
custom4: string,
allPages: boolean = false
): Observable<TaskHistoryEventResourceData> {
return this.httpClient.get<TaskHistoryEventResourceData>(`${this.url}/v1/task-history-event${this.getQueryParameters(
orderBy,
sortDirection,
taskId,
parentBPI,
BPI,
eventType,
userId,
domain,
workbasketKey,
porCompany,
porSystem,
porInstance,
porType,
porValue,
taskClassificationKey,
taskClassificationCategory,
attachmentClassificationKey,
custom1,
custom2,
custom3,
custom4,
allPages
)}`);
}
private getQueryParameters(
orderBy: string,
sortDirection: string,
taskId: string,
parentBPI: string,
BPI: string,
eventType: string,
userId: string,
domain: string,
workbasketKey: string,
porCompany: string,
porSystem: string,
porInstance: string,
porType: string,
porValue: string,
taskClassificationKey: string,
taskClassificationCategory: string,
attachmentClassificationKey: string,
custom1: string,
custom2: string,
custom3: string,
custom4: string,
allPages: boolean = false): string {
const parameters = new QueryParametersModel();
parameters.SORTBY = orderBy
parameters.SORTDIRECTION = sortDirection;
parameters.TASK_ID_LIKE = taskId;
parameters.PARENT_BUSINESS_PROCESS_ID_LIKE = parentBPI;
parameters.BUSINESS_PROCESS_ID_LIKE = BPI;
parameters.EVENT_TYPE_LIKE = eventType;
parameters.USER_ID_LIKE = userId;
parameters.DOMAIN = domain;
parameters.WORKBASKETKEYLIKE = workbasketKey;
parameters.POR_COMPANY_LIKE = porCompany;
parameters.POR_SYSTEM_LIKE = porSystem;
parameters.POR_INSTANCE_LIKE = porInstance;
parameters.POR_TYPE_LIKE = porType;
parameters.POR_VALUE_LIKE = porValue;
parameters.TASK_CLASSIFICATION_KEY_LIKE = taskClassificationKey;
parameters.TASK_CLASSIFICATION_CATEGORY_LIKE = taskClassificationCategory;
parameters.ATTACHMENT_CLASSIFICATION_KEY_LIKE = attachmentClassificationKey;
parameters.CUSTOM_1_LIKE = custom1;
parameters.CUSTOM_2_LIKE = custom2;
parameters.CUSTOM_3_LIKE = custom3;
parameters.CUSTOM_4_LIKE = custom4;
if (allPages) { TaskanaQueryParameters.page = undefined; TaskanaQueryParameters.pageSize = undefined; }
return TaskanaQueryParameters.getQueryParameters(parameters);
}
}

View File

@ -0,0 +1,83 @@
<div class="panel panel-default">
<div class="panel-heading">
<div class="pull-right btn-group">
<button type="button" class="btn btn-default" data-toggle="tooltip" title="Query">
<span class="material-icons md-20 blue" (click)="search()">search</span>
</button>
<button type="button" class="btn btn-default" data-toggle="tooltip" title="Query">
<span class="material-icons md-20 blue" (click)="clear()">clear</span>
</button>
</div>
<h4 class="panel-header">Taskana history query</h4>
</div>
<div class="panel-body">
<div class="divTable table-striped">
<form [formGroup]="taskQueryForm">
<div class="divTableHeading">
<div class="divTableRow">
<ng-container *ngFor="let taskHeader of taskQueryHeader | mapToIterable">
<div class="divTableHeader" *ngIf="filterFieldsToShow(taskHeader.key) && !filterExpandGroup(taskHeader.key)"
(click)="changeOrderBy(taskHeader.key); search();">
<span class="icon-space">
{{getHeaderFieldDescription(taskHeader.key)}}
</span>
<span *ngIf="orderBy.sortBy === taskHeader.key" class="material-icons md-20 blue pull-right" [ngClass]="{'flip': orderBy.sortDirection === 'desc'}">sort</span>
</div>
<div class="divTableHeader divTableHeaderSeparator" [ngClass]="{'zoom-in': !toggleExpand, 'zoom-out': toggleExpand}"
*ngIf="taskHeader.key === 'custom1'" (click)="toggleExpand = !toggleExpand">
<span class="material-icons md-24 blue pull-right">{{toggleExpand? 'chevron_left' : 'chevron_right'}}</span>
</div>
<div class="divTableHeader" *ngIf="filterFieldsToShow(taskHeader.key) && filterExpandGroup(taskHeader.key) && toggleExpand"
(click)="changeOrderBy(taskHeader.key); search();">
<span class="icon-space">
{{getHeaderFieldDescription(taskHeader.key)}}
</span>
<span *ngIf="orderBy.sortBy === taskHeader.key && filterFieldsToAllowQuerying(taskHeader.key)" class="material-icons md-20 blue pull-right"
[ngClass]="{'flip': orderBy.sortDirection === 'desc'}">sort</span>
</div>
</ng-container>
</div>
<div class="divTableRow">
<ng-container *ngFor="let taskHeader of taskQueryHeader | mapToIterable">
<div class="divTableHeader" *ngIf="filterFieldsToShow(taskHeader.key) && !filterExpandGroup(taskHeader.key)">
<input type="text" (keyup.enter)="search()" class="form-control input-sm" placeholder="{{getHeaderFieldDescription(taskHeader.key)}}"
formControlName="{{taskHeader.key}}">
</div>
<div class="divTableHeader divTableHeaderSeparator" [ngClass]="{'zoom-in': !toggleExpand, 'zoom-out': toggleExpand}"
*ngIf="taskHeader.key === 'custom1'" (click)="toggleExpand = !toggleExpand">
</div>
<div class="divTableHeader" *ngIf="filterFieldsToShow(taskHeader.key) && filterExpandGroup(taskHeader.key) && toggleExpand">
<input *ngIf="filterFieldsToAllowQuerying(taskHeader.key)" type="text" formControlName="{{taskHeader.key}}"
(keyup.enter)="search()" class="form-control input-sm" placeholder="{{getHeaderFieldDescription(taskHeader.key)}}">
</div>
</ng-container>
</div>
</div>
<div class="divTableBody">
<div *ngFor="let task of taskQuery" class="divTableRow">
<ng-container *ngFor="let taskHeader of taskQueryHeader | mapToIterable">
<div class="divTableCell" *ngIf="filterFieldsToShow(taskHeader.key) && !filterExpandGroup(taskHeader.key)">
{{task[taskHeader.key]}}
</div>
<div class="divTableCell divTableCellSeparator" *ngIf="taskHeader.key === 'custom1'" [ngClass]="{'zoom-in': !toggleExpand, 'zoom-out': toggleExpand}"
(click)="toggleExpand = !toggleExpand">
</div>
<div class="divTableCell" *ngIf="filterFieldsToShow(taskHeader.key) && filterExpandGroup(taskHeader.key) && filterFieldsToAllowQuerying(taskHeader.key) && toggleExpand">
{{task[taskHeader.key]}}
</div>
<div class="divTableCell" *ngIf="!filterFieldsToAllowQuerying(taskHeader.key) && toggleExpand">
<button *ngIf="task[taskHeader.key]" type="button" class="btn btn-default btn-xs" (click)="openDetails(taskHeader.key, task[taskHeader.key])">
<span class="material-icons md-16 blue pull-right">open_in_new</span>
</button>
</div>
</ng-container>
</div>
</div>
</form>
</div>
<div class="divTablePagination" *ngIf="taskQueryResource">
<taskana-pagination [(page)]="taskQueryResource.page" [numberOfItems]="taskQuery.length" type="Entries"
(changePage)="changePage($event)"></taskana-pagination>
</div>
</div>
</div>

View File

@ -0,0 +1,28 @@
.divTable{
max-height: calc(100vh - 152px);
padding-right: 15px;
}
.divTableFoot {
display: block;
}
.divTableCell {
height: 34px;
max-height: 34px;
}
.btn-xs{
padding: 0px;
}
.divTable .btn {
border: none;
}
.icon-space{
margin-right: 20px;
}
.divTablePagination {
margin: 0 auto;
}

View File

@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { TaskQueryComponent } from './task-query.component';
describe('TaskQueryComponent', () => {
let component: TaskQueryComponent;
let fixture: ComponentFixture<TaskQueryComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ TaskQueryComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(TaskQueryComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,231 @@
import { Component, OnInit } from '@angular/core';
import { TaskQueryService } from '../services/task-query/task-query.service';
import { TaskHistoryEventData } from '../../models/task-history-event';
import { SortingModel, Direction } from 'app/models/sorting';
import { OrientationService } from 'app/services/orientation/orientation.service';
import { Subscription } from 'rxjs';
import { Orientation } from 'app/models/orientation';
import { TaskanaQueryParameters } from 'app/shared/util/query-parameters';
import { GeneralModalService } from 'app/services/general-modal/general-modal.service';
import { MessageModal } from 'app/models/message-modal';
import { FormGroup, FormControl } from '@angular/forms';
import { TaskHistoryEventResourceData } from 'app/models/task-history-event-resource';
import { RequestInProgressService } from 'app/services/requestInProgress/request-in-progress.service';
@Component({
selector: 'taskana-task-query',
templateUrl: './task-query.component.html',
styleUrls: ['./task-query.component.scss']
})
export class TaskQueryComponent implements OnInit {
taskQueryResource: TaskHistoryEventResourceData;
taskQuery: Array<TaskHistoryEventData>
taskQueryHeader = new TaskHistoryEventData();
orderBy = new SortingModel(TaskanaQueryParameters.parameters.WORKBASKET_KEY);
orientationSubscription: Subscription;
taskQuerySubscription: Subscription;
taskQueryForm = new FormGroup({
});
constructor(
private taskQueryService: TaskQueryService,
private orientationService: OrientationService,
private generalModalService: GeneralModalService,
private requestInProgressService: RequestInProgressService, ) { }
ngOnInit() {
this.orientationSubscription = this.orientationService.getOrientation().subscribe((orientation: Orientation) => {
this.performRequest();
});
this.initTaskQueryForm();
}
getHeaderFieldDescription(property: string): string {
switch (property) {
case 'parentBusinessProcessId':
return 'Parent BPI';
case 'businessProcessId':
return 'BPI';
case 'taskId':
return 'Task id';
case 'eventType':
return 'Event type';
case 'created':
return 'Created';
case 'userId':
return 'User id';
case 'domain':
return 'Domain';
case 'workbasketKey':
return 'Workbasket key';
case 'porCompany':
return 'Obj company';
case 'porSystem':
return 'Obj system';
case 'porInstance':
return 'Obj instance';
case 'porType':
return 'Obj type';
case 'porValue':
return 'Obj value';
case 'taskClassificationKey':
return 'Classification key';
case 'taskClassificationCategory':
return 'Classification category';
case 'attachmentClassificationKey':
return 'Attachment Classification';
case 'custom1':
return 'Custom 1';
case 'custom2':
return 'Custom 2';
case 'custom3':
return 'Custom 3';
case 'custom4':
return 'Custom 4';
case 'oldData':
return 'Old data';
case 'newData':
return 'New data';
case 'comment':
return 'Comment';
case 'oldValue':
return 'Old value';
case 'newValue':
return 'New value';
default:
return property;
}
}
filterFieldsToAllowQuerying(fieldName: string): boolean {
if (!fieldName || fieldName === 'oldData' || fieldName === 'newData' || fieldName === 'comment'
|| fieldName === 'oldValue' || fieldName === 'newValue') {
return false;
}
return true;
}
filterFieldsToShow(fieldName: string): boolean {
if (fieldName === 'taskHistoryId' || fieldName === 'page' || fieldName === 'created' || fieldName === '_links') {
return false;
}
return true;
}
filterExpandGroup(fieldName: string): boolean {
if (fieldName === 'custom1' || fieldName === 'custom2' || fieldName === 'custom3' || fieldName === 'custom4'
|| fieldName === 'oldData' || fieldName === 'newData' || fieldName === 'comment'
|| fieldName === 'oldValue' || fieldName === 'newValue') {
return true;
}
return false;
}
search() {
this.performRequest();
}
changeOrderBy(key: string) {
if (!this.filterFieldsToAllowQuerying(key)) {
return null;
}
if (this.orderBy.sortBy === key) {
this.orderBy.sortDirection = this.toggleSortDirection(this.orderBy.sortDirection);
}
this.orderBy.sortBy = key;
}
openDetails(key: string, val: string) {
this.generalModalService.triggerMessage(
new MessageModal(
`These are the details of ${this.getHeaderFieldDescription(key)}`,
val,
'code'
)
)
}
getTaskValue(key: string, task: TaskHistoryEventData): string {
return task[key];
}
clear() {
this.taskQueryForm.reset();
this.performRequest();
}
changePage(page) {
TaskanaQueryParameters.page = page;
this.performRequest();
}
private toggleSortDirection(sortDirection: string): Direction {
if (sortDirection === Direction.ASC) {
return Direction.DESC;
}
return Direction.ASC
}
private performRequest() {
setTimeout(() => this.requestInProgressService.setRequestInProgress(true), 1)
this.calculateQueryPages();
this.taskQuerySubscription = this.taskQueryService.queryTask(
this.orderBy.sortBy.replace(/([A-Z])|([0-9])/g, (g) => `-${g[0].toLowerCase()}`),
this.orderBy.sortDirection,
this.taskQueryForm.get('taskId') ? this.taskQueryForm.get('taskId').value : undefined,
this.taskQueryForm.get('parentBusinessProcessId') ? this.taskQueryForm.get('parentBusinessProcessId').value : undefined,
this.taskQueryForm.get('businessProcessId') ? this.taskQueryForm.get('businessProcessId').value : undefined,
this.taskQueryForm.get('eventType') ? this.taskQueryForm.get('eventType').value : undefined,
this.taskQueryForm.get('userId') ? this.taskQueryForm.get('userId').value : undefined,
this.taskQueryForm.get('domain') ? this.taskQueryForm.get('domain').value : undefined,
this.taskQueryForm.get('workbasketKey') ? this.taskQueryForm.get('workbasketKey').value : undefined,
this.taskQueryForm.get('porCompany') ? this.taskQueryForm.get('porCompany').value : undefined,
this.taskQueryForm.get('porSystem') ? this.taskQueryForm.get('porSystem').value : undefined,
this.taskQueryForm.get('porInstance') ? this.taskQueryForm.get('porInstance').value : undefined,
this.taskQueryForm.get('porType') ? this.taskQueryForm.get('porType').value : undefined,
this.taskQueryForm.get('porValue') ? this.taskQueryForm.get('porValue').value : undefined,
this.taskQueryForm.get('taskClassificationKey') ? this.taskQueryForm.get('taskClassificationKey').value : undefined,
this.taskQueryForm.get('taskClassificationCategory') ? this.taskQueryForm.get('taskClassificationCategory').value : undefined,
this.taskQueryForm.get('attachmentClassificationKey') ? this.taskQueryForm.get('attachmentClassificationKey').value : undefined,
this.taskQueryForm.get('custom1') ? this.taskQueryForm.get('custom1').value : undefined,
this.taskQueryForm.get('custom2') ? this.taskQueryForm.get('custom2').value : undefined,
this.taskQueryForm.get('custom3') ? this.taskQueryForm.get('custom3').value : undefined,
this.taskQueryForm.get('custom4') ? this.taskQueryForm.get('custom4').value : undefined,
false).subscribe(taskQueryResource => {
this.requestInProgressService.setRequestInProgress(false)
if (!taskQueryResource._embedded) {
this.taskQuery = null;
this.taskQueryResource = null;
return null;
}
this.taskQueryResource = taskQueryResource;
this.taskQuery = taskQueryResource._embedded.taskHistoryEventResourceList;
})
}
private initTaskQueryForm() {
const me = this;
Object.keys(new TaskHistoryEventData()).forEach(function (key) {
me.taskQueryForm.addControl(key, new FormControl());
});
}
private calculateQueryPages() {
const rowHeight = 34;
const unusedHeight = 300;
const totalHeight = window.innerHeight;
const cards = Math.round((totalHeight - (unusedHeight)) / rowHeight);
TaskanaQueryParameters.page ? TaskanaQueryParameters.page = TaskanaQueryParameters.page : TaskanaQueryParameters.page = 1;
cards > 0 ? TaskanaQueryParameters.pageSize = cards : TaskanaQueryParameters.pageSize = 1;
}
onDestroy() {
if (this.orientationSubscription) { this.orientationSubscription.unsubscribe(); }
if (this.taskQuerySubscription) { this.taskQuerySubscription.unsubscribe(); }
}
}

View File

@ -0,0 +1,7 @@
export class MessageModal {
constructor(
public title: string = undefined,
public message: any = undefined,
public type = 'error'
) { }
}

View File

@ -1,6 +0,0 @@
export class ErrorModel {
constructor(
public title: string = undefined,
public message: any = undefined
) { }
}

View File

@ -0,0 +1,50 @@
export class QueryParametersModel {
SORTBY: string;
SORTDIRECTION: string;
// Filtering
NAME: string;
NAMELIKE: string;
DESCLIKE: string;
OWNER: string;
OWNERLIKE: string;
TYPE: string;
KEY: string;
WORKBASKET_KEY: string;
KEYLIKE: string;
PRIORITY: string;
STATE: string;
WORKBASKET_ID: string;
TASK_PRIMARY_OBJ_REF_TYPE_LIKE: string;
TASK_PRIMARY_OBJ_REF_VALUE_LIKE: string;
// Access
REQUIREDPERMISSION: string;
ACCESSIDS: string;
ACCESSIDLIKE: string;
WORKBASKETKEYLIKE: string;
// Pagination
PAGE: string;
PAGESIZE: string;
// Domain
DOMAIN: string;
// Task history events
TASK_ID_LIKE: string;
PARENT_BUSINESS_PROCESS_ID_LIKE: string;
BUSINESS_PROCESS_ID_LIKE: string;
EVENT_TYPE_LIKE: string;
CREATED_LIKE: string;
USER_ID_LIKE: string;
POR_COMPANY_LIKE: string;
POR_SYSTEM_LIKE: string;
POR_INSTANCE_LIKE: string;
POR_TYPE_LIKE: string;
POR_VALUE_LIKE: string;
TASK_CLASSIFICATION_KEY_LIKE: string;
TASK_CLASSIFICATION_CATEGORY_LIKE: string;
ATTACHMENT_CLASSIFICATION_KEY_LIKE: string;
CUSTOM_1_LIKE: string;
CUSTOM_2_LIKE: string;
CUSTOM_3_LIKE: string;
CUSTOM_4_LIKE: string;
COMMENT_LIKE: string;
}

View File

@ -0,0 +1,7 @@
import { Links } from './links';
import { TaskHistoryEventData } from './task-history-event';
export class TaskHistoryEventResourceData {
public _embedded: { 'taskHistoryEventResourceList': Array<TaskHistoryEventData> }
public _links: Links = undefined
}

View File

@ -0,0 +1,31 @@
import { Page } from './page';
export class TaskHistoryEventData {
taskHistoryId = 0;
taskId = '';
parentBusinessProcessId = '';
businessProcessId = '';
eventType = '';
created = '';
userId = '';
domain = '';
workbasketKey = '';
porCompany = '';
porSystem = '';
porInstance = '';
porType = '';
porValue = '';
taskClassificationKey = '';
taskClassificationCategory = '';
attachmentClassificationKey = '';
custom1 = '';
custom2 = '';
custom3 = '';
custom4 = '';
comment = '';
oldValue = '';
newValue = '';
oldData = '';
newData = '';
page = new Page();
}

View File

@ -1,16 +1,17 @@
<div class="container"> <div>
<ul class="nav nav-tabs" role="tablist"> <ul class="nav nav-tabs" role="tablist">
<li> <li>
<a style="display: none"></a> <a style="display: none"></a>
</li> </li>
<li role="presentation" class="active"> <li (click)="selectTab('tasks')" role="presentation" class="active" [ngClass]="{'active':tabSelected === 'tasks'}">
<a href="#tasks-tab" data-toggle="tab" aria-controls="Tasks" role="tab" aria-expanded="true">Tasks</a> <a href="#tasks-tab" data-toggle="tab" aria-controls="Tasks" role="tab" aria-expanded="true">Tasks</a>
</li> </li>
<li role="presentation"> <li (click)="selectTab('workbaskets')" [ngClass]="{'active':tabSelected === 'workbaskets'}">
<a href="#workbaskets-tab" data-toggle="tab" aria-controls="Workbaskets" role="tab" aria-expanded="true">Workbaskets</a> <a href="#workbaskets-tab" data-toggle="tab" aria-controls="Workbaskets" role="tab" aria-expanded="true">Workbaskets</a>
</li> </li>
<li> <li (click)="selectTab('classifications')" [ngClass]="{'active':tabSelected === 'classifications'}">
<a href="#classifications-tab" data-toggle="tab" aria-controls="Classifications" role="tab" data-toggle="tab" aria-expanded="true">Classifications</a> <a href="#classifications-tab" data-toggle="tab" aria-controls="Classifications" role="tab" data-toggle="tab"
aria-expanded="true">Classifications</a>
</li> </li>
</ul> </ul>
<div class="tab-content"> <div class="tab-content">

View File

@ -8,8 +8,14 @@ import { Component, OnInit, HostListener, OnDestroy } from '@angular/core';
}) })
export class MonitorComponent implements OnInit, OnDestroy { export class MonitorComponent implements OnInit, OnDestroy {
tabSelected = 'tasks';
ngOnInit(): void { ngOnInit(): void {
} }
ngOnDestroy(): void { ngOnDestroy(): void {
} }
selectTab(tab) {
this.tabSelected = tab;
}
} }

View File

@ -2,8 +2,8 @@
<div class="panel-heading"> <div class="panel-heading">
<h4>{{reportData.meta.name}} ({{reportData.meta.date | date : 'dd.MM.yyyy HH:mm:ss'}})</h4> <h4>{{reportData.meta.name}} ({{reportData.meta.date | date : 'dd.MM.yyyy HH:mm:ss'}})</h4>
</div> </div>
<div class="panel-body col-xs-12 col-md-8 col-md-offset-2"> <div class="panel-body">
<div style="display: block"> <div style="display: block" class =" col-xs-12 col-md-7 col-md-offset-2">
<canvas baseChart [data]="pieChartData" [labels]="pieChartLabels" [chartType]="pieChartType"></canvas> <canvas baseChart [data]="pieChartData" [labels]="pieChartLabels" [chartType]="pieChartType"></canvas>
</div> </div>
<taskana-report [type]="reportType" [reportData]="reportData"></taskana-report> <taskana-report [type]="reportType" [reportData]="reportData"></taskana-report>

View File

@ -12,6 +12,7 @@ import { ClassificationCategoriesService } from './classification-categories.ser
import { DomainService } from 'app/services/domain/domain.service'; import { DomainService } from 'app/services/domain/domain.service';
import { TaskanaQueryParameters } from 'app/shared/util/query-parameters'; import { TaskanaQueryParameters } from 'app/shared/util/query-parameters';
import { Direction } from 'app/models/sorting'; import { Direction } from 'app/models/sorting';
import { QueryParametersModel } from 'app/models/query-parameters';
@Injectable() @Injectable()
export class ClassificationsService { export class ClassificationsService {
@ -27,35 +28,20 @@ export class ClassificationsService {
} }
// GET // GET
getClassifications(sortBy: string = TaskanaQueryParameters.KEY, getClassifications(): Observable<Array<Classification>> {
order: string = Direction.ASC,
name: string = undefined,
nameLike: string = undefined,
descLike: string = undefined,
owner: string = undefined,
ownerLike: string = undefined,
type: string = undefined,
key: string = undefined,
keyLike: string = undefined,
requiredPermission: string = undefined,
allPages: boolean = true): Observable<Array<Classification>> {
return this.domainService.getSelectedDomain().pipe( return this.domainService.getSelectedDomain().pipe(
mergeMap(domain => { mergeMap(domain => {
return this.getClassificationObservable(this.httpClient.get<ClassificationResource>( return this.getClassificationObservable(this.httpClient.get<ClassificationResource>(
`${environment.taskanaRestUrl}/v1/classifications/${TaskanaQueryParameters.getQueryParameters( `${this.url}${TaskanaQueryParameters.getQueryParameters(this.classificationParameters(domain))}`));
sortBy, order, name,
nameLike, descLike, owner, ownerLike, type, key, keyLike, requiredPermission,
!allPages ? TaskanaQueryParameters.page : undefined, !allPages ? TaskanaQueryParameters.pageSize : undefined, domain)}`));
}), }),
tap(() => { this.domainService.domainChangedComplete(); }) tap(() => { this.domainService.domainChangedComplete(); })
) )
} }
// GET // GET
getClassification(id: string): Observable<ClassificationDefinition> { getClassification(id: string): Observable<ClassificationDefinition> {
return this.httpClient.get<ClassificationDefinition>(`${environment.taskanaRestUrl}/v1/classifications/${id}`) return this.httpClient.get<ClassificationDefinition>(`${this.url}${id}`)
.pipe(tap((classification: ClassificationDefinition) => { .pipe(tap((classification: ClassificationDefinition) => {
if (classification) { if (classification) {
this.classificationCategoriesService.selectClassificationType(classification.type); this.classificationCategoriesService.selectClassificationType(classification.type);
@ -99,6 +85,18 @@ export class ClassificationsService {
// #endregion // #endregion
private classificationParameters(domain: string): QueryParametersModel {
const parameters = new QueryParametersModel();
parameters.SORTBY = TaskanaQueryParameters.parameters.KEY;
parameters.SORTDIRECTION = Direction.ASC;
parameters.DOMAIN = domain;
TaskanaQueryParameters.page = undefined;
TaskanaQueryParameters.pageSize = undefined;
return parameters;
}
private getClassificationObservable(classificationRef: Observable<any>): Observable<any> { private getClassificationObservable(classificationRef: Observable<any>): Observable<any> {
const classificationTypes = this.classificationCategoriesService.getSelectedClassificationType(); const classificationTypes = this.classificationCategoriesService.getSelectedClassificationType();
return combineLatest( return combineLatest(

View File

@ -1,19 +0,0 @@
import { Injectable } from '@angular/core';
import { Subject , Observable } from 'rxjs';
import { ErrorModel } from 'app/models/modal-error';
@Injectable()
export class ErrorModalService {
private errorTriggered = new Subject<ErrorModel>();
constructor() { }
triggerError(error: ErrorModel) {
this.errorTriggered.next(error);
}
getError(): Observable<ErrorModel> {
return this.errorTriggered.asObservable();
}
}

View File

@ -0,0 +1,19 @@
import { Injectable } from '@angular/core';
import { Subject , Observable } from 'rxjs';
import { MessageModal } from 'app/models/message-modal';
@Injectable()
export class GeneralModalService {
private messageTriggered = new Subject<MessageModal>();
constructor() { }
triggerMessage(message: MessageModal) {
this.messageTriggered.next(message);
}
getMessage(): Observable<MessageModal> {
return this.messageTriggered.asObservable();
}
}

View File

@ -7,7 +7,7 @@ export class SelectedRouteService {
public selectedRouteTriggered = new Subject<string>(); public selectedRouteTriggered = new Subject<string>();
private detailRoutes: Array<string> = ['workbaskets', 'classifications', 'monitor', 'workplace', 'access-items-management']; private detailRoutes: Array<string> = ['workbaskets', 'classifications', 'monitor', 'workplace', 'access-items-management', 'history'];
constructor(private router: Router) { } constructor(private router: Router) { }

View File

@ -34,6 +34,10 @@ export class TaskanaEngineServiceMock {
return of(version); return of(version);
} }
isHistoryProviderEnabled(): Observable<boolean> {
return of(true);
}
private findRole(roles2Find: Array<string>) { private findRole(roles2Find: Array<string>) {
return this.currentUserInfo.roles.find(role => { return this.currentUserInfo.roles.find(role => {
return roles2Find.some(roleLookingFor => { return roles2Find.some(roleLookingFor => {

View File

@ -44,6 +44,10 @@ export class TaskanaEngineService {
} }
isHistoryProviderEnabled(): Observable<boolean> {
return this.httpClient.get<boolean>(`${environment.taskanaRestUrl}/v1/history-provider-enabled`);
}
private findRole(roles2Find: Array<string>) { private findRole(roles2Find: Array<string>) {
return this.currentUserInfo.roles.find(role => { return this.currentUserInfo.roles.find(role => {
return roles2Find.some(roleLookingFor => { return roles2Find.some(roleLookingFor => {

View File

@ -13,6 +13,7 @@ import { DomainService } from 'app/services/domain/domain.service';
import { WorkbasketResource } from '../../models/workbasket-resource'; import { WorkbasketResource } from '../../models/workbasket-resource';
import { TaskanaQueryParameters } from 'app/shared/util/query-parameters'; import { TaskanaQueryParameters } from 'app/shared/util/query-parameters';
import { mergeMap, tap, catchError } from 'rxjs/operators'; import { mergeMap, tap, catchError } from 'rxjs/operators';
import { QueryParametersModel } from 'app/models/query-parameters';
@Injectable() @Injectable()
export class WorkbasketService { export class WorkbasketService {
@ -29,7 +30,7 @@ export class WorkbasketService {
// #region "REST calls" // #region "REST calls"
// GET // GET
getWorkBasketsSummary(forceRequest: boolean = false, getWorkBasketsSummary(forceRequest: boolean = false,
sortBy: string = TaskanaQueryParameters.KEY, sortBy: string = TaskanaQueryParameters.parameters.KEY,
order: string = Direction.ASC, order: string = Direction.ASC,
name: string = undefined, name: string = undefined,
nameLike: string = undefined, nameLike: string = undefined,
@ -46,12 +47,11 @@ export class WorkbasketService {
return this.workbasketSummaryRef; return this.workbasketSummaryRef;
} }
return this.domainService.getSelectedDomain().pipe(mergeMap(domain => { return this.domainService.getSelectedDomain().pipe(mergeMap(domain => {
return this.workbasketSummaryRef = this.httpClient.get<WorkbasketSummaryResource>( return this.workbasketSummaryRef = this.httpClient.get<WorkbasketSummaryResource>(
`${environment.taskanaRestUrl}/v1/workbaskets/${TaskanaQueryParameters.getQueryParameters( `${environment.taskanaRestUrl}/v1/workbaskets/${TaskanaQueryParameters.getQueryParameters(this.workbasketParameters(sortBy, order, name,
sortBy, order, name, nameLike, descLike, owner, ownerLike, type, key, keyLike, requiredPermission, allPages, domain))}`)
nameLike, descLike, owner, ownerLike, type, key, keyLike, requiredPermission,
!allPages ? TaskanaQueryParameters.page : undefined, !allPages ? TaskanaQueryParameters.pageSize : undefined, domain)}`)
.pipe(tap((workbaskets => { .pipe(tap((workbaskets => {
return workbaskets; return workbaskets;
}))) })))
@ -152,5 +152,41 @@ export class WorkbasketService {
return observableThrowError(errMsg); return observableThrowError(errMsg);
} }
private workbasketParameters(
sortBy: string = TaskanaQueryParameters.parameters.KEY,
order: string = Direction.ASC,
name: string = undefined,
nameLike: string = undefined,
descLike: string = undefined,
owner: string = undefined,
ownerLike: string = undefined,
type: string = undefined,
key: string = undefined,
keyLike: string = undefined,
requiredPermission: string = undefined,
allPages: boolean = false,
domain: string = ''): QueryParametersModel {
const parameters = new QueryParametersModel();
parameters.SORTBY = sortBy;
parameters.SORTDIRECTION = order;
parameters.NAME = name;
parameters.NAMELIKE = nameLike;
parameters.DESCLIKE = descLike;
parameters.OWNER = owner;
parameters.OWNERLIKE = ownerLike;
parameters.TYPE = type;
parameters.KEY = key;
parameters.KEYLIKE = keyLike;
parameters.REQUIREDPERMISSION = requiredPermission;
parameters.DOMAIN = domain;
if (allPages) {
TaskanaQueryParameters.page = undefined;
TaskanaQueryParameters.pageSize = undefined;
}
return parameters;
}
// #endregion // #endregion
} }

View File

@ -16,12 +16,12 @@
</ul> </ul>
</div> </div>
<div class="col-xs-4"> <div class="col-xs-4">
<input type="text" [(ngModel)]="filter.filterParams.name" (keyup.enter)="search()" class="form-control input-sm" id="display-name-filter" <input type="text" [(ngModel)]="filter.filterParams.name" (keyup.enter)="search()" class="form-control input-sm"
placeholder="Filter name"> id="display-name-filter" placeholder="Filter name">
</div> </div>
<div class="col-xs-4"> <div class="col-xs-4">
<input type="text" [(ngModel)]="filter.filterParams.key" (keyup.enter)="search()" class="form-control input-sm" id="display-key-filter" <input type="text" [(ngModel)]="filter.filterParams.key" (keyup.enter)="search()" class="form-control input-sm"
placeholder="Filter key"> id="display-key-filter" placeholder="Filter key">
</div> </div>
<button (click)="clear(); search()" type="button" class="btn btn-default btn-sm pull-right margin-right" <button (click)="clear(); search()" type="button" class="btn btn-default btn-sm pull-right margin-right"
data-toggle="tooltip" title="Clear"> data-toggle="tooltip" title="Clear">
@ -36,8 +36,8 @@
</div> </div>
<div class="row"> <div class="row">
<div class="col-xs-8 col-xs-offset-2"> <div class="col-xs-8 col-xs-offset-2">
<input type="text" [(ngModel)]="filter.filterParams.owner" (keyup.enter)="search()" class="form-control input-sm" id="display-name-owner" <input type="text" [(ngModel)]="filter.filterParams.owner" (keyup.enter)="search()" class="form-control input-sm"
placeholder="Filter owner"> id="display-name-owner" placeholder="Filter owner">
</div> </div>
<button (click)="search()" type="button" class="btn btn-default btn-sm pull-right margin-right" data-toggle="tooltip" <button (click)="search()" type="button" class="btn btn-default btn-sm pull-right margin-right" data-toggle="tooltip"
title="Search"> title="Search">
@ -48,8 +48,7 @@
<ng-template #tasktype> <ng-template #tasktype>
<div class="row"> <div class="row">
<div class="col-xs-2"> <div class="col-xs-2">
<input type="text" [(ngModel)]="filter.filterParams.priority" (keyup.enter)="search()" data-toggle="tooltip" <taskana-number-picker [(ngModel)]="filter.filterParams.priority" (keyup.enter)="search()" title="priority" id="display-priority-filter"></taskana-number-picker>
title="priority" class="form-control" id="display-priority-filter">
</div> </div>
<div class="col-xs-4"> <div class="col-xs-4">
<input type="text" [(ngModel)]="filter.filterParams.name" (keyup.enter)="search()" class="form-control" id="display-name-filter" <input type="text" [(ngModel)]="filter.filterParams.name" (keyup.enter)="search()" class="form-control" id="display-name-filter"
@ -66,8 +65,8 @@
</div> </div>
<div class="row"> <div class="row">
<div class="dropdown col-xs-2 col-xs-offset-2"> <div class="dropdown col-xs-2 col-xs-offset-2">
<button class="btn btn-default" data-toggle="dropdown" type="button" data-toggle="dropdown" <button class="btn btn-default" data-toggle="dropdown" type="button" data-toggle="dropdown" aria-haspopup="true"
aria-haspopup="true" aria-expanded="true" title="State: {{filter.filterParams.state ? filter.filterParams?.state : 'All'}}"> aria-expanded="true" title="State: {{filter.filterParams.state ? filter.filterParams?.state : 'All'}}">
<span>{{filter.filterParams.state ? filter.filterParams?.state : 'All'}}</span> <span>{{filter.filterParams.state ? filter.filterParams?.state : 'All'}}</span>
</button> </button>
<ul class="dropdown-menu dropdown-menu-users" role="menu"> <ul class="dropdown-menu dropdown-menu-users" role="menu">

View File

@ -1,16 +1,20 @@
<div class="modal fade" #generalModal tabindex="-1" data-backdrop="static" data-keyboard="false" role="dialog" aria-labelledby="generalModalLabel"> <div class="modal fade" #generalModal tabindex="-1" data-backdrop="static" data-keyboard="false" role="dialog"
aria-labelledby="generalModalLabel">
<div class="modal-dialog" role="document"> <div class="modal-dialog" role="document">
<div class="modal-content word-break"> <div class="modal-content word-break">
<div class="modal-header"> <div class="modal-header">
<h4 class="modal-title" id="generalModalLabel">{{title}}</h4> <h4 class="modal-title" id="generalModalLabel">{{title}}</h4>
</div> </div>
<div *ngIf="error" class="modal-body"> <div *ngIf="type === 'error'" class="modal-body">
<div class="alert alert-danger" role="alert"> <div class="alert alert-danger" role="alert">
<span data-toggle="tooltip" class="material-icons md-20">error</span> <span data-toggle="tooltip" class="material-icons md-20">error</span>
<span class="sr-only">Error:</span> <span class="sr-only">Error:</span>
{{message}} {{message}}
</div> </div>
</div> </div>
<div *ngIf="type === 'code'">
<pre><code>{{message}}</code></pre>
</div>
<div class="modal-footer"> <div class="modal-footer">
<button type="button" class="btn btn-default btn-danger" data-dismiss="modal" (click)="removeMessage()">Close</button> <button type="button" class="btn btn-default btn-danger" data-dismiss="modal" (click)="removeMessage()">Close</button>
</div> </div>

View File

@ -1,5 +1,5 @@
import { Component, Input, ViewChild, OnChanges, SimpleChanges, Output, EventEmitter } from '@angular/core'; import { Component, Input, ViewChild, OnChanges, SimpleChanges, Output, EventEmitter } from '@angular/core';
declare var $: any; declare var $: any; // jquery
@Component({ @Component({
selector: 'taskana-general-message-modal', selector: 'taskana-general-message-modal',
@ -12,10 +12,10 @@ export class GeneralMessageModalComponent implements OnChanges {
@Output() messageChange = new EventEmitter<string>(); @Output() messageChange = new EventEmitter<string>();
@Input() @Input()
title = ''; title: string;
@Input() @Input()
error = false; type: string;
@ViewChild('generalModal') @ViewChild('generalModal')
private modal; private modal;

View File

@ -0,0 +1,11 @@
<div class="input-group">
<input class="form-control input-text" name="number" [(ngModel)]="value">
<div class="input-group-btn-vertical">
<button type="button" (click)="increase()" data-toggle="tooltip" title="increase value" class="btn btn-default">
<span class="material-icons md-14 green-blue">arrow_drop_up</span>
</button>
<button type="button" (click)="decrease()" data-toggle="tooltip" title="decrease value" class="btn btn-default">
<span class="material-icons md-14 green-blue">arrow_drop_down</span>
</button>
</div>
</div>

View File

@ -0,0 +1,35 @@
button{
font-size: 1px;
padding: 0px;
}
.input-group{
max-width: 100px;
}
input{
text-align: right;
}
.input-group-btn-vertical {
position: relative;
white-space: nowrap;
vertical-align: middle;
display: table-cell;
}
.input-group-btn-vertical > .btn {
display: block;
float: none;
width: 100%;
max-width: 100%;
padding: 1px;
margin-left: -1px;
position: relative;
border-radius: 0;
}
.input-group-btn-vertical > .btn:first-child {
border-top-right-radius: 4px;
}
.input-group-btn-vertical > .btn:last-child {
margin-top: -3px;
border-bottom-right-radius: 4px;
}

View File

@ -0,0 +1,30 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { NumberPickerComponent } from './number-picker.component';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
describe('NumberPickerComponent', () => {
let component: NumberPickerComponent;
let fixture: ComponentFixture<NumberPickerComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [
NumberPickerComponent],
imports: [
FormsModule,
ReactiveFormsModule
]
})
.compileComponents();
fixture = TestBed.createComponent(NumberPickerComponent);
component = fixture.componentInstance;
fixture.detectChanges();
}));
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,68 @@
import { Component, OnInit, forwardRef } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
@Component({
selector: 'taskana-number-picker',
templateUrl: './number-picker.component.html',
styleUrls: ['./number-picker.component.scss'],
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => NumberPickerComponent),
multi: true
}
]
})
export class NumberPickerComponent implements OnInit, ControlValueAccessor {
// The internal data model
private innerValue: any = 0;
// Placeholders for the callbacks which are later provided
// by the Control Value Accessor
private onTouchedCallback: () => {};
private onChangeCallback: (_: any) => {};
// get accessor
get value(): any {
return this.innerValue;
};
// set accessor including call the onchange callback
set value(v: any) {
if (v !== this.innerValue) {
this.innerValue = v;
this.onChangeCallback(v);
}
}
// From ControlValueAccessor interface
writeValue(value: any) {
if (value !== this.innerValue) {
this.innerValue = value;
}
}
// From ControlValueAccessor interface
registerOnChange(fn: any) {
this.onChangeCallback = fn;
}
// From ControlValueAccessor interface
registerOnTouched(fn: any) {
this.onTouchedCallback = fn;
}
constructor() {
}
ngOnInit() {
}
increase() {
this.value++;
}
decrease() {
this.value--;
}
}

View File

@ -32,7 +32,7 @@ export class PaginationComponent implements OnChanges {
constructor() {} constructor() {}
ngOnChanges(changes: SimpleChanges): void { ngOnChanges(changes: SimpleChanges): void {
if (changes.page && changes.page.currentValue !== undefined) { if (changes.page && changes.page.currentValue) {
this.pageSelected = changes.page.currentValue.number; this.pageSelected = changes.page.currentValue.number;
} }
} }

View File

@ -6,6 +6,7 @@ import { Observable, of } from 'rxjs';
import { AccessItemsWorkbasketResource } from 'app/models/access-item-workbasket-resource'; import { AccessItemsWorkbasketResource } from 'app/models/access-item-workbasket-resource';
import { TaskanaQueryParameters } from 'app/shared/util/query-parameters'; import { TaskanaQueryParameters } from 'app/shared/util/query-parameters';
import { SortingModel } from 'app/models/sorting'; import { SortingModel } from 'app/models/sorting';
import { QueryParametersModel } from 'app/models/query-parameters';
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root'
@ -40,17 +41,33 @@ export class AccessIdsService {
} }
return this.accessItemsRef = this.httpClient.get<AccessItemsWorkbasketResource>(encodeURI( return this.accessItemsRef = this.httpClient.get<AccessItemsWorkbasketResource>(encodeURI(
`${environment.taskanaRestUrl}/v1/workbasket-access-items/${TaskanaQueryParameters.getQueryParameters(sortModel.sortBy, `${environment.taskanaRestUrl}/v1/workbasket-access-items/${TaskanaQueryParameters.getQueryParameters(
sortModel.sortDirection, this.accessIdsParameters(sortModel,
undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, accessIds,
accessIds.map((values: AccessIdDefinition) => { accessIdLike, workbasketKeyLike))}`))
return values.accessId
}).join('|'),
accessIdLike, workbasketKeyLike)}`))
} }
removeAccessItemsPermissions(accessId: string) { removeAccessItemsPermissions(accessId: string) {
return this.httpClient return this.httpClient
.delete<AccessItemsWorkbasketResource>(`${environment.taskanaRestUrl}/v1/workbasket-access-items/?access-id=` + accessId) .delete<AccessItemsWorkbasketResource>(`${environment.taskanaRestUrl}/v1/workbasket-access-items/?access-id=` + accessId)
} }
private accessIdsParameters(
sortModel: SortingModel,
accessIds: Array<AccessIdDefinition>,
accessIdLike: string = undefined,
workbasketKeyLike: string = undefined): QueryParametersModel {
const parameters = new QueryParametersModel();
parameters.SORTBY = sortModel.sortBy;
parameters.SORTDIRECTION = sortModel.sortDirection;
parameters.ACCESSIDS = accessIds.map((values: AccessIdDefinition) => {
return values.accessId
}).join('|');
parameters.ACCESSIDLIKE = accessIdLike;
parameters.WORKBASKETKEYLIKE = workbasketKeyLike;
TaskanaQueryParameters.page = undefined;
TaskanaQueryParameters.pageSize = undefined;
return parameters;
}
} }

View File

@ -2,14 +2,14 @@ import { TestBed, inject } from '@angular/core/testing';
import { HttpClientModule } from '@angular/common/http'; import { HttpClientModule } from '@angular/common/http';
import { HttpClientInterceptor } from './http-client-interceptor.service'; import { HttpClientInterceptor } from './http-client-interceptor.service';
import { ErrorModalService } from 'app/services/errorModal/error-modal.service'; import { GeneralModalService } from 'app/services/general-modal/general-modal.service';
import { RequestInProgressService } from 'app/services/requestInProgress/request-in-progress.service'; import { RequestInProgressService } from 'app/services/requestInProgress/request-in-progress.service';
describe('HttpExtensionService', () => { describe('HttpExtensionService', () => {
beforeEach(() => { beforeEach(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
imports: [HttpClientModule], imports: [HttpClientModule],
providers: [HttpClientInterceptor, ErrorModalService, RequestInProgressService] providers: [HttpClientInterceptor, GeneralModalService, RequestInProgressService]
}); });
}); });

View File

@ -2,9 +2,9 @@ import { Injectable } from '@angular/core';
import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest, HttpErrorResponse } from '@angular/common/http'; import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest, HttpErrorResponse } from '@angular/common/http';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { ErrorModel } from 'app/models/modal-error'; import { MessageModal } from 'app/models/message-modal';
import { ErrorModalService } from 'app/services/errorModal/error-modal.service'; import { GeneralModalService } from 'app/services/general-modal/general-modal.service';
import { RequestInProgressService } from 'app/services/requestInProgress/request-in-progress.service'; import { RequestInProgressService } from 'app/services/requestInProgress/request-in-progress.service';
import { environment } from 'environments/environment'; import { environment } from 'environments/environment';
import { tap } from 'rxjs/operators'; import { tap } from 'rxjs/operators';
@ -13,7 +13,7 @@ import { tap } from 'rxjs/operators';
export class HttpClientInterceptor implements HttpInterceptor { export class HttpClientInterceptor implements HttpInterceptor {
constructor( constructor(
private errorModalService: ErrorModalService, private generalModalService: GeneralModalService,
private requestInProgressService: RequestInProgressService) { private requestInProgressService: RequestInProgressService) {
} }
@ -26,13 +26,13 @@ export class HttpClientInterceptor implements HttpInterceptor {
return next.handle(req).pipe(tap(() => { }, error => { return next.handle(req).pipe(tap(() => { }, error => {
this.requestInProgressService.setRequestInProgress(false); this.requestInProgressService.setRequestInProgress(false);
if (error instanceof HttpErrorResponse && (error.status === 401 || error.status === 403)) { if (error instanceof HttpErrorResponse && (error.status === 401 || error.status === 403)) {
this.errorModalService.triggerError( this.generalModalService.triggerMessage(
new ErrorModel('You have no access to this resource ', error)); new MessageModal('You have no access to this resource ', error));
} else if (error instanceof HttpErrorResponse && (error.status === 404) && error.url.indexOf('environment-information.json')) { } else if (error instanceof HttpErrorResponse && (error.status === 404) && error.url.indexOf('environment-information.json')) {
// ignore this error message // ignore this error message
} else { } else {
this.errorModalService.triggerError( this.generalModalService.triggerMessage(
new ErrorModel('There was error, please contact with your administrator ', error)) new MessageModal('There was error, please contact with your administrator ', error))
} }
})) }))
} }

View File

@ -23,6 +23,7 @@ import { FilterComponent } from 'app/shared/filter/filter.component';
import { IconTypeComponent } from 'app/administration/components/type-icon/icon-type.component'; import { IconTypeComponent } from 'app/administration/components/type-icon/icon-type.component';
import { FieldErrorDisplayComponent } from 'app/shared/field-error-display/field-error-display.component'; import { FieldErrorDisplayComponent } from 'app/shared/field-error-display/field-error-display.component';
import { PaginationComponent } from './pagination/pagination.component'; import { PaginationComponent } from './pagination/pagination.component';
import { NumberPickerComponent } from './number-picker/number-picker.component';
import { ProgressBarComponent } from './progress-bar/progress-bar.component'; import { ProgressBarComponent } from './progress-bar/progress-bar.component';
import { DatePickerComponent } from './date-picker/date-picker.component'; import { DatePickerComponent } from './date-picker/date-picker.component';
@ -76,6 +77,7 @@ const DECLARATIONS = [
RemoveConfirmationComponent, RemoveConfirmationComponent,
FieldErrorDisplayComponent, FieldErrorDisplayComponent,
PaginationComponent, PaginationComponent,
NumberPickerComponent,
ProgressBarComponent, ProgressBarComponent,
DatePickerComponent DatePickerComponent
]; ];

View File

@ -1,7 +1,7 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { SpinnerComponent } from './spinner.component'; import { SpinnerComponent } from './spinner.component';
import { ErrorModalService } from 'app/services/errorModal/error-modal.service'; import { GeneralModalService } from 'app/services/general-modal/general-modal.service';
describe('SpinnerComponent', () => { describe('SpinnerComponent', () => {
let component: SpinnerComponent; let component: SpinnerComponent;
@ -10,7 +10,7 @@ describe('SpinnerComponent', () => {
beforeEach(async(() => { beforeEach(async(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
declarations: [SpinnerComponent], declarations: [SpinnerComponent],
providers: [ErrorModalService] providers: [GeneralModalService]
}) })
.compileComponents(); .compileComponents();
})); }));

View File

@ -1,9 +1,9 @@
import { Component, Input, Output, EventEmitter, OnDestroy } from '@angular/core'; import { Component, Input, Output, EventEmitter, OnDestroy } from '@angular/core';
import { ViewChild } from '@angular/core'; import { ViewChild } from '@angular/core';
import { ErrorModel } from 'app/models/modal-error'; import { MessageModal } from 'app/models/message-modal';
import { ErrorModalService } from 'app/services/errorModal/error-modal.service'; import { GeneralModalService } from 'app/services/general-modal/general-modal.service';
declare var $: any; declare var $: any;
@Component({ @Component({
@ -53,7 +53,7 @@ export class SpinnerComponent implements OnDestroy {
@ViewChild('spinnerModal') @ViewChild('spinnerModal')
private modal; private modal;
constructor(private errorModalService: ErrorModalService) { constructor(private generalModalService: GeneralModalService) {
} }
@ -63,8 +63,8 @@ export class SpinnerComponent implements OnDestroy {
this.isDelayedRunning = value; this.isDelayedRunning = value;
this.cancelTimeout(); this.cancelTimeout();
this.requestTimeout = setTimeout(() => { this.requestTimeout = setTimeout(() => {
this.errorModalService.triggerError( this.generalModalService.triggerMessage(
new ErrorModel('There was an error with your request, please make sure you have internet connection', new MessageModal('There was an error with your request, please make sure you have internet connection',
'Request time execeed')); 'Request time execeed'));
this.cancelTimeout(); this.cancelTimeout();
this.isRunning = false; this.isRunning = false;

View File

@ -1,19 +1,33 @@
import { TaskanaQueryParameters } from './query-parameters'; import { TaskanaQueryParameters } from './query-parameters';
import { Direction } from 'app/models/sorting'; import { Direction } from 'app/models/sorting';
import { QueryParametersModel } from 'app/models/query-parameters';
describe('TaskanaQueryParameters', () => { describe('TaskanaQueryParameters', () => {
it('should create a empty query', () => { it('should create a empty query', () => {
expect(TaskanaQueryParameters.getQueryParameters()).toBe(''); TaskanaQueryParameters.page = undefined;
TaskanaQueryParameters.pageSize = undefined;
expect(TaskanaQueryParameters.getQueryParameters(new QueryParametersModel())).toBe('?');
TaskanaQueryParameters.page = 1;
TaskanaQueryParameters.pageSize = 9;
});
it('should create a query with pagin information', () => {
expect(TaskanaQueryParameters.getQueryParameters(new QueryParametersModel())).toBe('?page=1&page-size=9');
}); });
it('should create a query separated with &', () => { it('should create a query separated with &', () => {
expect(TaskanaQueryParameters.getQueryParameters(TaskanaQueryParameters.KEY,
Direction.ASC).split('&').length).toBe(2); const parameters = new QueryParametersModel();
parameters.SORTBY = TaskanaQueryParameters.parameters.KEY;
parameters.SORTDIRECTION = Direction.ASC;
expect(TaskanaQueryParameters.getQueryParameters(parameters).split('&').length).toBe(4);
}); });
it('should remove last & from query', () => { it('should remove last & from query', () => {
expect(TaskanaQueryParameters.getQueryParameters(TaskanaQueryParameters.KEY, const parameters = new QueryParametersModel();
Direction.ASC).endsWith('?')).toBeFalsy(); parameters.SORTBY = TaskanaQueryParameters.parameters.KEY;
parameters.SORTDIRECTION = Direction.ASC;
expect(TaskanaQueryParameters.getQueryParameters(parameters).endsWith('?')).toBeFalsy();
}); });
}); });

View File

@ -1,94 +1,80 @@
import { QueryParametersModel } from 'app/models/query-parameters';
export class TaskanaQueryParameters { export class TaskanaQueryParameters {
static parameters = {
// Sorting // Sorting
static SORTBY = 'sort-by'; SORTBY: 'sort-by',
static ORDER = 'order'; SORTDIRECTION: 'order',
// Filtering // Filtering
static NAME = 'name'; NAME: 'name',
static NAMELIKE = 'name-like'; NAMELIKE: 'name-like',
static DESCLIKE = 'description-like'; DESCLIKE: 'description-like',
static OWNER = 'owner'; OWNER: 'owner',
static OWNERLIKE = 'owner-like'; OWNERLIKE: 'owner-like',
static TYPE = 'type'; TYPE: 'type',
static KEY = 'key'; KEY: 'key',
static WORKBASKET_KEY = 'workbasket-key'; WORKBASKET_KEY: 'workbasket-key',
static KEYLIKE = 'key-like'; KEYLIKE: 'key-like',
static PRIORITY = 'priority'; PRIORITY: 'priority',
static STATE = 'state'; STATE: 'state',
static WORKBASKET_ID = 'workbasket-id'; WORKBASKET_ID: 'workbasket-id',
static TASK_PRIMARY_OBJ_REF_TYPE_LIKE = 'por.type'; TASK_PRIMARY_OBJ_REF_TYPE_LIKE: 'por.type',
static TASK_PRIMARY_OBJ_REF_VALUE_LIKE = 'por.value'; TASK_PRIMARY_OBJ_REF_VALUE_LIKE: 'por.value',
// Access // Access
static REQUIREDPERMISSION = 'required-permission'; REQUIREDPERMISSION: 'required-permission',
static ACCESSIDS = 'access-ids'; ACCESSIDS: 'access-ids',
static ACCESSIDLIKE = 'access-id-like'; ACCESSIDLIKE: 'access-id-like',
static WORKBASKETKEYLIKE = 'workbasket-key-like'; WORKBASKETKEYLIKE: 'workbasket-key-like',
// Pagination // Pagination
static PAGE = 'page'; PAGE: 'page',
static PAGESIZE = 'page-size'; PAGESIZE: 'page-size',
// Domain
DOMAIN: 'domain',
// Task history events
TASK_ID_LIKE: 'task-id-like',
PARENT_BUSINESS_PROCESS_ID_LIKE: 'parent-business-process-id-like',
BUSINESS_PROCESS_ID_LIKE: 'business-process-id-like',
EVENT_TYPE_LIKE: 'event-type-like',
CREATED_LIKE: 'created-like',
USER_ID_LIKE: 'user-id-like',
POR_COMPANY_LIKE: 'por-company-like',
POR_SYSTEM_LIKE: 'por-system-like',
POR_INSTANCE_LIKE: 'por-instance-like',
POR_TYPE_LIKE: 'por-type-like',
POR_VALUE_LIKE: 'por-value-like',
TASK_CLASSIFICATION_KEY_LIKE: 'task-classification-key-like',
TASK_CLASSIFICATION_CATEGORY_LIKE: 'task-classification-category-like',
ATTACHMENT_CLASSIFICATION_KEY_LIKE: 'attachment-classification-key-like',
CUSTOM_1_LIKE: 'custom-1-like',
CUSTOM_2_LIKE: 'custom-2-like',
CUSTOM_3_LIKE: 'custom-3-like',
CUSTOM_4_LIKE: 'custom-4-like',
COMMENT_LIKE: 'comment-like'
}
static page = 1; static page = 1;
static pageSize = 9; static pageSize = 9;
// Domain public static getQueryParameters(queryParametersModel: QueryParametersModel): string {
static DOMAIN = 'domain';
public static getQueryParameters(
sortBy: string = undefined,
order: string = undefined,
name: string = undefined,
nameLike: string = undefined,
descLike: string = undefined,
owner: string = undefined,
ownerLike: string = undefined,
type: string = undefined,
key: string = undefined,
keyLike: string = undefined,
requiredPermission: string = undefined,
page: number = undefined,
pageSize: number = undefined,
domain: string = undefined,
accessIds: string = undefined,
accessIdLike: string = undefined,
workbasketKeyLike: string = undefined,
basketId: string = undefined,
priority: string = undefined,
state: string = undefined,
objRefTypeLike: string = undefined,
objRefValueLike: string = undefined
): string {
let query = '?'; let query = '?';
query += sortBy ? `${this.SORTBY}=${sortBy}&` : '';
query += order ? `${this.ORDER}=${order}&` : '';
query += name ? `${this.NAME}=${name}&` : '';
query += nameLike ? `${this.NAMELIKE}=${nameLike}&` : '';
query += descLike ? `${this.DESCLIKE}=${descLike}&` : '';
query += owner ? `${this.OWNER}=${owner}&` : '';
query += ownerLike ? `${this.OWNERLIKE}=${ownerLike}&` : '';
query += basketId ? `${this.WORKBASKET_ID}=${basketId}&` : '';
query += priority ? `${this.PRIORITY}=${priority}&` : '';
query += state ? `${this.STATE}=${state}&` : '';
query += type ? `${this.TYPE}=${type}&` : '';
query += key ? `${this.KEY}=${key}&` : '';
query += keyLike ? `${this.KEYLIKE}=${keyLike}&` : '';
query += requiredPermission
? `${this.REQUIREDPERMISSION}=${requiredPermission}&`
: '';
query += page ? `${this.PAGE}=${page}&` : '';
query += pageSize ? `${this.PAGESIZE}=${pageSize}&` : '';
query += domain ? `${this.DOMAIN}=${domain}&` : '';
query += accessIds ? `${this.ACCESSIDS}=${accessIds}&` : '';
query += accessIdLike ? `${this.ACCESSIDLIKE}=${accessIdLike}&` : '';
query += workbasketKeyLike
? `${this.WORKBASKETKEYLIKE}=${workbasketKeyLike}&`
: '';
query += objRefTypeLike ? `${this.TASK_PRIMARY_OBJ_REF_TYPE_LIKE}=${objRefTypeLike}&` : '';
query += objRefValueLike ? `${this.TASK_PRIMARY_OBJ_REF_VALUE_LIKE}=${objRefValueLike}&` : '';
Object.keys(queryParametersModel).forEach(function (key) {
const value = queryParametersModel[key];
query += value ? `${TaskanaQueryParameters.parameters[key]}=${value}&` : '';
});
query += this.page ? `${TaskanaQueryParameters.parameters.PAGE}=${this.page}&` : '';
query += this.pageSize ? `${TaskanaQueryParameters.parameters.PAGESIZE}=${this.pageSize}&` : '';
query = TaskanaQueryParameters.removeLastChar(query);
return query;
}
private static removeLastChar(query: string): string {
if (query.lastIndexOf('&') === query.length - 1) { if (query.lastIndexOf('&') === query.length - 1) {
query = query.slice(0, query.lastIndexOf('&')); query = query.slice(0, query.lastIndexOf('&'));
} }
return query === '?' ? '' : query; return query
} }
} }

View File

@ -1,13 +1,14 @@
import {Task} from 'app/workplace/models/task'; import { Task } from 'app/workplace/models/task';
import {Observable, Subject} from 'rxjs'; import { Observable, Subject } from 'rxjs';
import {HttpClient} from '@angular/common/http'; import { HttpClient } from '@angular/common/http';
import {Injectable} from '@angular/core'; import { Injectable } from '@angular/core';
import {environment} from 'environments/environment'; import { environment } from 'environments/environment';
import {TaskResource} from 'app/workplace/models/task-resource'; import { TaskResource } from 'app/workplace/models/task-resource';
import {Direction} from 'app/models/sorting'; import { Direction } from 'app/models/sorting';
import { TaskanaQueryParameters } from 'app/shared/util/query-parameters'; import { TaskanaQueryParameters } from 'app/shared/util/query-parameters';
import { TaskanaDate } from 'app/shared/util/taskana.date'; import { TaskanaDate } from 'app/shared/util/taskana.date';
import { map } from 'rxjs/operators'; import { map } from 'rxjs/operators';
import { QueryParametersModel } from 'app/models/query-parameters';
@Injectable() @Injectable()
export class TaskService { export class TaskService {
@ -46,23 +47,9 @@ export class TaskService {
return this.taskSelectedStream; return this.taskSelectedStream;
} }
/**
* @param {string} basketId
* @param {string} sortBy name of field, that the tasks should be sorted by, default is priority
* @returns {Observable<TaskResource>}
*/
/**
* @param {string} basketId the id of workbasket
* @param {string} sortBy name of field, that the tasks should be sorted by, default is priority
* @param {string} sortDirection ASC or DESC
* @param {string} nameLike the name of the task
* @param {string} ownerLike the owner of the task
* @param {string} priority the priority of the task
* @param {string} state the state of the task
*/
findTasksWithWorkbasket(basketId: string, findTasksWithWorkbasket(basketId: string,
sortBy = 'priority', sortBy: string,
sortDirection: string = Direction.ASC, sortDirection: string,
nameLike: string, nameLike: string,
ownerLike: string, ownerLike: string,
priority: string, priority: string,
@ -70,10 +57,17 @@ export class TaskService {
objRefTypeLike: string, objRefTypeLike: string,
objRefValueLike: string, objRefValueLike: string,
allPages: boolean = false): Observable<TaskResource> { allPages: boolean = false): Observable<TaskResource> {
const url = `${this.url}${TaskanaQueryParameters.getQueryParameters( const url = `${this.url}${TaskanaQueryParameters.getQueryParameters(this.accessIdsParameters(
sortBy, sortDirection, undefined, nameLike, undefined, undefined, ownerLike, undefined, undefined, undefined, undefined, basketId,
!allPages ? TaskanaQueryParameters.page : undefined, !allPages ? TaskanaQueryParameters.pageSize : undefined, sortBy,
undefined, undefined, undefined, undefined, basketId, priority, state, objRefTypeLike, objRefValueLike)}`; sortDirection,
nameLike,
ownerLike,
priority,
state,
objRefTypeLike,
objRefValueLike,
allPages))}`;
return this.httpClient.get<TaskResource>(url); return this.httpClient.get<TaskResource>(url);
} }
@ -130,4 +124,34 @@ export class TaskService {
if (task.due) { task.due = new Date(task.due).toISOString(); } if (task.due) { task.due = new Date(task.due).toISOString(); }
return task; return task;
} }
private accessIdsParameters(
basketId: string,
sortBy = 'priority',
sortDirection: string = Direction.ASC,
nameLike: string,
ownerLike: string,
priority: string,
state: string,
objRefTypeLike: string,
objRefValueLike: string,
allPages: boolean = false): QueryParametersModel {
const parameters = new QueryParametersModel();
parameters.WORKBASKET_ID = basketId;
parameters.SORTBY = sortBy;
parameters.SORTDIRECTION = sortDirection;
parameters.NAMELIKE = nameLike
parameters.OWNERLIKE = ownerLike;
parameters.PRIORITY = priority;
parameters.STATE = state;
parameters.TASK_PRIMARY_OBJ_REF_TYPE_LIKE = objRefTypeLike;
parameters.TASK_PRIMARY_OBJ_REF_VALUE_LIKE = objRefValueLike;
if (allPages) {
TaskanaQueryParameters.page = undefined;
TaskanaQueryParameters.pageSize = undefined;
}
return parameters;
}
} }

View File

@ -12,7 +12,7 @@ import { Component } from '@angular/core';
import { DomainService } from 'app/services/domain/domain.service'; import { DomainService } from 'app/services/domain/domain.service';
import { RequestInProgressService } from 'app/services/requestInProgress/request-in-progress.service'; import { RequestInProgressService } from 'app/services/requestInProgress/request-in-progress.service';
import { SelectedRouteService } from 'app/services/selected-route/selected-route'; import { SelectedRouteService } from 'app/services/selected-route/selected-route';
import { ErrorModalService } from 'app/services/errorModal/error-modal.service'; import { GeneralModalService } from 'app/services/general-modal/general-modal.service';
@Component({ @Component({
selector: 'taskana-dummy-detail', selector: 'taskana-dummy-detail',
@ -35,7 +35,7 @@ xdescribe('TaskComponent', () => {
imports: [FormsModule, HttpClientModule, RouterTestingModule.withRoutes(routes)], imports: [FormsModule, HttpClientModule, RouterTestingModule.withRoutes(routes)],
declarations: [TaskComponent, SpinnerComponent, DummyDetailComponent], declarations: [TaskComponent, SpinnerComponent, DummyDetailComponent],
providers: [TaskService, HttpClient, WorkbasketService, DomainService, RequestInProgressService, providers: [TaskService, HttpClient, WorkbasketService, DomainService, RequestInProgressService,
SelectedRouteService, ErrorModalService] SelectedRouteService, GeneralModalService]
}).compileComponents(); }).compileComponents();
})); }));

View File

@ -79,8 +79,7 @@
</div> </div>
<div class="form-group col-xs-2"> <div class="form-group col-xs-2">
<label for="task-priority" disabled class="control-label">Priority</label> <label for="task-priority" disabled class="control-label">Priority</label>
<input type="text" class="form-control" id="task-priority" placeholder="Priority" [(ngModel)]="task.priority" <taskana-number-picker [(ngModel)]="task.priority" title="priority" id="task-priority" name="task.priority"></taskana-number-picker>
name="task.priority">
</div> </div>
</div> </div>
</div> </div>

View File

@ -15,7 +15,7 @@ import { WorkplaceService } from '../services/workplace.service';
import { RemoveConfirmationService } from 'app/services/remove-confirmation/remove-confirmation.service'; import { RemoveConfirmationService } from 'app/services/remove-confirmation/remove-confirmation.service';
import { RequestInProgressService } from 'app/services/requestInProgress/request-in-progress.service'; import { RequestInProgressService } from 'app/services/requestInProgress/request-in-progress.service';
import { AlertService } from 'app/services/alert/alert.service'; import { AlertService } from 'app/services/alert/alert.service';
import { ErrorModalService } from 'app/services/errorModal/error-modal.service'; import { GeneralModalService } from 'app/services/general-modal/general-modal.service';
@Component({ @Component({
selector: 'taskana-dummy-detail', selector: 'taskana-dummy-detail',
@ -40,7 +40,7 @@ xdescribe('TaskdetailsComponent', () => {
TaskdetailsAttributeComponent, DummyDetailComponent], TaskdetailsAttributeComponent, DummyDetailComponent],
imports: [FormsModule, RouterTestingModule.withRoutes(routes), HttpClientModule], imports: [FormsModule, RouterTestingModule.withRoutes(routes), HttpClientModule],
providers: [TaskService, HttpClient, WorkplaceService, RemoveConfirmationService, providers: [TaskService, HttpClient, WorkplaceService, RemoveConfirmationService,
RequestInProgressService, AlertService, ErrorModalService] RequestInProgressService, AlertService, GeneralModalService]
}) })
.compileComponents(); .compileComponents();
})); }));

View File

@ -6,8 +6,8 @@ import { TaskService } from 'app/workplace/services/task.service';
import { RemoveConfirmationService } from 'app/services/remove-confirmation/remove-confirmation.service'; import { RemoveConfirmationService } from 'app/services/remove-confirmation/remove-confirmation.service';
import { Task } from 'app/workplace/models/task'; import { Task } from 'app/workplace/models/task';
import { ErrorModel } from 'app/models/modal-error'; import { MessageModal } from 'app/models/message-modal';
import { ErrorModalService } from 'app/services/errorModal/error-modal.service'; import { GeneralModalService } from 'app/services/general-modal/general-modal.service';
import { RequestInProgressService } from 'app/services/requestInProgress/request-in-progress.service'; import { RequestInProgressService } from 'app/services/requestInProgress/request-in-progress.service';
import { AlertService } from 'app/services/alert/alert.service'; import { AlertService } from 'app/services/alert/alert.service';
import { AlertModel, AlertType } from 'app/models/alert'; import { AlertModel, AlertType } from 'app/models/alert';
@ -42,7 +42,7 @@ export class TaskdetailsComponent implements OnInit, OnDestroy {
private removeConfirmationService: RemoveConfirmationService, private removeConfirmationService: RemoveConfirmationService,
private requestInProgressService: RequestInProgressService, private requestInProgressService: RequestInProgressService,
private alertService: AlertService, private alertService: AlertService,
private errorModalService: ErrorModalService, private generalModalService: GeneralModalService,
private masterAndDetailService: MasterAndDetailService) { private masterAndDetailService: MasterAndDetailService) {
} }
@ -84,8 +84,8 @@ export class TaskdetailsComponent implements OnInit, OnDestroy {
this.cloneTask(); this.cloneTask();
this.taskService.selectTask(task); this.taskService.selectTask(task);
}, err => { }, err => {
this.errorModalService.triggerError( this.generalModalService.triggerMessage(
new ErrorModel('An error occurred while fetching the task', err)); new MessageModal('An error occurred while fetching the task', err));
}); });
} }
} }

View File

@ -142,9 +142,10 @@ export class TasklistComponent implements OnInit, OnDestroy {
if (this.toolbarElement) { if (this.toolbarElement) {
const toolbarSize = this.toolbarElement.nativeElement.offsetHeight; const toolbarSize = this.toolbarElement.nativeElement.offsetHeight;
const cardHeight = 53; const cardHeight = 53;
const unusedHeight = 145; const unusedHeight = 150;
const totalHeight = window.innerHeight; const totalHeight = window.innerHeight;
const cards = Math.round((totalHeight - (unusedHeight + toolbarSize)) / cardHeight); const cards = Math.round((totalHeight - (unusedHeight + toolbarSize)) / cardHeight);
TaskanaQueryParameters.page = TaskanaQueryParameters.page ? TaskanaQueryParameters.page : 1;
cards > 0 ? TaskanaQueryParameters.pageSize = cards : TaskanaQueryParameters.pageSize = 1; cards > 0 ? TaskanaQueryParameters.pageSize = cards : TaskanaQueryParameters.pageSize = 1;
} }
} }

View File

@ -13,4 +13,7 @@
@import 'checkboxes'; @import 'checkboxes';
@import 'buttons'; @import 'buttons';
@import 'tabs'; @import 'tabs';
@import 'table';
@import 'bootstrap-3-backward-compatibility';
@import 'mixin/colors';
@import 'progress-bar'; @import 'progress-bar';

View File

@ -24,7 +24,7 @@
} }
/* Rules for sizing the icon. */ /* Rules for sizing the icon. */
.material-icons.md-15 { font-size: 15px; } .material-icons.md-14 { font-size: 15px; }
.material-icons.md-18 { font-size: 18px; } .material-icons.md-18 { font-size: 18px; }
.material-icons.md-20 { font-size: 20px; } .material-icons.md-20 { font-size: 20px; }
.material-icons.md-24 { font-size: 24px; } .material-icons.md-24 { font-size: 24px; }

View File

@ -256,7 +256,7 @@ a > svg-icon > svg{
} }
/*end buttons and icons vertical align */ /*end buttons and icons vertical align */
.btn > span.flip { span.flip {
transform: rotateX(180deg); transform: rotateX(180deg);
} }
@ -306,7 +306,7 @@ taskana-monitor-workbaskets, taskana-monitor-classification-tasks {
} }
} }
taskana-task-details, taskana-classification-details, taskana-access-items-management, taskana-task { taskana-task-details, taskana-classification-details, taskana-access-items-management, taskana-task, taskana-task-query {
& .panel{ & .panel{
border: none; border: none;
box-shadow: none; box-shadow: none;
@ -319,6 +319,15 @@ taskana-task-details, taskana-classification-details, taskana-access-items-manag
} }
} }
taskana-task-query {
& .panel{
&> .panel-body {
height: calc(100vh - 105px);
max-height: calc(100vh - 105px);
}
}
}
taskana-monitor-tasks, taskana-monitor-workbaskets, taskana-monitor-classification-tasks, taskana-access-items-management { taskana-monitor-tasks, taskana-monitor-workbaskets, taskana-monitor-classification-tasks, taskana-access-items-management {
& .panel { & .panel {
&> .panel-heading { &> .panel-heading {

View File

@ -0,0 +1,55 @@
.divTable{
display: table;
}
.divTableRow {
display: table-row;
}
.divTable .divTableHeading > .divTableRow:last-child > .divTableHeader {
background-color: #f9f9f9;
border-bottom: 1px solid $grey
}
.divTable.table-striped .divTableBody > .divTableRow:nth-of-type(odd) {
background-color: #f9f9f9;
}
.divTableCell, .divTableHeader {
display: table-cell;
padding: 3px 3px;
white-space: nowrap;
min-width: 50px;
vertical-align: middle;
}
.divTableCell{
padding: 0px 3px;
}
.divTableHeaderSeparator, .divTableCellSeparator{
border-left: 1px solid $grey;
border-right: 1px solid $grey;
background-color: $light-grey;
&.zoom-in {
cursor: zoom-in;
}
&.zoom-out {
cursor: zoom-out;
}
min-width: 0px;
}
.divTableHeading {
background-color: $light-grey;
display: table-header-group;
font-weight: bold;
cursor: pointer;
}
.divTableFoot {
background-color: $light-grey;
display: table-footer-group;
font-weight: bold;
}
.divTableBody {
display: table-row-group;
}