TSK-662 Add task classification report to monitor.

This commit is contained in:
Martin Rojas Miguel Angel 2018-09-06 19:19:54 +02:00 committed by Mustapha Zorgati
parent db70a89435
commit c6a40bb2a3
40 changed files with 631 additions and 485 deletions

View File

@ -43,7 +43,7 @@ public class ClassificationReportBuilderImpl
@Override
public ClassificationReport buildReport() throws InvalidArgumentException, NotAuthorizedException {
LOGGER.debug("entry to buildReport(), this = {}", this);
this.taskanaEngine.checkRoleMembership(TaskanaRole.MONITOR);
this.taskanaEngine.checkRoleMembership(TaskanaRole.MONITOR, TaskanaRole.ADMIN);
try {
this.taskanaEngine.openConnection();
ClassificationReport report = new ClassificationReport(this.columnHeaders);
@ -62,7 +62,7 @@ public class ClassificationReportBuilderImpl
@Override
public DetailedClassificationReport buildDetailedReport() throws InvalidArgumentException, NotAuthorizedException {
LOGGER.debug("entry to buildDetailedReport(), this = {}", this);
this.taskanaEngine.checkRoleMembership(TaskanaRole.MONITOR);
this.taskanaEngine.checkRoleMembership(TaskanaRole.MONITOR, TaskanaRole.ADMIN);
try {
this.taskanaEngine.openConnection();
DetailedClassificationReport report = new DetailedClassificationReport(this.columnHeaders);

View File

@ -43,7 +43,7 @@ public class WorkbasketReportBuilderImpl
@Override
public WorkbasketReport buildReport() throws InvalidArgumentException, NotAuthorizedException {
LOGGER.debug("entry to buildReport(), this = {}", this);
this.taskanaEngine.checkRoleMembership(TaskanaRole.MONITOR);
this.taskanaEngine.checkRoleMembership(TaskanaRole.MONITOR, TaskanaRole.ADMIN);
try {
this.taskanaEngine.openConnection();
WorkbasketReport report = new WorkbasketReport(this.columnHeaders);

View File

@ -603,21 +603,37 @@ include::../../../{snippets}/GetTaskStatusReportDocTest/http-response.adoc[]
include::../../../{snippets}/GetTaskStatusReportDocTest/response-fields.adoc[]
=== Get a count of tasks sorted by state
=== Get a tasks workbasket report
A `GET` request is used to get the number of tasks sorted by state.
==== Example Request
include::../../../{snippets}/GetCountByStateDocTest/http-request.adoc[]
include::../../../{snippets}/GetTaskWorkbasketReportDocTest/http-request.adoc[]
==== Example Response
include::../../../{snippets}/GetCountByStateDocTest/http-response.adoc[]
include::../../../{snippets}/GetTaskWorkbasketReportDocTest/http-response.adoc[]
==== Response Structure
include::../../../{snippets}/GetCountByStateDocTest/response-fields.adoc[]
Same as task status report
=== Get a tasks classification report
A `GET` request is used to get the number of tasks sorted by state.
==== Example Request
include::../../../{snippets}/GetTaskClassificationReportDocTest/http-request.adoc[]
==== Example Response
include::../../../{snippets}/GetTaskClassificationReportDocTest/http-response.adoc[]
==== Response Structure
Same as task status report
== Other Resources (using the TaskanaEngineController)

View File

@ -6,8 +6,8 @@ INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000003', '2018-01-29
INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000004', '2018-01-29 15:55:04', null , null , '2018-01-29 15:55:04', '2018-01-29 15:55:00', '2018-01-30 15:55:00', 'Widerruf' , 'creator_user_id' , 'Widerruf' , null , 2 , 'READY' , 'EXTERN' , 'L1050' , 'CLI:100000000000000000000000000000000003', 'WBI:100000000000000000000000000000000001' , 'GPK_KSC' , 'DOMAIN_A', 'PI_0000000000004' , 'DOC_0000000000000000004' , null , '00' , 'PASystem' , '00' , 'VNR' , '11223344' , false , false , null , null , null , 'ade' , null , null , null , null , null , null , null , null , null , null , null , 'abc' , null , null );
INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000005', '2018-01-29 15:55:05', null , null , '2018-01-29 15:55:05', '2018-01-29 15:55:00', '2018-01-30 15:55:00', 'Widerruf' , 'creator_user_id' , 'Widerruf' , null , 2 , 'READY' , 'EXTERN' , 'L1050' , 'CLI:100000000000000000000000000000000003', 'WBI:100000000000000000000000000000000001' , 'GPK_KSC' , 'DOMAIN_A', 'PI_0000000000005' , 'DOC_0000000000000000005' , null , '00' , 'PASystem' , '00' , 'VNR' , '11223344' , false , false , null , null , null , null , null , null , null , null , null , null , null , null , null , null , null , 'abc' , null , null );
INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000006', '2018-01-29 15:55:06', null , null , '2018-01-29 15:55:06', '2018-01-29 15:55:00', '2018-01-30 15:55:00', 'Widerruf' , 'creator_user_id' , 'Widerruf' , null , 2 , 'READY' , 'EXTERN' , 'L1050' , 'CLI:100000000000000000000000000000000003', 'WBI:100000000000000000000000000000000001' , 'GPK_KSC' , 'DOMAIN_A', 'PI_0000000000006' , 'DOC_0000000000000000006' , null , '00' , 'PASystem' , '00' , 'VNR' , '11223344' , false , false , null , null , null , null , null , null , null , null , null , null , null , null , null , null , null , 'abc' , null , null );
INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000007', '2018-01-29 15:55:07', null , null , '2018-01-29 15:55:07', '2018-01-29 15:55:00', '2018-01-30 15:55:00', 'Widerruf' , 'creator_user_id' , 'Widerruf' , null , 2 , 'READY' , 'EXTERN' , 'L1050' , 'CLI:100000000000000000000000000000000003', 'WBI:100000000000000000000000000000000001' , 'GPK_KSC' , 'DOMAIN_A', 'PI_0000000000007' , 'DOC_0000000000000000007' , null , '00' , 'PASystem' , '00' , 'VNR' , '11223344' , false , false , null , null , null , null , 'ffg' , null , null , null , null , null , null , null , null , null , null , 'abc' , null , null );
INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000008', '2018-01-29 15:55:08', null , null , '2018-01-29 15:55:08', '2018-01-29 15:55:00', '2018-01-30 15:55:00', 'Widerruf' , 'creator_user_id' , 'Widerruf' , null , 2 , 'READY' , 'EXTERN' , 'L1050' , 'CLI:100000000000000000000000000000000003', 'WBI:100000000000000000000000000000000001' , 'GPK_KSC' , 'DOMAIN_A', 'PI_0000000000008' , 'DOC_0000000000000000008' , null , '00' , 'PASystem' , '00' , 'VNR' , '22334455' , false , false , null , null , null , null , null , null , null , null , null , null , null , null , null , null , null , 'abc' , null , null );
INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000007', '2018-01-29 15:55:07', null , null , '2018-01-29 15:55:07', '2018-01-29 15:55:00', '2018-08-11 15:55:00', 'Widerruf' , 'creator_user_id' , 'Widerruf' , null , 2 , 'READY' , 'EXTERN' , 'L1050' , 'CLI:100000000000000000000000000000000003', 'WBI:100000000000000000000000000000000001' , 'GPK_KSC' , 'DOMAIN_A', 'PI_0000000000007' , 'DOC_0000000000000000007' , null , '00' , 'PASystem' , '00' , 'VNR' , '11223344' , false , false , null , null , null , null , 'ffg' , null , null , null , null , null , null , null , null , null , null , 'abc' , null , null );
INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000008', '2018-01-29 15:55:08', null , null , '2018-01-29 15:55:08', '2018-01-29 15:55:00', '2018-08-11 15:55:00', 'Widerruf' , 'creator_user_id' , 'Widerruf' , null , 2 , 'READY' , 'EXTERN' , 'L1050' , 'CLI:100000000000000000000000000000000003', 'WBI:100000000000000000000000000000000001' , 'GPK_KSC' , 'DOMAIN_A', 'PI_0000000000008' , 'DOC_0000000000000000008' , null , '00' , 'PASystem' , '00' , 'VNR' , '22334455' , false , false , null , null , null , null , null , null , null , null , null , null , null , null , null , null , null , 'abc' , null , null );
INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000009', '2018-01-29 15:55:09', null , null , '2018-01-29 15:55:09', '2018-01-29 15:55:00', '2018-01-30 15:55:00', 'Widerruf' , 'creator_user_id' , 'Widerruf' , null , 2 , 'READY' , 'EXTERN' , 'L1050' , 'CLI:100000000000000000000000000000000003', 'WBI:100000000000000000000000000000000001' , 'GPK_KSC' , 'DOMAIN_A', 'PI_0000000000009' , 'DOC_0000000000000000009' , null , '00' , 'PASystem' , '00' , 'VNR' , '22334455' , false , false , null , null , null , null , null , null , null , null , null , null , null , null , null , null , null , 'abc' , null , null );
INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000010', '2018-01-29 15:55:10', null , null , '2018-01-29 15:55:10', '2018-01-29 15:55:00', '2018-01-30 15:55:00', 'Widerruf' , 'creator_user_id' , 'Widerruf' , null , 2 , 'READY' , 'EXTERN' , 'L1050' , 'CLI:100000000000000000000000000000000003', 'WBI:100000000000000000000000000000000001' , 'GPK_KSC' , 'DOMAIN_A', 'PI_0000000000010' , 'DOC_0000000000000000010' , null , '00' , 'PASystem' , '00' , 'VNR' , '22334455' , false , false , null , null , null , null , null , 'rty' , null , null , null , null , null , null , null , null , null , 'abc' , null , null );
INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000011', '2018-01-29 15:55:11', null , null , '2018-01-29 15:55:11', '2018-01-29 15:55:00', '2018-01-30 15:55:00', 'Widerruf' , 'creator_user_id' , 'Widerruf' , null , 2 , 'READY' , 'EXTERN' , 'L1050' , 'CLI:100000000000000000000000000000000003', 'WBI:100000000000000000000000000000000001' , 'GPK_KSC' , 'DOMAIN_A', 'PI_0000000000011' , 'DOC_0000000000000000011' , null , '00' , 'PASystem' , '00' , 'VNR' , '22334455' , false , false , null , null , null , null , null , null , null , null , null , null , null , null , null , null , null , 'abc' , null , null );
@ -58,10 +58,10 @@ INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000048', '2018-01-29
INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000049', '2018-01-29 15:55:08', null , null , '2018-01-29 15:55:08', '2018-01-29 15:55:00', '2018-01-30 15:55:00', 'Widerruf' , 'creator_user_id2' , 'Widerruf' , null , 2 , 'READY' , 'EXTERN' , 'L1060' , 'CLI:200000000000000000000000000000000017', 'WBI:100000000000000000000000000000000015' , 'USER_3_2' , 'DOMAIN_B', 'PI_0000000000008' , 'DOC_0000000000000000003' , null , '00' , 'PASyste1' , '00' , 'VNR' , '22334455' , false , false , null , null , null , null , null , null , null , null , null , null , null , null , null , null , null , 'abc' , null , null );
INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000050', '2018-01-29 15:55:09', null , null , '2018-01-29 15:55:09', '2018-01-29 15:55:00', '2018-01-30 15:55:00', 'Widerruf' , 'creator_user_id2' , 'Widerruf' , null , 2 , 'READY' , 'EXTERN' , 'L1060' , 'CLI:200000000000000000000000000000000017', 'WBI:100000000000000000000000000000000015' , 'USER_3_2' , 'DOMAIN_B', 'PI_0000000000009' , 'DOC_0000000000000000009' , null , '00' , 'PASyste1' , '05' , 'VNR' , '22334455' , false , false , null , null , null , null , null , null , null , null , null , null , null , null , null , null , null , 'abc' , null , null );
INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000051', '2018-01-29 15:55:10', null , null , '2018-01-29 15:55:10', '2018-01-29 15:55:00', '2018-01-30 15:55:00', 'Widerruf' , 'creator_user_id2' , 'Widerruf' , null , 2 , 'READY' , 'EXTERN' , 'L1060' , 'CLI:200000000000000000000000000000000017', 'WBI:100000000000000000000000000000000015' , 'USER_3_2' , 'DOMAIN_B', 'PI_0000000000010' , 'DOC_0000000000000000010' , null , '00' , 'PASyste1' , '00' , 'VNR' , '22334455' , false , false , null , null , null , null , null , null , null , null , null , null , null , null , null , null , null , 'abc' , null , null );
INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000052', '2018-01-29 15:55:11', null , null , '2018-01-29 15:55:11', '2018-01-29 15:55:00', '2018-01-30 15:55:00', 'Widerruf' , 'creator_user_id' , 'Widerruf' , null , 2 , 'READY' , 'EXTERN' , 'L1060' , 'CLI:200000000000000000000000000000000017', 'WBI:100000000000000000000000000000000015' , 'USER_3_2' , 'DOMAIN_B', 'PI_0000000000011' , 'DOC_0000000000000000011' , null , '00' , 'PASystem' , '04' , 'VNR' , '22334455' , false , false , null , null , null , null , null , null , null , null , null , null , null , null , null , null , null , 'abc' , null , null );
INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000053', '2018-01-29 15:55:12', null , null , '2018-01-29 15:55:12', '2018-01-29 15:55:00', '2018-01-30 15:55:00', 'Widerruf' , 'creator_user_id3' , 'Widerruf' , null , 2 , 'READY' , 'EXTERN' , 'L1060' , 'CLI:200000000000000000000000000000000017', 'WBI:100000000000000000000000000000000015' , 'USER_3_2' , 'DOMAIN_B', 'PI_0000000000012' , 'DOC_0000000000000000012' , null , '00' , 'PASystem' , '00' , 'VNR' , '22334455' , false , false , null , null , null , null , null , null , null , null , null , null , null , null , null , null , null , 'abc' , null , null );
INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000054', '2018-01-29 15:55:13', null , null , '2018-01-29 15:55:13', '2018-01-29 15:55:00', '2018-01-30 15:55:00', 'Widerruf' , 'erstellerSpezial' , 'Widerruf' , null , 2 , 'READY' , 'EXTERN' , 'L1060' , 'CLI:200000000000000000000000000000000017', 'WBI:100000000000000000000000000000000015' , 'USER_3_2' , 'DOMAIN_B', 'PI_0000000000010' , 'DOC_0000000000000000011' , null , '00' , 'PASystem' , '00' , 'VNR' , '22334455' , false , false , null , null , null , null , null , null , null , null , null , null , null , null , null , null , null , 'abc' , null , null );
INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000055', '2018-01-29 15:55:14', null , null , '2018-01-29 15:55:14', '2018-01-29 15:55:00', '2018-01-30 15:55:00', 'Widerruf' , 'Ersteller1' , 'Widerruf' , null , 2 , 'READY' , 'EXTERN' , 'L1060' , 'CLI:200000000000000000000000000000000017', 'WBI:100000000000000000000000000000000015' , 'USER_3_2' , 'DOMAIN_B', 'PI_0000000000014' , 'DOC_0000000000000000014' , null , '00' , 'PASyste1' , '04' , 'VNR' , '12345678' , false , false , null , null , null , null , null , null , null , null , null , null , null , null , null , null , null , 'abc' , null , null );
INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000052', '2018-01-29 15:55:11', null , null , '2018-01-29 15:55:11', '2018-01-29 15:55:00', '2018-08-15 15:55:00', 'Widerruf' , 'creator_user_id' , 'Widerruf' , null , 2 , 'READY' , 'EXTERN' , 'L1060' , 'CLI:200000000000000000000000000000000017', 'WBI:100000000000000000000000000000000015' , 'USER_3_2' , 'DOMAIN_B', 'PI_0000000000011' , 'DOC_0000000000000000011' , null , '00' , 'PASystem' , '04' , 'VNR' , '22334455' , false , false , null , null , null , null , null , null , null , null , null , null , null , null , null , null , null , 'abc' , null , null );
INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000053', '2018-01-29 15:55:12', null , null , '2018-01-29 15:55:12', '2018-01-29 15:55:00', '2018-08-14 15:55:00', 'Widerruf' , 'creator_user_id3' , 'Widerruf' , null , 2 , 'READY' , 'EXTERN' , 'L1060' , 'CLI:200000000000000000000000000000000017', 'WBI:100000000000000000000000000000000015' , 'USER_3_2' , 'DOMAIN_B', 'PI_0000000000012' , 'DOC_0000000000000000012' , null , '00' , 'PASystem' , '00' , 'VNR' , '22334455' , false , false , null , null , null , null , null , null , null , null , null , null , null , null , null , null , null , 'abc' , null , null );
INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000054', '2018-01-29 15:55:13', null , null , '2018-01-29 15:55:13', '2018-01-29 15:55:00', '2018-08-13 15:55:00', 'Widerruf' , 'erstellerSpezial' , 'Widerruf' , null , 2 , 'READY' , 'EXTERN' , 'L1060' , 'CLI:200000000000000000000000000000000017', 'WBI:100000000000000000000000000000000015' , 'USER_3_2' , 'DOMAIN_B', 'PI_0000000000010' , 'DOC_0000000000000000011' , null , '00' , 'PASystem' , '00' , 'VNR' , '22334455' , false , false , null , null , null , null , null , null , null , null , null , null , null , null , null , null , null , 'abc' , null , null );
INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000055', '2018-01-29 15:55:14', null , null , '2018-01-29 15:55:14', '2018-01-29 15:55:00', '2018-08-13 15:55:00', 'Widerruf' , 'Ersteller1' , 'Widerruf' , null , 2 , 'READY' , 'EXTERN' , 'L1060' , 'CLI:200000000000000000000000000000000017', 'WBI:100000000000000000000000000000000015' , 'USER_3_2' , 'DOMAIN_B', 'PI_0000000000014' , 'DOC_0000000000000000014' , null , '00' , 'PASyste1' , '04' , 'VNR' , '12345678' , false , false , null , null , null , null , null , null , null , null , null , null , null , null , null , null , null , 'abc' , null , null );
INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000056', '2018-01-29 15:55:15', null , null , '2018-01-29 15:55:15', '2018-01-29 15:55:00', '2018-01-30 15:55:00', 'Widerruf' , 'Ersteller1' , 'Widerruf' , null , 2 , 'READY' , 'EXTERN' , 'L1060' , 'CLI:200000000000000000000000000000000017', 'WBI:100000000000000000000000000000000015' , 'USER_3_2' , 'DOMAIN_B', 'PI_0000000000015' , 'DOC_0000000000000000015' , null , '00' , 'PASyste1' , '00' , 'VNR' , '23456789' , false , true , null , null , null , null , null , null , null , null , null , null , null , null , null , null , null , 'abc' , null , null );
INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000057', '2018-01-29 15:55:16', null , null , '2018-01-29 15:55:16', '2018-01-29 15:55:00', '2018-01-30 15:55:00', 'Widerruf' , 'creator_user_id' , 'Widerruf' , null , 2 , 'READY' , 'EXTERN' , 'L1060' , 'CLI:200000000000000000000000000000000017', 'WBI:100000000000000000000000000000000015' , 'USER_3_2' , 'DOMAIN_B', 'PI_0000000000010' , 'DOC_0000000000000000011' , null , '00' , 'PASyste2' , '00' , 'VNR' , '34567890' , false , true , null , null , null , null , null , null , null , null , null , null , null , null , null , null , null , 'abc' , null , null );
INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000058', '2018-01-29 15:55:17', null , null , '2018-01-29 15:55:17', '2018-01-29 15:55:00', '2018-01-30 15:55:00', 'Widerruf' , 'creator_user_id' , 'Widerruf' , null , 2 , 'READY' , 'EXTERN' , 'L1060' , 'CLI:200000000000000000000000000000000017', 'WBI:100000000000000000000000000000000015' , 'USER_3_2' , 'DOMAIN_B', 'PI_0000000000017' , 'DOC_0000000000000000017' , null , '00' , 'PASystem' , '03' , 'VNR' , '45678901' , false , false , null , null , null , null , null , null , null , null , null , null , null , null , null , null , null , 'abc' , null , null );

View File

@ -45,9 +45,8 @@ public class MonitorControllerRestDocumentation {
private MockMvc mockMvc;
private FieldDescriptor[] taskStatusReportFieldDescriptors;
private FieldDescriptor[] countByStateFieldDescriptors;
private FieldDescriptor[] taskReportFieldDescriptors;
@Before
public void setUp() {
document("{methodName}",
@ -62,7 +61,7 @@ public class MonitorControllerRestDocumentation {
.withRequestDefaults(prettyPrint()))
.build();
taskStatusReportFieldDescriptors = new FieldDescriptor[] {
taskReportFieldDescriptors = new FieldDescriptor[] {
fieldWithPath("meta").description("Object holding metainfo on the report"),
fieldWithPath("meta.name").description("Name of the report"),
fieldWithPath("meta.date").description("Date of the report creation"),
@ -77,31 +76,37 @@ public class MonitorControllerRestDocumentation {
fieldWithPath("sumRow.total").description("Total number of tasks"),
fieldWithPath("_links.self.href").ignored()
};
countByStateFieldDescriptors = new FieldDescriptor[] {
fieldWithPath("[]..state").description("The state the tasks are in"),
fieldWithPath("[]..counter").description("Number of tasks in the corresponding state")
};
}
@Test
public void getTaskStatusReport() throws Exception {
this.mockMvc.perform(RestDocumentationRequestBuilders
.get("http://127.0.0.1:" + port + "/v1/monitor/taskStatusReport")
.get("http://127.0.0.1:" + port + "/v1/monitor/tasks-status-report")
.header("Authorization", "Basic YWRtaW46YWRtaW4="))
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(MockMvcRestDocumentation.document("GetTaskStatusReportDocTest",
responseFields(taskStatusReportFieldDescriptors)));
responseFields(taskReportFieldDescriptors)));
}
@Test
public void getCountByState() throws Exception {
public void tasksWorkbasketReport() throws Exception {
this.mockMvc.perform(RestDocumentationRequestBuilders
.get("http://127.0.0.1:" + port + "/v1/monitor/countByState?states=READY,CLAIMED,COMPLETED")
.get("http://127.0.0.1:" + port + "/v1/monitor/tasks-workbasket-report?daysInPast=4&states=READY,CLAIMED,COMPLETED")
.accept("application/hal+json")
.header("Authorization", "Basic dGVhbWxlYWRfMTp0ZWFtbGVhZF8x"))
.header("Authorization", "Basic YWRtaW46YWRtaW4="))
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(MockMvcRestDocumentation.document("GetCountByStateDocTest",
responseFields(countByStateFieldDescriptors)));
.andDo(MockMvcRestDocumentation.document("GetTaskWorkbasketReportDocTest",
responseFields(taskReportFieldDescriptors)));
}
@Test
public void tasksClassificationReport() throws Exception {
this.mockMvc.perform(RestDocumentationRequestBuilders
.get("http://127.0.0.1:" + port + "/v1/monitor/tasks-classification-report")
.accept("application/hal+json")
.header("Authorization", "Basic YWRtaW46YWRtaW4="))
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(MockMvcRestDocumentation.document("GetTaskClassificationReportDocTest",
responseFields(taskReportFieldDescriptors)));
}
}

View File

@ -0,0 +1,33 @@
package pro.taskana.monitor;
import pro.taskana.impl.report.TimeIntervalColumnHeader;
/**
* Class for Classification time Interval Column Header, overrides displayName.
*
* @author mmr
*/
public class ClassificationTimeIntervalColumnHeader extends TimeIntervalColumnHeader {
public ClassificationTimeIntervalColumnHeader(int ageInDays) {
super(ageInDays);
}
public ClassificationTimeIntervalColumnHeader(int lowerAgeLimit, int upperAgeLimit) {
super(lowerAgeLimit, upperAgeLimit);
}
@Override
public String getDisplayName() {
if (this.getLowerAgeLimit() == Integer.MIN_VALUE) {
return "<" + this.getUpperAgeLimit();
} else if (this.getUpperAgeLimit() == Integer.MAX_VALUE) {
return ">" + this.getLowerAgeLimit();
} else if (this.getLowerAgeLimit() == this.getUpperAgeLimit()) {
return this.getUpperAgeLimit() + "";
} else if (this.getLowerAgeLimit() != this.getUpperAgeLimit()) {
return "[" + this.getLowerAgeLimit() + " ... " + this.getUpperAgeLimit() + "]";
}
return super.getDisplayName();
}
}

View File

@ -0,0 +1,26 @@
package pro.taskana.monitor;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
import pro.taskana.impl.report.TimeIntervalColumnHeader;
/**
* Class for Workbasket Time Interval Column Header, overrides displayName.
*
* @author mmr
*/
public class WorkbasketTimeIntervalColumnHeader extends TimeIntervalColumnHeader {
public WorkbasketTimeIntervalColumnHeader(int ageInDays) {
super(ageInDays);
}
@Override
public String getDisplayName() {
LocalDateTime ldt = LocalDateTime.now().plusDays(getLowerAgeLimit());
DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd", Locale.ENGLISH);
return dateFormat.format(ldt);
}
}

View File

@ -1,6 +1,9 @@
package pro.taskana.rest;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
@ -15,6 +18,9 @@ import pro.taskana.TaskMonitorService;
import pro.taskana.TaskState;
import pro.taskana.exceptions.InvalidArgumentException;
import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.impl.report.TimeIntervalColumnHeader;
import pro.taskana.monitor.ClassificationTimeIntervalColumnHeader;
import pro.taskana.monitor.WorkbasketTimeIntervalColumnHeader;
import pro.taskana.rest.resource.ReportResource;
import pro.taskana.rest.resource.assembler.ReportAssembler;
@ -31,54 +37,63 @@ public class MonitorController {
@Autowired
private ReportAssembler reportAssembler;
@GetMapping(path = "/countByState")
@GetMapping(path = "/tasks-status-report")
@Transactional(readOnly = true, rollbackFor = Exception.class)
public ResponseEntity<?> getTaskcountForState(
@RequestParam(value = "states") List<TaskState> taskStates) {
String taskCount = "[{\"state\": \"READY\", \"counter\": 7},{\"state\": \"CLAIMED\",\"counter\": 4},{\"state\": \"COMPLETED\",\"counter\": 4 }]";
return ResponseEntity.status(HttpStatus.OK).body(taskCount);
}
@GetMapping(path = "/taskcountByWorkbasketDaysAndState")
@Transactional(readOnly = true, rollbackFor = Exception.class)
public ResponseEntity<?> getTaskCountByWorkbasketAndDaysInPastAndState(
@RequestParam(value = "daysInPast") Long daysInPast,
@RequestParam(value = "states") List<TaskState> states) {
StringBuilder builder = new StringBuilder();
builder.append(
"{ \"dates\": [\"02.02.2018\",\"03.02.2018\",\"04.02.2018\", \"05.02.2018\", \"06.02.2018\", \"07.02.2018\",\"08.02.2018\",\"09.02.2018\",\"10.02.2018\",\"11.02.2018\", \"12.02.2018\"],");
builder.append("\"data\": [");
builder.append("{\"data\": [0,0,0,0,0,0,0,0,0,0,0],\"label\": \"Basket1\"},");
builder.append("{\"data\": [0,0,0,0,0,0,0,0,0,0,0],\"label\": \"Basket2\"},");
builder.append("{\"data\": [0,0,0,0,0,0,0,0,0,0,0],\"label\": \"Basket3\"},");
builder.append("{\"data\": [0,0,0,0,0,0,0,0,0,0,0],\"label\": \"Basket4\"},");
builder.append("{\"data\": [0,0,0,0,0,0,0,0,0,0,0],\"label\": \"Gruppenpostkorb KSC\"},");
builder.append("{\"data\": [0,0,0,0,0,0,0,0,0,0,0],\"label\": \"Gruppenpostkorb KSC 1\"},");
builder.append("{\"data\": [0,0,0,0,0,0,0,0,0,0,0],\"label\": \"Gruppenpostkorb KSC 2\"},");
builder.append("{\"data\": [0,0,0,0,0,0,0,0,0,0,0],\"label\": \"PPK Teamlead KSC 1\"},");
builder.append("{\"data\": [0,0,0,0,0,0,0,0,0,0,0],\"label\": \"PPK Teamlead KSC 2\"},");
builder.append("{\"data\": [0,0,0,0,0,0,0,0,0,0,0],\"label\": \"PPK User 1 KSC 1\"},");
builder.append("{\"data\": [0,0,0,0,0,0,0,0,0,0,0],\"label\": \"PPK User 2 KSC 1\"},");
builder.append("{\"data\": [0,0,0,0,0,0,0,0,0,0,0],\"label\": \"PPK User 1 KSC 2\"},");
builder.append("{\"data\": [0,0,0,0,0,0,0,0,0,0,0],\"label\": \"PPK User 2 KSC 2\"},");
builder.append("{\"data\": [0,0,0,0,0,0,0,0,0,0,0],\"label\": \"Gruppenpostkorb KSC B\"},");
builder.append("{\"data\": [0,0,0,0,0,0,0,0,0,0,0],\"label\": \"Gruppenpostkorb KSC B1\"},");
builder.append("{\"data\": [0,0,0,0,0,0,0,0,0,0,0],\"label\": \"Gruppenpostkorb KSC B2\"}");
builder.append("]}");
return ResponseEntity.status(HttpStatus.OK).body(builder.toString());
}
@GetMapping(path = "/taskStatusReport")
@Transactional(readOnly = true, rollbackFor = Exception.class)
public ResponseEntity<ReportResource> getTaskStatusReport(@RequestParam(required = false) List<String> domains,
public ResponseEntity<ReportResource> getTasksStatusReport(@RequestParam(required = false) List<String> domains,
@RequestParam(required = false) List<TaskState> states) throws NotAuthorizedException,
InvalidArgumentException {
// return ResponseEntity.status(HttpStatus.OK)
// .body(reportAssembler.toResource(taskMonitorService.getTaskStatusReport(domains, states), domains, states));
return ResponseEntity.status(HttpStatus.OK)
.body(reportAssembler.toResource(
taskMonitorService.createTaskStatusReportBuilder().stateIn(states).domainIn(domains).buildReport(),
domains, states));
}
@GetMapping(path = "/tasks-workbasket-report")
@Transactional(readOnly = true, rollbackFor = Exception.class)
public ResponseEntity<?> getTasksWorkbasketReport(
@RequestParam(value = "daysInPast") int daysInPast,
@RequestParam(value = "states") List<TaskState> states)
throws NotAuthorizedException, InvalidArgumentException {
return ResponseEntity.status(HttpStatus.OK)
.body(reportAssembler.toResource(
taskMonitorService.createWorkbasketReportBuilder()
.stateIn(states)
.withColumnHeaders(getTasksWorkbasketsTimeInterval(daysInPast)).buildReport(), daysInPast, states));
}
@GetMapping(path = "/tasks-classification-report")
@Transactional(readOnly = true, rollbackFor = Exception.class)
public ResponseEntity<ReportResource> getTasksClassificationReport()
throws NotAuthorizedException, InvalidArgumentException {
return ResponseEntity.status(HttpStatus.OK)
.body(reportAssembler.toResource(
taskMonitorService.createClassificationReportBuilder()
.withColumnHeaders(getTaskClassificationTimeInterval())
.buildReport()));
}
private List<TimeIntervalColumnHeader> getTaskClassificationTimeInterval() {
return Stream.concat(Stream.concat(
Stream.of(new ClassificationTimeIntervalColumnHeader(Integer.MIN_VALUE, -10),
new ClassificationTimeIntervalColumnHeader(-10, -5)
),
Stream.of(-4, -3, -2, -1, 0, 1, 2, 3, 4)
.map(ClassificationTimeIntervalColumnHeader::new)
),
Stream.of(new ClassificationTimeIntervalColumnHeader(5, 10),
new ClassificationTimeIntervalColumnHeader(10, Integer.MAX_VALUE)
))
.collect(Collectors.toList());
}
private List<TimeIntervalColumnHeader> getTasksWorkbasketsTimeInterval(int daysInPast) {
List<TimeIntervalColumnHeader> columnHeaders = new ArrayList<>();
for (int i = 0; i <= daysInPast; i++) {
columnHeaders.add(new WorkbasketTimeIntervalColumnHeader(i - daysInPast));
}
return columnHeaders;
}
}

View File

@ -19,6 +19,9 @@ import pro.taskana.report.Report;
import pro.taskana.report.ReportColumnHeader;
import pro.taskana.report.ReportRow;
import pro.taskana.report.TaskStatusReport;
import pro.taskana.report.ClassificationReport;
import pro.taskana.report.WorkbasketReport;
import pro.taskana.rest.MonitorController;
import pro.taskana.rest.resource.ReportResource;
@ -30,14 +33,32 @@ public class ReportAssembler {
public ReportResource toResource(TaskStatusReport report, List<String> domains, List<TaskState> states)
throws NotAuthorizedException, InvalidArgumentException {
ReportResource resource = toResource(report);
ReportResource resource = toReportResource(report);
resource.add(
linkTo(methodOn(MonitorController.class).getTaskStatusReport(domains, states))
linkTo(methodOn(MonitorController.class).getTasksStatusReport(domains, states))
.withSelfRel().expand());
return resource;
}
private <I extends QueryItem, H extends ReportColumnHeader<? super I>> ReportResource toResource(
public ReportResource toResource(ClassificationReport report)
throws NotAuthorizedException, InvalidArgumentException {
ReportResource resource = toReportResource(report);
resource.add(
linkTo(methodOn(MonitorController.class).getTasksClassificationReport())
.withSelfRel().expand());
return resource;
}
public ReportResource toResource(WorkbasketReport report, int daysInPast, List<TaskState> states)
throws NotAuthorizedException, InvalidArgumentException {
ReportResource resource = toReportResource(report);
resource.add(
linkTo(methodOn(MonitorController.class).getTasksWorkbasketReport(daysInPast, states))
.withSelfRel().expand());
return resource;
}
private <I extends QueryItem, H extends ReportColumnHeader<? super I>> ReportResource toReportResource(
Report<I, H> report) {
String[] header = report.getColumnHeaders()
.stream()

View File

@ -21,7 +21,7 @@
"src/environments/data-sources"
],
"styles": [
"src/assets/_styles.scss"
"src/assets/_main.scss"
],
"scripts": [
"node_modules/jquery/dist/jquery.min.js",
@ -78,7 +78,7 @@
"node_modules/bootstrap/dist/js/bootstrap.min.js"
],
"styles": [
"src/assets/_styles.scss"
"src/assets/_main.scss"
],
"assets": [
"src/assets",

241
web/package-lock.json generated
View File

@ -1669,9 +1669,9 @@
"dev": true
},
"@types/selenium-webdriver": {
"version": "2.53.43",
"resolved": "https://registry.npmjs.org/@types/selenium-webdriver/-/selenium-webdriver-2.53.43.tgz",
"integrity": "sha512-UBYHWph6P3tutkbXpW6XYg9ZPbTKjw/YC2hGG1/GEvWwTbvezBUv3h+mmUFw79T3RFPnmedpiXdOBbXX+4l0jg==",
"version": "3.0.10",
"resolved": "https://registry.npmjs.org/@types/selenium-webdriver/-/selenium-webdriver-3.0.10.tgz",
"integrity": "sha512-ikB0JHv6vCR1KYUQAzTO4gi/lXLElT4Tx+6De2pc/OZwizE9LRNiTa+U8TBFKBD/nntPnr/MPSHSnOTybjhqNA==",
"dev": true
},
"@types/strip-bom": {
@ -2059,9 +2059,9 @@
"optional": true
},
"adm-zip": {
"version": "0.4.4",
"resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.4.tgz",
"integrity": "sha1-ph7VrmkFw66lizplfSUDMJEFJzY=",
"version": "0.4.11",
"resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.11.tgz",
"integrity": "sha512-L8vcjDTCOIJk7wFvmlEUN7AsSb8T+2JrdP7KINBjzr24TJ5Mwj590sLu3BC7zNZowvJWa/JtPmD8eJCzdtDWjA==",
"dev": true
},
"after": {
@ -2964,6 +2964,15 @@
"electron-to-chromium": "^1.3.47"
}
},
"browserstack": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/browserstack/-/browserstack-1.5.1.tgz",
"integrity": "sha512-O8VMT64P9NOLhuIoD4YngyxBURefaSdR4QdhG8l6HZ9VxtU7jc3m6jLufFwKA5gaf7fetfB2TnRJnMxyob+heg==",
"dev": true,
"requires": {
"https-proxy-agent": "^2.2.1"
}
},
"buffer": {
"version": "4.9.1",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz",
@ -5145,7 +5154,8 @@
"ansi-regex": {
"version": "2.1.1",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"aproba": {
"version": "1.1.1",
@ -5221,6 +5231,7 @@
"version": "2.10.1",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"hoek": "2.x.x"
}
@ -5392,6 +5403,7 @@
"version": "1.0.11",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"graceful-fs": "^4.1.2",
"inherits": "~2.0.0",
@ -5459,7 +5471,8 @@
"graceful-fs": {
"version": "4.1.11",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"har-schema": {
"version": "1.0.5",
@ -5653,6 +5666,7 @@
"version": "0.5.1",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"minimist": "0.0.8"
}
@ -5942,6 +5956,7 @@
"version": "3.0.1",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"ansi-regex": "^2.0.0"
}
@ -10720,12 +10735,6 @@
}
}
},
"options": {
"version": "0.0.6",
"resolved": "https://registry.npmjs.org/options/-/options-0.0.6.tgz",
"integrity": "sha1-7CLTEoBrtT5zF3Pnza788cZDEo8=",
"dev": true
},
"original": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/original/-/original-1.0.1.tgz",
@ -11285,15 +11294,16 @@
}
},
"protractor": {
"version": "5.3.2",
"resolved": "https://registry.npmjs.org/protractor/-/protractor-5.3.2.tgz",
"integrity": "sha512-pw4uwwiy5lHZjIguxNpkEwJJa7hVz+bJsvaTI+IbXlfn2qXwzbF8eghW/RmrZwE2sGx82I8etb8lVjQ+JrjejA==",
"version": "5.4.0",
"resolved": "https://registry.npmjs.org/protractor/-/protractor-5.4.0.tgz",
"integrity": "sha512-6TSYqMhUUzxr4/wN0ttSISqPMKvcVRXF4k8jOEpGWD8OioLak4KLgfzHK9FJ49IrjzRrZ+Mx1q2Op8Rk0zEcnQ==",
"dev": true,
"requires": {
"@types/node": "^6.0.46",
"@types/q": "^0.0.32",
"@types/selenium-webdriver": "~2.53.39",
"@types/selenium-webdriver": "^3.0.0",
"blocking-proxy": "^1.0.0",
"browserstack": "^1.5.1",
"chalk": "^1.1.3",
"glob": "^7.0.3",
"jasmine": "2.8.0",
@ -11303,50 +11313,14 @@
"saucelabs": "^1.5.0",
"selenium-webdriver": "3.6.0",
"source-map-support": "~0.4.0",
"webdriver-js-extender": "^1.0.0",
"webdriver-js-extender": "2.0.0",
"webdriver-manager": "^12.0.6"
},
"dependencies": {
"@types/node": {
"version": "6.0.114",
"resolved": "https://registry.npmjs.org/@types/node/-/node-6.0.114.tgz",
"integrity": "sha512-5ViC9dwf1VIAtrOFTvOuN04lJgw28eKjuy0Vg2Bd/fSlxKP2feCSkIw04ZgOENL2ywdWrtbkthp1XVLEjJmouw==",
"dev": true
},
"adm-zip": {
"version": "0.4.11",
"resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.11.tgz",
"integrity": "sha512-L8vcjDTCOIJk7wFvmlEUN7AsSb8T+2JrdP7KINBjzr24TJ5Mwj590sLu3BC7zNZowvJWa/JtPmD8eJCzdtDWjA==",
"dev": true
},
"ajv": {
"version": "5.5.2",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz",
"integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=",
"dev": true,
"requires": {
"co": "^4.6.0",
"fast-deep-equal": "^1.0.0",
"fast-json-stable-stringify": "^2.0.0",
"json-schema-traverse": "^0.3.0"
}
},
"assert-plus": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
"integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
"dev": true
},
"aws-sign2": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
"integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=",
"dev": true
},
"caseless": {
"version": "0.12.0",
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
"integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=",
"version": "6.0.116",
"resolved": "https://registry.npmjs.org/@types/node/-/node-6.0.116.tgz",
"integrity": "sha512-vToa8YEeulfyYg1gSOeHjvvIRqrokng62VMSj2hoZrwZNcYrp2h3AWo6KeBVuymIklQUaY5zgVJvVsC4KiiLkQ==",
"dev": true
},
"del": {
@ -11364,28 +11338,6 @@
"rimraf": "^2.2.8"
}
},
"form-data": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz",
"integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=",
"dev": true,
"requires": {
"asynckit": "^0.4.0",
"combined-stream": "1.0.6",
"mime-types": "^2.1.12"
},
"dependencies": {
"combined-stream": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz",
"integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=",
"dev": true,
"requires": {
"delayed-stream": "~1.0.0"
}
}
}
},
"globby": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz",
@ -11400,70 +11352,6 @@
"pinkie-promise": "^2.0.0"
}
},
"har-validator": {
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz",
"integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=",
"dev": true,
"requires": {
"ajv": "^5.1.0",
"har-schema": "^2.0.0"
}
},
"http-signature": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
"integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
"dev": true,
"requires": {
"assert-plus": "^1.0.0",
"jsprim": "^1.2.2",
"sshpk": "^1.7.0"
}
},
"qs": {
"version": "6.5.2",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
"integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==",
"dev": true
},
"request": {
"version": "2.87.0",
"resolved": "https://registry.npmjs.org/request/-/request-2.87.0.tgz",
"integrity": "sha512-fcogkm7Az5bsS6Sl0sibkbhcKsnyon/jV1kF3ajGmF0c8HrttdKTPRT9hieOaQHA5HEq6r8OyWOo/o781C1tNw==",
"dev": true,
"requires": {
"aws-sign2": "~0.7.0",
"aws4": "^1.6.0",
"caseless": "~0.12.0",
"combined-stream": "~1.0.5",
"extend": "~3.0.1",
"forever-agent": "~0.6.1",
"form-data": "~2.3.1",
"har-validator": "~5.0.3",
"http-signature": "~1.2.0",
"is-typedarray": "~1.0.0",
"isstream": "~0.1.2",
"json-stringify-safe": "~5.0.1",
"mime-types": "~2.1.17",
"oauth-sign": "~0.8.2",
"performance-now": "^2.1.0",
"qs": "~6.5.1",
"safe-buffer": "^5.1.1",
"tough-cookie": "~2.3.3",
"tunnel-agent": "^0.6.0",
"uuid": "^3.1.0"
}
},
"tunnel-agent": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
"integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
"dev": true,
"requires": {
"safe-buffer": "^5.0.1"
}
},
"webdriver-manager": {
"version": "12.1.0",
"resolved": "https://registry.npmjs.org/webdriver-manager/-/webdriver-manager-12.1.0.tgz",
@ -14974,66 +14862,13 @@
}
},
"webdriver-js-extender": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/webdriver-js-extender/-/webdriver-js-extender-1.0.0.tgz",
"integrity": "sha1-gcUzqeM9W/tZe05j4s2yW1R3dRU=",
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/webdriver-js-extender/-/webdriver-js-extender-2.0.0.tgz",
"integrity": "sha512-fbyKiVu3azzIc5d4+26YfuPQcFTlgFQV5yQ/0OQj4Ybkl4g1YQuIPskf5v5wqwRJhHJnPHthB6tqCjWHOKLWag==",
"dev": true,
"requires": {
"@types/selenium-webdriver": "^2.53.35",
"selenium-webdriver": "^2.53.2"
},
"dependencies": {
"sax": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/sax/-/sax-0.6.1.tgz",
"integrity": "sha1-VjsZx8HeiS4Jv8Ty/DDjwn8JUrk=",
"dev": true
},
"selenium-webdriver": {
"version": "2.53.3",
"resolved": "https://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-2.53.3.tgz",
"integrity": "sha1-0p/1qVff8aG0ncRXdW5OS/vc4IU=",
"dev": true,
"requires": {
"adm-zip": "0.4.4",
"rimraf": "^2.2.8",
"tmp": "0.0.24",
"ws": "^1.0.1",
"xml2js": "0.4.4"
}
},
"tmp": {
"version": "0.0.24",
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.24.tgz",
"integrity": "sha1-1qXhmNFKmDXMby18PZ4wJCjIzxI=",
"dev": true
},
"ultron": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/ultron/-/ultron-1.0.2.tgz",
"integrity": "sha1-rOEWq1V80Zc4ak6I9GhTeMiy5Po=",
"dev": true
},
"ws": {
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/ws/-/ws-1.1.5.tgz",
"integrity": "sha512-o3KqipXNUdS7wpQzBHSe180lBGO60SoK0yVo3CYJgb2MkobuWuBX6dhkYP5ORCLd55y+SaflMOV5fqAB53ux4w==",
"dev": true,
"requires": {
"options": ">=0.0.5",
"ultron": "1.0.x"
}
},
"xml2js": {
"version": "0.4.4",
"resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.4.tgz",
"integrity": "sha1-MREBAAMAiuGSQOuhdJe1fHKcVV0=",
"dev": true,
"requires": {
"sax": "0.6.x",
"xmlbuilder": ">=1.0.0"
}
}
"@types/selenium-webdriver": "^3.0.0",
"selenium-webdriver": "^3.0.1"
}
},
"webpack": {
@ -15790,6 +15625,7 @@
"version": "1.1.11",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"balanced-match": "1.0.0",
"concat-map": "0.0.1"
@ -15958,6 +15794,7 @@
"version": "3.0.4",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"brace-expansion": "^1.1.7"
}

View File

@ -57,7 +57,7 @@
"karma-jasmine-html-reporter": "0.2.2",
"moment": "2.22.1",
"ng2-mock-component": "0.1.1",
"protractor": "5.3.2",
"protractor": "^5.4.0",
"ts-mockito": "2.3.0",
"ts-node": "4.1.0",
"tslint": "5.9.1",

View File

@ -1,32 +0,0 @@
.nav.nav-tabs {
& > li {
& > a {
min-height: 52px;
padding-top: 15px;
border-radius: 0px;
&.has-changes{
border-bottom: solid #f0ad4e;
}
cursor: pointer;
}
&:first-child > a{
border-left: none;
}
}
& > li.active > a {
border-top: 3px solid #479ea9;
padding-top: 13px;
background-color: #f5f5f5;
}
& > p{
margin: 0px;
}
& > li.disabled {
cursor: not-allowed;
}
& > li.disabled > a {
pointer-events: none;
}
}

View File

@ -3,9 +3,9 @@ import { RouterModule, Routes } from '@angular/router';
import { AppComponent } from './app.component';
import { BusinessAdminGuard } from 'app/guards/business-admin-guard';
import { MonitorGuard } from 'app/guards/monitor-guard';
import { UserGuard } from 'app/guards/user-guard';
import { BusinessAdminGuard } from './guards/business-admin-guard';
import { MonitorGuard } from './guards/monitor-guard';
import { UserGuard } from './guards/user-guard';
import { NoAccessComponent } from './components/no-access/no-access.component';
const appRoutes: Routes = [

View File

@ -1,12 +1,6 @@
import { Observable } from 'rxjs';
import { HttpClient } from '@angular/common/http';
import { CanActivate, Router } from '@angular/router';
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 { WindowRefService } from 'app/services/window/window.service';
@Injectable()
export class UserGuard implements CanActivate {

View File

@ -0,0 +1,16 @@
<div *ngIf="reportData" class="panel panel-default">
<div class="panel-heading">
<h4>{{reportData.meta.name}} ({{reportData.meta.date | date : 'dd.MM.yyyy HH:mm:ss'}})</h4>
</div>
<div class="panel-body">
<div class="row">
<div class="col-xs-12 col-md-8 col-md-offset-2">
<div style="display: block;">
<canvas baseChart [datasets]="lineChartData" [labels]="lineChartLabels" [options]="lineChartOptions"
[colors]="lineChartColors" [legend]="lineChartLegend" [chartType]="lineChartType"></canvas>
</div>
</div>
</div>
<taskana-report [type]="reportType" [reportData]="reportData"></taskana-report>
</div>
</div>

View File

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

View File

@ -0,0 +1,37 @@
import { Component, OnInit } from '@angular/core';
import { ReportType } from '../report/reportType';
import { RestConnectorService } from 'app/monitor/services/restConnector/rest-connector.service';
import { ReportData } from '../models/report-data';
import { ChartData } from 'app/monitor/models/chart-data';
import { ChartColorsDefinition } from '../models/chart-colors';
@Component({
selector: 'taskana-monitor-classification-tasks',
templateUrl: './classification-tasks.component.html',
styleUrls: ['./classification-tasks.component.scss']
})
export class ClassificationTasksComponent implements OnInit {
reportType = ReportType.ClassificationStatus;
reportData: ReportData;
lineChartLabels: Array<any>;
lineChartLegend = true;
lineChartType = 'line';
lineChartData: Array<ChartData>;
lineChartOptions: any = {
responsive: true
};
lineChartColors = ChartColorsDefinition.getColors();
constructor(private restConnectorService: RestConnectorService) {
}
ngOnInit() {
this.restConnectorService.getClassificationTasksReport().subscribe((data: ReportData) => {
this.reportData = data;
this.lineChartData = this.restConnectorService.getChartData(data);
this.lineChartLabels = this.restConnectorService.getChartHeaders(data);
})
}
}

View File

@ -0,0 +1,71 @@
export class ChartColorsDefinition {
public static getColors(): Array<any> {
return [
{ // red
backgroundColor: 'rgba(215, 40, 40, 0.2)',
borderColor: 'rgba(215, 40, 40, 1)',
pointBackgroundColor: 'rgba(215, 40, 40, 1)',
pointBorderColor: '#fff',
pointHoverBackgroundColor: '#fff',
pointHoverBorderColor: 'rgba(215, 40, 40, 0.8)'
},
{ // yellow
backgroundColor: 'rgba(208, 205, 44, 0.2)',
borderColor: 'rgba(208, 205, 44, 1)',
pointBackgroundColor: 'rgba(208, 205, 44, 1)',
pointBorderColor: '#fff',
pointHoverBackgroundColor: '#fff',
pointHoverBorderColor: 'rgba(208, 205, 44, 0.8)'
},
{ // green
backgroundColor: 'rgba(45, 205, 44, 0.2)',
borderColor: 'rgba(45, 205, 44, 1)',
pointBackgroundColor: 'rgba(45, 205, 44, 1)',
pointBorderColor: '#fff',
pointHoverBackgroundColor: '#fff',
pointHoverBorderColor: 'rgba(45, 205, 44, 0.8)'
},
{ // blue
backgroundColor: 'rgba(45, 45, 201, 0.2)',
borderColor: 'rgba(45, 45, 201, 1)',
pointBackgroundColor: 'rgba(45, 45, 201, 1)',
pointBorderColor: '#fff',
pointHoverBackgroundColor: '#fff',
pointHoverBorderColor: 'rgba(45, 45, 201, 0.8)'
},
{ // cyan
backgroundColor: 'rgba(45, 190, 201, 0.2)',
borderColor: 'rgba(45, 190, 201, 1)',
pointBackgroundColor: 'rgba(45, 190, 201, 1)',
pointBorderColor: '#fff',
pointHoverBackgroundColor: '#fff',
pointHoverBorderColor: 'rgba(45, 190, 201, 0.8)'
},
{ // black-grey
backgroundColor: 'rgba(37, 35, 38, 0.2)',
borderColor: 'rgba(37, 35, 38, 1)',
pointBackgroundColor: 'rgba(37, 35, 38, 1)',
pointBorderColor: '#fff',
pointHoverBackgroundColor: '#fff',
pointHoverBorderColor: 'rgba(37, 35, 38, 0.8)'
},
{ // orange
backgroundColor: 'rgba(221, 125, 0, 0.2)',
borderColor: 'rgba(221, 125, 0, 1)',
pointBackgroundColor: 'rgba(221, 125, 0, 1)',
pointBorderColor: '#fff',
pointHoverBackgroundColor: '#fff',
pointHoverBorderColor: 'rgba(221, 125, 0, 0.8)'
},
{ // lile
backgroundColor: 'rgba(180, 137, 255, 0.2)',
borderColor: 'rgba(180, 137, 255, 1)',
pointBackgroundColor: 'rgba(180, 137, 255, 1)',
pointBorderColor: '#fff',
pointHoverBackgroundColor: '#fff',
pointHoverBorderColor: 'rgba(180, 137, 255, 0.8)'
}
]
}
}

View File

@ -0,0 +1,4 @@
export class ChartData {
data: Array<number>;
label: string;
}

View File

@ -0,0 +1,8 @@
export class MetaInfoData {
date: string;
header: Array<string>;
name: string;
rowDesc: string;
TotalDesc: string;
}

View File

@ -0,0 +1,8 @@
import { ReportInfoData } from './report-info-data';
import { MetaInfoData } from './meta-info-data';
export class ReportData {
meta: MetaInfoData;
rows: Map<string, ReportInfoData>;
sumRow: ReportInfoData;
}

View File

@ -0,0 +1,3 @@
export class ReportInfoData {
cells: Map<string, number>;
}

View File

@ -1,10 +1,27 @@
<div class="container">
<tabset #staticTabs>
<tab heading="Tasks">
<taskana-tasks></taskana-tasks>
</tab>
<tab heading="Workbaskets">
<taskana-workbasket></taskana-workbasket>
</tab>
</tabset>
<ul class="nav nav-tabs" role="tablist">
<li>
<a style="display: none"></a>
</li>
<li role="presentation" class="active">
<a href="#tasks-tab" data-toggle="tab" aria-controls="Tasks" role="tab" aria-expanded="true">Tasks</a>
</li>
<li role="presentation">
<a href="#workbaskets-tab" data-toggle="tab" aria-controls="Workbaskets" role="tab" aria-expanded="true">Workbaskets</a>
</li>
<li>
<a href="#classifications-tab" data-toggle="tab" aria-controls="Classifications" role="tab" data-toggle="tab" aria-expanded="true">Classifications</a>
</li>
</ul>
<div class="tab-content">
<div role="tabpanel" class="tab-pane active" id="tasks-tab">
<taskana-monitor-tasks></taskana-monitor-tasks>
</div>
<div role="tabpanel" class="tab-pane" id="workbaskets-tab">
<taskana-monitor-workbaskets></taskana-monitor-workbaskets>
</div>
<div role="tabpanel" class="tab-pane" id="classifications-tab">
<taskana-monitor-classification-tasks></taskana-monitor-classification-tasks>
</div>
</div>
</div>

View File

@ -7,12 +7,13 @@ import { TabsModule } from 'ngx-bootstrap/tabs';
import { HttpClientModule } from '@angular/common/http';
import { AngularSvgIconModule } from 'angular-svg-icon';
import { MonitorRoutingModule } from './monitor-routing.module';
import { SharedModule } from 'app/shared/shared.module';
import { SharedModule } from '../shared/shared.module';
import { TasksComponent } from './tasks/tasks.component';
import { WorkbasketComponent } from './workbasket/workbasket.component';
import { ReportComponent } from './report/report.component';
import { MonitorComponent } from './monitor.component';
import { TasksComponent } from './tasks/tasks.component';
import { WorkbasketComponent } from './workbasket/workbasket.component';
import { ClassificationTasksComponent } from './classification-tasks/classification-tasks.component';
import { RestConnectorService } from './services/restConnector/rest-connector.service';
@ -31,7 +32,8 @@ const DECLARATIONS = [
TasksComponent,
WorkbasketComponent,
ReportComponent,
MonitorComponent
MonitorComponent,
ClassificationTasksComponent
];
@NgModule({

View File

@ -1,22 +1,28 @@
<div class="row" *ngIf="isDataAvailable">
<div class="row report" *ngIf="reportData">
<div class="col-sm-12" style="margin-bottom: 10px">
<h4>{{meta.name}} ({{meta.date | date : 'dd.MM.yyyy HH:mm:ss'}})</h4>
<table class="table table-responsive table-condensed">
<tr>
<th>{{meta.rowDesc}}</th>
<th *ngFor="let header of meta.header">{{header}}</th>
<th>{{meta.totalDesc}}</th>
</tr>
<tr *ngFor="let row of rows | mapToIterable | orderBy:['key']">
<td>{{row.key}}</td>
<td *ngFor="let header of meta.header">{{row.val.cells[header]}}</td>
<th>{{row.val.total}}</th>
</tr>
<tr>
<th>{{meta.totalDesc}}</th>
<th *ngFor="let header of meta.header">{{sumRow.cells[header]}}</th>
<th>{{sumRow.total}}</th>
</tr>
<table class="table table-responsive table-condensed table-striped">
<thead>
<tr>
<th>{{reportData.meta.rowDesc}}</th>
<th class="align-center" *ngFor="let header of reportData.meta.header">
{{header}}</th>
<th class="align-center">{{reportData.meta.totalDesc}}</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let row of reportData.rows | mapToIterable | orderBy:['key']">
<td>{{row.key}}</td>
<td *ngFor="let header of reportData.meta.header" class="align-center">{{row.val.cells[header]}}</td>
<th class="align-center">{{row.val.total}}</th>
</tr>
</tbody>
<tfoot>
<tr>
<th>{{reportData.meta.totalDesc}}</th>
<th *ngFor="let header of reportData.meta.header" class="align-center">{{reportData.sumRow.cells[header]}}</th>
<th class="align-center">{{reportData.sumRow.total}}</th>
</tr>
</tfoot>
</table>
</div>
</div>

View File

@ -0,0 +1,3 @@
.report{
padding-top: 20px;
}

View File

@ -1,55 +1,26 @@
import { Component, Input, OnInit } from '@angular/core';
import { RestConnectorService } from 'app/monitor/services/restConnector/rest-connector.service';
import { error } from 'util';
import { ReportType } from './reportType';
import { ReportData } from 'app/monitor/models/report-data';
import { RestConnectorService } from 'app/monitor/services/restConnector/rest-connector.service';
@Component({
selector: 'taskana-report',
templateUrl: './report.component.html'
templateUrl: './report.component.html',
styleUrls: ['./report.component.scss']
})
export class ReportComponent implements OnInit {
@Input()
type: ReportType;
@Input()
reportData: ReportData
meta: ReportMeta;
/*
* The keys of the rows object are unknown. They represent the name of that specific row.
* Each row (value of rows Object) has two keys: 'cells:Object' and 'total:number'.
* The keys of 'cells' are the same as 'meta.header:number'.
* This also applies to sumRow.
*/
rows: Object;
sumRow: Object;
isDataAvailable = false;
reportType = ReportType;
constructor(private restConnector: RestConnectorService) {
}
ngOnInit(): void {
switch (this.type) {
case ReportType.WorkbasketStatus:
this.restConnector.getTaskStatusReport().subscribe(res => {
this.meta = res['meta'];
this.rows = res['rows'];
this.sumRow = res['sumRow'];
this.isDataAvailable = true;
});
break;
default:
error(`unknown ReportType ${this.type}`);
}
}
}
class ReportMeta {
name: string;
date: string;
header: Array<string>;
rowDesc: string;
totalDesc: string;
}

View File

@ -1,3 +1,5 @@
export enum ReportType {
WorkbasketStatus
TasksStatus,
WorkbasketStatus,
ClassificationStatus
}

View File

@ -1,9 +1,9 @@
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { environment } from '../../../../environments/environment';
import { HttpClient } from '@angular/common/http';
import { environment } from 'environments/environment';
import { Observable } from 'rxjs';
import { State } from 'app/models/state';
import { WorkbasketCounter } from 'app/monitor/models/workbasket-counter';
import { ReportData } from '../../models/report-data';
import { ChartData } from 'app/monitor/models/chart-data';
@Injectable()
export class RestConnectorService {
@ -11,18 +11,44 @@ export class RestConnectorService {
constructor(private httpClient: HttpClient) {
}
getTaskStatistics(): Observable<State[]> {
return this.httpClient.get<Array<State>>(environment.taskanaRestUrl + '/v1/monitor/countByState?states=READY,CLAIMED,COMPLETED')
getTaskStatusReport(): Observable<ReportData> {
return this.httpClient.get<ReportData>(environment.taskanaRestUrl + '/v1/monitor/tasks-status-report?states=READY,CLAIMED,COMPLETED')
}
getWorkbasketStatistics(): Observable<WorkbasketCounter> {
return this.httpClient.get<WorkbasketCounter>(environment.taskanaRestUrl
+ '/v1/monitor/taskcountByWorkbasketDaysAndState?daysInPast=5&states=READY,CLAIMED,COMPLETED')
getWorkbasketStatistics(): Observable<ReportData> {
return this.httpClient.get<ReportData>(environment.taskanaRestUrl
+ '/v1/monitor/tasks-workbasket-report?daysInPast=5&states=READY,CLAIMED,COMPLETED');
}
getTaskStatusReport(): Observable<Object> {
return this.httpClient.get(environment.taskanaRestUrl + '/v1/monitor/taskStatusReport')
getClassificationTasksReport(): Observable<ReportData> {
return this.httpClient.get<ReportData>(environment.taskanaRestUrl
+ '/v1/monitor/tasks-classification-report');
}
getChartData(source: ReportData): Array<ChartData> {
const result = new Array<ChartData>();
Object.keys(source.rows).forEach(key => {
const rowData = new ChartData();
rowData.label = key;
rowData.data = new Array<number>();
source.meta.header.forEach((headerValue: string) => {
rowData.data.push(source.rows[key].cells[headerValue]);
})
result.push(rowData)
})
return result;
}
getChartHeaders(source: ReportData): Array<string> {
const result = new Array<string>();
source.meta.header.forEach((header: string) => {
result.push(header);
})
return result;
}
}

View File

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

View File

@ -1,9 +1,10 @@
import { Component, OnInit } from '@angular/core';
import { ReportType } from '../report/reportType';
import { RestConnectorService } from '../services/restConnector/rest-connector.service';
import { ReportData } from 'app/monitor/models/report-data';
@Component({
selector: 'taskana-tasks',
selector: 'taskana-monitor-tasks',
templateUrl: './tasks.component.html',
styleUrls: ['./tasks.component.scss'],
})
@ -13,30 +14,20 @@ export class TasksComponent implements OnInit {
pieChartLabels: string[] = ['Ready', 'Claimed', 'Completed'];
pieChartData: number[] = [];
pieChartType = 'pie';
isDataAvailable = false;
reportType = ReportType.WorkbasketStatus;
reportData: ReportData
reportType = ReportType.TasksStatus;
constructor(private restConnectorService: RestConnectorService) {
}
ngOnInit() {
this.restConnectorService.getTaskStatistics().subscribe(data => {
if (data.find(x => x.state === 'READY') !== null) {
this.pieChartData.push(data.find(x => x.state === 'READY').counter);
} else {
this.pieChartData.push(0);
}
if (data.find(x => x.state === 'CLAIMED') !== null) {
this.pieChartData.push(data.find(x => x.state === 'CLAIMED').counter);
} else {
this.pieChartData.push(0);
}
if (data.find(x => x.state === 'COMPLETED') !== null) {
this.pieChartData.push(data.find(x => x.state === 'COMPLETED').counter);
} else {
this.pieChartData.push(0);
}
this.isDataAvailable = true;
});
this.restConnectorService.getTaskStatusReport().subscribe((data: ReportData) => {
this.reportData = data;
Object.keys(data.sumRow.cells).forEach(key => {
this.pieChartData.push(data.sumRow.cells[key]);
})
})
}
}

View File

@ -1,22 +1,16 @@
<div class="row" *ngIf="isDataAvailable">
<div class="col-md-12" style="margin-bottom: 10px">
<table class="table table-responsive table-condensed">
<tr>
<th>Workbaskets</th>
<th *ngFor="let label of lineChartLabels">{{label}}</th>
</tr>
<tr *ngFor="let d of lineChartData">
<td>{{d.label}}</td>
<td *ngFor="let label of lineChartLabels; let j=index">{{d && d.data[j]}}</td>
</tr>
</table>
<div *ngIf="reportData" class="panel panel-default">
<div class="panel-heading">
<h4>{{reportData.meta.name}} ({{reportData.meta.date | date : 'dd.MM.yyyy HH:mm:ss'}})</h4>
</div>
<div class="panel-body">
<div class="row">
<div class="col-xs-12 col-md-8 col-md-offset-2">
<div style="display: block;">
<canvas baseChart [datasets]="lineChartData" [labels]="lineChartLabels" [options]="lineChartOptions"
[colors]="lineChartColors" [legend]="lineChartLegend" [chartType]="lineChartType"></canvas>
</div>
</div>
</div>
<taskana-report [type]="reportType" [reportData]="reportData"></taskana-report>
</div>
</div>
<div class="row" *ngIf="isDataAvailable">
<div class="col-md-12">
<div style="display: block;">
<canvas baseChart width="400" height="400" [datasets]="lineChartData" [labels]="lineChartLabels" [options]="lineChartOptions"
[colors]="lineChartColors" [legend]="lineChartLegend" [chartType]="lineChartType"></canvas>
</div>
</div>
</div>

View File

@ -1,60 +1,39 @@
import { Component, OnInit } from '@angular/core';
import { RestConnectorService } from 'app/monitor/services/restConnector/rest-connector.service';
import { WorkbasketCounter } from 'app/monitor/models/workbasket-counter';
import { WorkbasketCounterData } from 'app/monitor/models/workbasket-counter-data';
import { ChartColorsDefinition } from '../models/chart-colors';
import { ReportData } from 'app/monitor/models/report-data';
import { ReportType } from 'app/monitor/report/reportType';
import { ChartData } from 'app/monitor/models/chart-data';
@Component({
selector: 'taskana-workbasket',
selector: 'taskana-monitor-workbaskets',
templateUrl: './workbasket.component.html',
styleUrls: ['./workbasket.component.scss'],
providers: [RestConnectorService]
})
export class WorkbasketComponent implements OnInit {
isDataAvailable = false;
reportType = ReportType.WorkbasketStatus;
reportData: ReportData;
lineChartLabels: Array<any>;
lineChartLegend = true;
lineChartType = 'line';
lineChartData: Array<WorkbasketCounterData>;
lineChartData: Array<ChartData>;
lineChartOptions: any = {
responsive: true
};
lineChartColors: Array<any> = [
{ // grey
backgroundColor: 'rgba(148,159,177,0.2)',
borderColor: 'rgba(148,159,177,1)',
pointBackgroundColor: 'rgba(148,159,177,1)',
pointBorderColor: '#fff',
pointHoverBackgroundColor: '#fff',
pointHoverBorderColor: 'rgba(148,159,177,0.8)'
},
{ // dark grey
backgroundColor: 'rgba(77,83,96,0.2)',
borderColor: 'rgba(77,83,96,1)',
pointBackgroundColor: 'rgba(77,83,96,1)',
pointBorderColor: '#fff',
pointHoverBackgroundColor: '#fff',
pointHoverBorderColor: 'rgba(77,83,96,1)'
},
{ // grey
backgroundColor: 'rgba(148,159,177,0.2)',
borderColor: 'rgba(148,159,177,1)',
pointBackgroundColor: 'rgba(148,159,177,1)',
pointBorderColor: '#fff',
pointHoverBackgroundColor: '#fff',
pointHoverBorderColor: 'rgba(148,159,177,0.8)'
}
];
private counter: WorkbasketCounter;
lineChartColors = ChartColorsDefinition.getColors();
constructor(private restConnectorService: RestConnectorService) { }
ngOnInit() {
this.restConnectorService.getWorkbasketStatistics().subscribe(data => {
this.lineChartLabels = data.dates;
this.lineChartData = data.data;
this.isDataAvailable = true;
});
this.restConnectorService.getWorkbasketStatistics().subscribe((data: ReportData) => {
this.reportData = data;
this.lineChartLabels = this.restConnectorService.getChartHeaders(data);
this.lineChartData = this.restConnectorService.getChartData(data);
})
}
}

View File

@ -7,4 +7,11 @@ export class TaskanaDate {
const datePipe = new DatePipe(dateLocale);
return datePipe.transform(Date.now(), dateFormat) + 'Z';
}
public static convertSimpleDate(date: Date): string {
const dateFormat = 'yyyy-MM-dd';
const dateLocale = 'en-US';
const datePipe = new DatePipe(dateLocale);
return datePipe.transform(date, dateFormat);
}
}

View File

@ -0,0 +1,9 @@
@import 'variables';
@import '../../node_modules/bootstrap-sass/assets/stylesheets/_bootstrap';
@import '../../node_modules/angular-tree-component/dist/angular-tree-component.css';
@import 'site';
@import 'forms';
@import 'tree';
@import 'type-ahead';
@import 'checkboxes';
@import 'tabs';

View File

@ -272,7 +272,7 @@ svg-icon.fa-fw > svg {
}
taskana-workbasket-information, taskana-workbasket-access-items, taskana-workbaskets-distribution-targets {
taskana-workbasket-information, taskana-workbasket-access-items, taskana-workbaskets-distribution-targets, taskana-monitor-tasks, taskana-monitor-workbaskets, taskana-monitor-classification-tasks {
&> .panel{
border: none;
box-shadow: none;
@ -285,6 +285,15 @@ taskana-workbasket-information, taskana-workbasket-access-items, taskana-workbas
}
}
taskana-monitor-tasks, taskana-monitor-workbaskets, taskana-monitor-classification-tasks {
&> .panel {
&> .panel-heading {
border-left: 1px solid #ddd;
border-right: 1px solid #ddd;
}
}
}
li.list-group-item.active:hover, {
color: #fff;
background-color: $green;
@ -323,3 +332,7 @@ li.list-group-item:hover, {
.center-block {
text-align: center;
}
.align-center {
text-align: center;
}

32
web/src/assets/_tabs.scss Normal file
View File

@ -0,0 +1,32 @@
.nav.nav-tabs {
& > li {
& > a {
min-height: 52px;
padding-top: 15px;
border-radius: 0px;
&.has-changes{
border-bottom: solid #f0ad4e;
}
cursor: pointer;
}
&:first-child > a{
border-left: none;
}
}
& > li.active > a {
border-top: 3px solid #479ea9;
padding-top: 13px;
background-color: #f5f5f5;
}
& > p{
margin: 0px;
}
& > li.disabled {
cursor: not-allowed;
}
& > li.disabled > a {
pointer-events: none;
}
}

View File

@ -1,8 +1,8 @@
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
import { environment } from './environments/environment';
import { AppModule } from 'app/app.module';
import { environment } from 'environments/environment';
if (environment.production) {
enableProdMode();