issue-25 #27
@ -66,6 +66,7 @@ import { DashboardComponent } from './dashboard/dashboard.component';
|
|||||||
import { ActiveScheduleComponent } from './dashboard/active-schedule/active-schedule.component';
|
import { ActiveScheduleComponent } from './dashboard/active-schedule/active-schedule.component';
|
||||||
import {MatTreeModule} from "@angular/material/tree";
|
import {MatTreeModule} from "@angular/material/tree";
|
||||||
import { TaskgroupOverviewComponent } from './dashboard/taskgroup-overview/taskgroup-overview.component';
|
import { TaskgroupOverviewComponent } from './dashboard/taskgroup-overview/taskgroup-overview.component';
|
||||||
|
import { TaskOverviewComponent } from './dashboard/task-overview/task-overview.component';
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
AppComponent,
|
AppComponent,
|
||||||
@ -95,7 +96,8 @@ import { TaskgroupOverviewComponent } from './dashboard/taskgroup-overview/taskg
|
|||||||
ScheduleDashboardComponent,
|
ScheduleDashboardComponent,
|
||||||
DashboardComponent,
|
DashboardComponent,
|
||||||
ActiveScheduleComponent,
|
ActiveScheduleComponent,
|
||||||
TaskgroupOverviewComponent
|
TaskgroupOverviewComponent,
|
||||||
|
TaskOverviewComponent
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
BrowserModule,
|
BrowserModule,
|
||||||
|
@ -75,8 +75,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.taskgroup-overview {
|
.taskgroup-overview {
|
||||||
width: 25%;
|
width: 30%;
|
||||||
float: right;
|
float: right;
|
||||||
|
margin-right: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.spacer {
|
.spacer {
|
||||||
|
@ -38,10 +38,13 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<span class="spacer"></span>
|
<div class="taskgroup-overview">
|
||||||
|
<app-task-overview [tasks]="tasks"></app-task-overview>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="taskgroup-overview">
|
<div class="taskgroup-overview">
|
||||||
<app-taskgroup-overview></app-taskgroup-overview>
|
|
||||||
|
<app-taskgroup-overview (taskgroupSelected)="onSelectTaskgroup($event)"></app-taskgroup-overview>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
import {Component, OnInit, ViewChild} from '@angular/core';
|
import {Component, OnInit, ViewChild} from '@angular/core';
|
||||||
import {ScheduleInfo, ScheduleService} from "../../api";
|
import {ScheduleInfo, ScheduleService, TaskOverviewInfo} from "../../api";
|
||||||
import {ActiveScheduleComponent} from "./active-schedule/active-schedule.component";
|
import {ActiveScheduleComponent} from "./active-schedule/active-schedule.component";
|
||||||
import {StopActiveScheduleInfo} from "./active-schedule/StopActiveScheduleInfo";
|
import {StopActiveScheduleInfo} from "./active-schedule/StopActiveScheduleInfo";
|
||||||
|
import {TaskOverviewComponent} from "./task-overview/task-overview.component";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-dashboard',
|
selector: 'app-dashboard',
|
||||||
@ -14,6 +15,8 @@ export class DashboardComponent implements OnInit{
|
|||||||
schedules: ScheduleInfo[] = []
|
schedules: ScheduleInfo[] = []
|
||||||
workedMinutesToday: number = 0
|
workedMinutesToday: number = 0
|
||||||
|
|
||||||
|
tasks: TaskOverviewInfo[] = []
|
||||||
|
|
||||||
@ViewChild('activeSchedule') activeScheduleComponent: ActiveScheduleComponent | undefined
|
@ViewChild('activeSchedule') activeScheduleComponent: ActiveScheduleComponent | undefined
|
||||||
constructor(private scheduleService: ScheduleService) {
|
constructor(private scheduleService: ScheduleService) {
|
||||||
}
|
}
|
||||||
@ -44,4 +47,9 @@ export class DashboardComponent implements OnInit{
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected readonly TaskOverviewComponent = TaskOverviewComponent;
|
||||||
|
|
||||||
|
onSelectTaskgroup(tasks: TaskOverviewInfo[]) {
|
||||||
|
this.tasks = tasks;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,28 @@
|
|||||||
|
.greenBtn {
|
||||||
|
background-color: #00bc8c;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-without-radius {
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.task-info {
|
||||||
|
line-height: .75em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.progress {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
margin-top: -5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.long-btn {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.yellowBtn {
|
||||||
|
background-color: #f39c12;
|
||||||
|
color: white;
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
<button mat-raised-button class="greenBtn long-btn" *ngIf="tasks.length > 0">Add</button>
|
||||||
|
<mat-card *ngFor="let task of tasks">
|
||||||
|
<mat-card-content>
|
||||||
|
<h3>{{task.taskName}}</h3>
|
||||||
|
<mat-progress-bar mode="determinate" value="{{task.activeTime}}" class="progress"></mat-progress-bar>
|
||||||
|
<p class="task-info"><i>ETA: </i>{{task.activeTime}} / {{task.eta}}</p>
|
||||||
|
<p class="task-info"><i>Limit: </i>{{task.limit}}</p>
|
||||||
|
</mat-card-content>
|
||||||
|
<mat-card-actions>
|
||||||
|
<button mat-raised-button color="primary" class="btn-without-radius">Start now</button>
|
||||||
|
<button mat-raised-button class="yellowBtn btn-without-radius">Schedule</button>
|
||||||
|
<button mat-raised-button class="greenBtn btn-without-radius">Finish</button>
|
||||||
|
</mat-card-actions>
|
||||||
|
</mat-card>
|
@ -0,0 +1,21 @@
|
|||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { TaskOverviewComponent } from './task-overview.component';
|
||||||
|
|
||||||
|
describe('TaskOverviewComponent', () => {
|
||||||
|
let component: TaskOverviewComponent;
|
||||||
|
let fixture: ComponentFixture<TaskOverviewComponent>;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [TaskOverviewComponent]
|
||||||
|
});
|
||||||
|
fixture = TestBed.createComponent(TaskOverviewComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
@ -0,0 +1,12 @@
|
|||||||
|
import {Component, Input} from '@angular/core';
|
||||||
|
import {TaskOverviewInfo} from "../../../api";
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-task-overview',
|
||||||
|
templateUrl: './task-overview.component.html',
|
||||||
|
styleUrls: ['./task-overview.component.css']
|
||||||
|
})
|
||||||
|
export class TaskOverviewComponent {
|
||||||
|
|
||||||
|
@Input() tasks: TaskOverviewInfo[] = []
|
||||||
|
}
|
@ -163,5 +163,5 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.overdue-taskgroup {
|
.overdue-taskgroup {
|
||||||
background-color: #ff6354;
|
background-color: #ff695b;
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
<!-- use a disabled button to provide padding for tree leaf -->
|
<!-- use a disabled button to provide padding for tree leaf -->
|
||||||
<button mat-icon-button disabled></button>
|
<button mat-icon-button disabled></button>
|
||||||
<div class="treenode-content-container">
|
<div class="treenode-content-container">
|
||||||
<button mat-button class="node-name">{{node.name}}</button>
|
<button mat-button class="node-name" (click)="onSelectTaskgroup(node.tasks)">{{node.name}}</button>
|
||||||
<span class="spacer"></span>
|
<span class="spacer"></span>
|
||||||
<div class="task-number">{{node.activeTasks}}</div>
|
<div class="task-number">{{node.activeTasks}}</div>
|
||||||
</div>
|
</div>
|
||||||
@ -21,10 +21,9 @@
|
|||||||
</mat-icon>
|
</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
<div class="treenode-content-container">
|
<div class="treenode-content-container">
|
||||||
<button mat-button class="node-name">{{node.name}}</button>
|
<button mat-button class="node-name" (click)="onSelectTaskgroup(node.tasks)">{{node.name}}</button>
|
||||||
<span class="spacer"></span>
|
<span class="spacer"></span>
|
||||||
<div class="task-number">{{node.activeTasks}}</div>
|
<div class="task-number">{{node.activeTasks}}</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</mat-tree-node>
|
</mat-tree-node>
|
||||||
</mat-tree>
|
</mat-tree>
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
import { Component } from '@angular/core';
|
import {Component, EventEmitter, Output} from '@angular/core';
|
||||||
import {MatIconModule} from "@angular/material/icon";
|
import {MatIconModule} from "@angular/material/icon";
|
||||||
import {MatButtonModule} from "@angular/material/button";
|
import {MatButtonModule} from "@angular/material/button";
|
||||||
import {MatTreeFlatDataSource, MatTreeFlattener, MatTreeModule} from "@angular/material/tree";
|
import {MatTreeFlatDataSource, MatTreeFlattener, MatTreeModule} from "@angular/material/tree";
|
||||||
import {FlatTreeControl} from "@angular/cdk/tree";
|
import {FlatTreeControl} from "@angular/cdk/tree";
|
||||||
import {RecursiveTaskgroupInfo, TaskgroupService} from "../../../api";
|
import {RecursiveTaskgroupInfo, TaskgroupService, TaskOverviewInfo} from "../../../api";
|
||||||
|
import {TaskOverviewComponent} from "../task-overview/task-overview.component";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -11,10 +12,11 @@ import {RecursiveTaskgroupInfo, TaskgroupService} from "../../../api";
|
|||||||
/** Flat node with expandable and level information */
|
/** Flat node with expandable and level information */
|
||||||
interface ExampleFlatNode {
|
interface ExampleFlatNode {
|
||||||
expandable: boolean;
|
expandable: boolean;
|
||||||
name: string;
|
|
||||||
level: number;
|
level: number;
|
||||||
|
name: string
|
||||||
activeTasks: number;
|
activeTasks: number;
|
||||||
hasOverdueTask: boolean
|
hasOverdueTask: boolean;
|
||||||
|
tasks: TaskOverviewInfo[];
|
||||||
}
|
}
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-taskgroup-overview',
|
selector: 'app-taskgroup-overview',
|
||||||
@ -22,13 +24,16 @@ interface ExampleFlatNode {
|
|||||||
styleUrls: ['./taskgroup-overview.component.css']
|
styleUrls: ['./taskgroup-overview.component.css']
|
||||||
})
|
})
|
||||||
export class TaskgroupOverviewComponent {
|
export class TaskgroupOverviewComponent {
|
||||||
|
|
||||||
|
@Output('taskgroupSelected') taskgroupSelected: EventEmitter<TaskOverviewInfo[]> = new EventEmitter<TaskOverviewInfo[]>();
|
||||||
private _transformer = (node: RecursiveTaskgroupInfo, level: number) => {
|
private _transformer = (node: RecursiveTaskgroupInfo, level: number) => {
|
||||||
return {
|
return {
|
||||||
expandable: !!node.childTaskgroups && node.childTaskgroups.length > 0,
|
expandable: !!node.childTaskgroups && node.childTaskgroups.length > 0,
|
||||||
name: node.taskgroupName,
|
name: node.taskgroupName,
|
||||||
level: level,
|
level: level,
|
||||||
activeTasks: node.amountActiveTasks,
|
activeTasks: node.amountActiveTasks,
|
||||||
hasOverdueTask: node.hasOverdueTask
|
hasOverdueTask: node.hasOverdueTask,
|
||||||
|
tasks: node.activeTasks
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -59,4 +64,8 @@ export class TaskgroupOverviewComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
hasChild = (_: number, node: ExampleFlatNode) => node.expandable;
|
hasChild = (_: number, node: ExampleFlatNode) => node.expandable;
|
||||||
|
|
||||||
|
onSelectTaskgroup(tasks: TaskOverviewInfo[]) {
|
||||||
|
this.taskgroupSelected.emit(tasks)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user