From 4e773b9fbfe316fe9a838b37d7fd3361c058ea19 Mon Sep 17 00:00:00 2001 From: Mustapha Zorgati Date: Wed, 3 Apr 2019 17:06:42 +0200 Subject: [PATCH] TSK-843 designed report table and made single row collapsable --- .../MonitorControllerRestDocumentation.java | 10 ++-- .../app/monitor/models/report-info-data.ts | 1 + web/src/app/monitor/monitor.module.ts | 6 +-- .../app/monitor/report/report.component.html | 20 ++++---- .../app/monitor/report/report.component.ts | 10 ++-- .../app/monitor/report/row/row.component.html | 25 ++++++---- .../app/monitor/report/row/row.component.scss | 15 ++++++ .../app/monitor/report/row/row.component.ts | 46 +++++++++++++------ .../monitor/timestamp/timestamp.component.ts | 4 +- web/src/assets/_table.scss | 9 ++++ 10 files changed, 101 insertions(+), 45 deletions(-) diff --git a/rest/taskana-rest-spring-test/src/test/java/pro/taskana/doc/api/MonitorControllerRestDocumentation.java b/rest/taskana-rest-spring-test/src/test/java/pro/taskana/doc/api/MonitorControllerRestDocumentation.java index b16e10ca9..c3e05ef03 100644 --- a/rest/taskana-rest-spring-test/src/test/java/pro/taskana/doc/api/MonitorControllerRestDocumentation.java +++ b/rest/taskana-rest-spring-test/src/test/java/pro/taskana/doc/api/MonitorControllerRestDocumentation.java @@ -38,12 +38,10 @@ import pro.taskana.rest.RestConfiguration; @SpringBootTest(classes = RestConfiguration.class, webEnvironment = WebEnvironment.RANDOM_PORT) public class MonitorControllerRestDocumentation { - @LocalServerPort - int port; - @Rule public JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation(); - + @LocalServerPort + int port; @Autowired private WebApplicationContext context; @@ -70,6 +68,8 @@ public class MonitorControllerRestDocumentation { fieldWithPath("meta.name").description("Name of the report"), fieldWithPath("meta.date").description("Date of the report creation"), fieldWithPath("meta.header").description("Column-headers of the report"), + fieldWithPath("meta.expHeader").description( + "Expandable Column-headers which match the depth of the foldable rows within the report."), fieldWithPath("meta.rowDesc").description("Descriptions for the rows the report"), fieldWithPath("meta.totalDesc").description("Description for the report itself"), subsectionWithPath("rows").description("Object holding the rows of the report.\n" @@ -77,7 +77,7 @@ public class MonitorControllerRestDocumentation { fieldWithPath("sumRow").description("Object holding the sums in the columns over all rows"), subsectionWithPath("sumRow.cells") .description("Contains the accumulated numbers over all columns defined in meta.header.\n" - + "For the exact structure please check the example response above"), + + "For the exact structure please check the example response above"), fieldWithPath("sumRow.total").description("Total number of tasks"), fieldWithPath("_links.self.href").ignored() }; diff --git a/web/src/app/monitor/models/report-info-data.ts b/web/src/app/monitor/models/report-info-data.ts index c69041d7b..19eb2f288 100644 --- a/web/src/app/monitor/models/report-info-data.ts +++ b/web/src/app/monitor/models/report-info-data.ts @@ -8,4 +8,5 @@ export class ReportInfoDataIterable { key: string; val: ReportInfoData; depth: number; + display = false; } diff --git a/web/src/app/monitor/monitor.module.ts b/web/src/app/monitor/monitor.module.ts index d988d3c6d..0850bb3b6 100644 --- a/web/src/app/monitor/monitor.module.ts +++ b/web/src/app/monitor/monitor.module.ts @@ -14,12 +14,12 @@ 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 {ReportRowComponent} from "./report/row/row.component"; -import {TimestampComponent} from "./timestamp/timestamp.component"; +import {ReportRowComponent} from './report/row/row.component'; +import {TimestampComponent} from './timestamp/timestamp.component'; import {RestConnectorService} from './services/restConnector/rest-connector.service'; -import {MapToIterable} from "../shared/pipes/mapToIterable/mapToIterable"; +import {MapToIterable} from '../shared/pipes/mapToIterable/mapToIterable'; const MODULES = [ CommonModule, diff --git a/web/src/app/monitor/report/report.component.html b/web/src/app/monitor/report/report.component.html index 0770b6b2e..0eb074d74 100644 --- a/web/src/app/monitor/report/report.component.html +++ b/web/src/app/monitor/report/report.component.html @@ -1,26 +1,30 @@
-
{{reportData.meta.rowDesc}}
+
{{reportData.meta.rowDesc}}
-
{{header}}
+
{{header}}
-
{{header}}
-
{{reportData.meta.totalDesc}}
+
{{header}}
+
{{reportData.meta.totalDesc}}
- - + + class="table-footer">
diff --git a/web/src/app/monitor/report/report.component.ts b/web/src/app/monitor/report/report.component.ts index d42e3ab0d..047037f23 100644 --- a/web/src/app/monitor/report/report.component.ts +++ b/web/src/app/monitor/report/report.component.ts @@ -1,6 +1,6 @@ import {Component, Input, OnInit} from '@angular/core'; import {ReportData} from 'app/monitor/models/report-data'; -import {ReportInfoDataIterable} from "../models/report-info-data"; +import {ReportInfoDataIterable} from '../models/report-info-data'; @Component({ selector: 'taskana-report', @@ -11,12 +11,9 @@ export class ReportComponent implements OnInit { expHeaders: Array; - currentExpHeaders: number = 0; + currentExpHeaders = 0; _sumRow: ReportInfoDataIterable; - constructor() { - } - private _reportData: ReportData; get reportData(): ReportData { @@ -32,6 +29,9 @@ export class ReportComponent implements OnInit { this._sumRow.key = reportData.meta.totalDesc; } + constructor() { + } + ngOnInit(): void { } diff --git a/web/src/app/monitor/report/row/row.component.html b/web/src/app/monitor/report/row/row.component.html index 2bb5230ef..bd126e8f1 100644 --- a/web/src/app/monitor/report/row/row.component.html +++ b/web/src/app/monitor/report/row/row.component.html @@ -1,19 +1,28 @@ -
+
-
- {{row.key}} + {{ canRowCollapse(i) ? "expand_more" : "expand_less"}}{{row.key}}
-
-
+
+
{{row.val.cells[header]}}
-
+
{{row.val.total}}
- + \ No newline at end of file diff --git a/web/src/app/monitor/report/row/row.component.scss b/web/src/app/monitor/report/row/row.component.scss index c92ef7adc..5c05b6101 100644 --- a/web/src/app/monitor/report/row/row.component.scss +++ b/web/src/app/monitor/report/row/row.component.scss @@ -1,4 +1,19 @@ +@import './src/assets/_colors'; + .table-cell--clickable { cursor: pointer; +} + +.table-row--highlight, +.table-row--hover:hover { + background-color: #f9f9f9; +} + +.table-row--highlight > .table-cell { + border-bottom: 2px solid #ddd; +} + +.table-row--white { + background-color: white; } \ No newline at end of file diff --git a/web/src/app/monitor/report/row/row.component.ts b/web/src/app/monitor/report/row/row.component.ts index 9ec66ef68..898e91206 100644 --- a/web/src/app/monitor/report/row/row.component.ts +++ b/web/src/app/monitor/report/row/row.component.ts @@ -1,9 +1,9 @@ import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core'; -import {ReportInfoDataIterable} from "../../models/report-info-data"; -import {MapToIterable} from "../../../shared/pipes/mapToIterable/mapToIterable"; +import {ReportInfoDataIterable} from '../../models/report-info-data'; +import {MapToIterable} from '../../../shared/pipes/mapToIterable/mapToIterable'; @Component({ - selector: 'monitor-report-row', + selector: 'taskana-report-row', templateUrl: './row.component.html', styleUrls: ['./row.component.scss'] }) @@ -12,19 +12,15 @@ export class ReportRowComponent implements OnInit { @Input() headers: Array; @Input() - bold: boolean = false; + bold = false; @Input() - maxTableDepth: number = 0; + maxTableDepth = 0; @Output() expandedDepth: EventEmitter = new EventEmitter(); + currentDepth = 0; maxDepth: number; - currentDepth: number = 0; flatRows: Array; - constructor(private mapToIterable: MapToIterable) { - } - - private _row: ReportInfoDataIterable; get row(): ReportInfoDataIterable { @@ -38,25 +34,47 @@ export class ReportRowComponent implements OnInit { this.maxDepth = this.flatten(row, 0); } + constructor(private mapToIterable: MapToIterable) { + } + ngOnInit() { } - toggleFold(depth: number) { - this.currentDepth = depth == this.currentDepth && depth < this.maxDepth ? depth + 1 : depth; - this.expandedDepth.emit(this.currentDepth); + toggleFold(index: number): void { + const toggleRow = this.flatRows[index++]; + if (toggleRow.depth < this.maxDepth) { + const firstChildRow = this.flatRows[index++]; + firstChildRow.display = !firstChildRow.display; + + let end = false; + for (let i = index; i < this.flatRows.length && !end; i++) { + const row = this.flatRows[i]; + end = row.depth <= toggleRow.depth; + if (!end) { + row.display = firstChildRow.display && row.depth === firstChildRow.depth; + } + } + this.currentDepth = Math.max(...this.flatRows.filter(r => r.display).map(r => r.depth)); + this.expandedDepth.emit(this.currentDepth); + } } range(depth: number): Array { return new Array(Math.max(depth, 0)); } + canRowCollapse(index: number) { + return !this.flatRows[index + 1].display; + } + private flatten(row: ReportInfoDataIterable, depth: number): number { row.depth = depth; + row.display = depth === 0; this.flatRows.push(row); if (row.val.foldableRows) { depth = Math.max(...this.mapToIterable.transform(row.val.foldableRows) .sort((a, b) => a.key.localeCompare(b.key)) - .map(r => this.flatten(r, depth + 1))) + .map(r => this.flatten(r, depth + 1))); } return depth; } diff --git a/web/src/app/monitor/timestamp/timestamp.component.ts b/web/src/app/monitor/timestamp/timestamp.component.ts index 9bd38386c..0d28750c4 100644 --- a/web/src/app/monitor/timestamp/timestamp.component.ts +++ b/web/src/app/monitor/timestamp/timestamp.component.ts @@ -1,6 +1,6 @@ import {Component, OnInit} from '@angular/core'; -import {ReportData} from "../models/report-data"; -import {RestConnectorService} from "../services/restConnector/rest-connector.service"; +import {ReportData} from '../models/report-data'; +import {RestConnectorService} from '../services/restConnector/rest-connector.service'; @Component({ selector: 'taskana-monitor-timestamp', diff --git a/web/src/assets/_table.scss b/web/src/assets/_table.scss index fbcd1cd92..485ceda62 100644 --- a/web/src/assets/_table.scss +++ b/web/src/assets/_table.scss @@ -72,3 +72,12 @@ min-width: 0; } + +.table-cell--border-right { + border-right: 2px solid #ddd; +} + + +.table-cell--border-left { + border-left: 2px solid #ddd; +} \ No newline at end of file