issue-20 #46

Merged
sebastian merged 15 commits from issue-20 into master 2023-11-12 13:18:53 +01:00
5 changed files with 154 additions and 10 deletions
Showing only changes of commit fd4012ec90 - Show all commits

View File

@ -7,6 +7,15 @@
<app-date-time-picker #stopTimePicker (onTimeSet)="onStopTimeSet($event)"></app-date-time-picker> <app-date-time-picker #stopTimePicker (onTimeSet)="onStopTimeSet($event)"></app-date-time-picker>
</div> </div>
<div class="progress-stacked" >
<div class="progress" role="progressbar" aria-label="Segment one" aria-valuenow="15" aria-valuemin="0" aria-valuemax="100" [style.width]=currentProgress>
<div class="progress-bar">{{currentProgress}}</div>
</div>
<div class="progress" role="progressbar" aria-label="Segment two" aria-valuenow="30" aria-valuemin="0" aria-valuemax="100" [style.width]=futureProgress>
<div class="progress-bar bg-success">{{futureProgress}}</div>
</div>
</div>
<button class="scheduleBtn" mat-raised-button color="primary" >Schedule</button> <button class="scheduleBtn" mat-raised-button color="primary" >Schedule</button>
</div> </div>

View File

@ -1,6 +1,5 @@
import {Component, Input, ViewChild} from '@angular/core'; import {Component, EventEmitter, Input, OnInit, Output, ViewChild} from '@angular/core';
import {TaskgroupEntityInfo, TaskShortInfo} from "../../../api"; import {TaskEntityInfo, TaskgroupEntityInfo} from "../../../api";
import {FormControl, Validators} from "@angular/forms";
import {DateTimePickerComponent} from "../../date-time-picker/date-time-picker.component"; import {DateTimePickerComponent} from "../../date-time-picker/date-time-picker.component";
@Component({ @Component({
@ -8,18 +7,26 @@ import {DateTimePickerComponent} from "../../date-time-picker/date-time-picker.c
templateUrl: './advanced-scheduler.component.html', templateUrl: './advanced-scheduler.component.html',
styleUrls: ['./advanced-scheduler.component.css'] styleUrls: ['./advanced-scheduler.component.css']
}) })
export class AdvancedSchedulerComponent { export class AdvancedSchedulerComponent implements OnInit{
@Input() task: TaskEntityInfo | undefined;
@Input() task: TaskShortInfo | undefined;
@Input() taskgroup: TaskgroupEntityInfo | undefined @Input() taskgroup: TaskgroupEntityInfo | undefined
@ViewChild('startTimePicker') startTimePicker?: DateTimePickerComponent; @ViewChild('startTimePicker') startTimePicker?: DateTimePickerComponent;
@ViewChild('stopTimePicker') stopTimePicker?: DateTimePickerComponent; @ViewChild('stopTimePicker') stopTimePicker?: DateTimePickerComponent;
@Output('onStartTimeSet') startTimeEmitter : EventEmitter<Date> = new EventEmitter<Date>();
@Output('onEndTimeSet') endTimeEmitter : EventEmitter<Date> = new EventEmitter<Date>();
selectedStartTime: Date | undefined selectedStartTime: Date | undefined
selectedStopTime: Date | undefined selectedStopTime: Date | undefined
currentProgress: string = "30%";
futureProgress: string = "60%"
ngOnInit() {
this.calcFutureProgress();
this.calcCurrentProgress();
}
setDate(clickedDate: Date) { setDate(clickedDate: Date) {
if(this.selectedStartTime == undefined) { if(this.selectedStartTime == undefined) {
this.startTimePicker!.setDateTime(clickedDate); this.startTimePicker!.setDateTime(clickedDate);
@ -28,13 +35,64 @@ export class AdvancedSchedulerComponent {
this.stopTimePicker!.setDateTime(clickedDate); this.stopTimePicker!.setDateTime(clickedDate);
this.selectedStopTime = clickedDate; this.selectedStopTime = clickedDate;
} }
this.calcFutureProgress();
}
setStopTime(selectedDate: Date) {
this.selectedStopTime = selectedDate
this.stopTimePicker!.setDateTime(selectedDate);
this.calcFutureProgress();
}
setStartTime(selectedDate: Date) {
this.selectedStartTime = selectedDate;
this.startTimePicker!.setDateTime(selectedDate);
this.calcFutureProgress();
} }
onStartTimeSet(selectedDate: Date) { onStartTimeSet(selectedDate: Date) {
this.selectedStartTime = selectedDate; this.selectedStartTime = selectedDate;
this.startTimeEmitter.emit(selectedDate)
this.calcFutureProgress();
} }
onStopTimeSet(selectedDate: Date) { onStopTimeSet(selectedDate: Date) {
this.selectedStopTime = selectedDate; this.selectedStopTime = selectedDate;
this.endTimeEmitter.emit(selectedDate);
this.calcFutureProgress();
}
calcCurrentProgress() {
if(this.task!.eta == 0) {
this.currentProgress = "0%";
} else {
const fraction = this.task!.workTime / this.task!.eta * 100;
this.currentProgress = fraction + "%";
} }
} }
calcFutureProgress() {
//const currentProgressNumber = parseFloat(this.currentProgress.slice(0, -1)) / 100;
if(this.selectedStartTime != undefined && this.selectedStopTime != undefined) {
const fraction = this.dateDiffInDays(this.selectedStartTime, this.selectedStopTime) / this.task!.eta * 100
this.futureProgress = fraction + "%";
} else {
this.futureProgress = "0%";
}
}
dateDiffInDays(a: Date, b: Date) {
const diffMs = b.getTime() - a.getTime();
return Math.floor((diffMs / 1000) / 60);
}
}

View File

@ -16,9 +16,12 @@
<mwl-calendar-week-view [viewDate]="viewDate" [daysInWeek]="daysInWeek" [dayStartHour]="7" [dayEndHour]="21" [refresh]="refresh" <mwl-calendar-week-view [viewDate]="viewDate" [daysInWeek]="daysInWeek" [dayStartHour]="7" [dayEndHour]="21" [refresh]="refresh"
(dayHeaderClicked)="timeClick($event.day.date)" (dayHeaderClicked)="timeClick($event.day.date)"
(hourSegmentClicked)="timeClick($event.date)" [events]="events" (eventClicked)="eventClicked($event)" (hourSegmentClicked)="timeClick($event.date)" [events]="events" (eventClicked)="eventClicked($event)"
(eventTimesChanged)="eventTimesChanged($event)"
> >
</mwl-calendar-week-view> </mwl-calendar-week-view>
<app-basic-scheduler *ngIf="scheduleStrategy === 1" #basicScheduler [task]="task" [taskgroup]="taskgroup" (onSchedule)="onBasicSchedule($event)"></app-basic-scheduler> <app-basic-scheduler *ngIf="scheduleStrategy === 1" #basicScheduler [task]="task" [taskgroup]="taskgroup" (onSchedule)="onBasicSchedule($event)"></app-basic-scheduler>
<app-advanced-scheduler *ngIf="scheduleStrategy === 3" #advancedScheduler [task]="task" [taskgroup]="taskgroup"></app-advanced-scheduler> <app-advanced-scheduler *ngIf="scheduleStrategy === 3" #advancedScheduler [task]="task" [taskgroup]="taskgroup"
(onStartTimeSet)="eventTimesExternalChange($event, true)" (onEndTimeSet)="eventTimesExternalChange($event, false)"
></app-advanced-scheduler>
</div> </div>

View File

@ -8,13 +8,14 @@ import {
TaskService, TaskShortInfo TaskService, TaskShortInfo
} from "../../../api"; } from "../../../api";
import {ActivatedRoute, Router} from "@angular/router"; import {ActivatedRoute, Router} from "@angular/router";
import {CalendarDateFormatter, CalendarEvent, CalendarView} from "angular-calendar"; import {CalendarDateFormatter, CalendarEvent, CalendarEventTimesChangedEvent, CalendarView} from "angular-calendar";
import { Subject } from 'rxjs'; import { Subject } from 'rxjs';
import {CalendarDatePipe} from "angular-calendar/modules/common/calendar-date/calendar-date.pipe"; import {CalendarDatePipe} from "angular-calendar/modules/common/calendar-date/calendar-date.pipe";
import {BasicSchedulerComponent} from "../basic-scheduler/basic-scheduler.component"; import {BasicSchedulerComponent} from "../basic-scheduler/basic-scheduler.component";
import * as events from "events"; import * as events from "events";
import { EventColor } from 'calendar-utils'; import { EventColor } from 'calendar-utils';
import {AdvancedSchedulerComponent} from "../advanced-scheduler/advanced-scheduler.component"; import {AdvancedSchedulerComponent} from "../advanced-scheduler/advanced-scheduler.component";
import * as moment from "moment";
const colors: Record<string, EventColor> = { const colors: Record<string, EventColor> = {
red: { red: {
@ -126,7 +127,33 @@ export class SchedulerComponent implements OnInit{
this.basicScheduler.setDate(clickedDate) this.basicScheduler.setDate(clickedDate)
} else if(this.advancedScheduler != undefined && this.scheduleStrategy === 3) { } else if(this.advancedScheduler != undefined && this.scheduleStrategy === 3) {
this.advancedScheduler.setDate(clickedDate) this.advancedScheduler.setDate(clickedDate)
const endDate: Date = moment(clickedDate).add(30, 'm').toDate();
this.advancedScheduler.setDate(endDate);
this.events.push({
title: this.computeTaskPath(this.taskgroupPath, this.task!),
start: clickedDate,
end: endDate,
color: colors['yellow'],
resizable: {
beforeStart: true,
afterEnd: true
} }
})
this.refresh.next();
}
}
eventTimesChanged({
event,
newStart,
newEnd,
}: CalendarEventTimesChangedEvent): void {
event.start = newStart;
event.end = newEnd;
this.refresh.next();
this.advancedScheduler!.setStartTime(event.start);
this.advancedScheduler!.setStopTime(event.end!);
} }
onBasicSchedule(scheduleInfo: BasicScheduleEntityInfo) { onBasicSchedule(scheduleInfo: BasicScheduleEntityInfo) {
@ -182,4 +209,50 @@ export class SchedulerComponent implements OnInit{
return result; return result;
} }
findTaskByTaskPathString(taskgroupPathString: string) :TaskShortInfo {
return this.task!;
}
findEventByTaskPath(taskPath: string) {
return this.events.find(event => event.title == taskPath);
}
eventTimesExternalChange(selectedDate: Date, start: boolean) {
const event: CalendarEvent<any>| undefined = this.findEventByTaskPath(this.computeTaskPath(this.taskgroupPath, this.task!));
if(event == undefined) {
if(start) {
this.events.push({
title: this.computeTaskPath(this.taskgroupPath, this.task!),
start: selectedDate,
color: colors['yellow'],
resizable: {
beforeStart: true,
afterEnd: true
}
})
} else {
const updatedDate = moment(selectedDate).subtract(30, 'm').toDate();
this.events.push({
title: this.computeTaskPath(this.taskgroupPath, this.task!),
start: updatedDate,
color: colors['yellow'],
resizable: {
beforeStart: true,
afterEnd: true
}
})
this.advancedScheduler!.setStartTime(updatedDate);
}
} else {
if(start) {
event.start = selectedDate;
} else {
event.end = selectedDate
}
}
this.refresh.next();
}
} }

View File

@ -10,6 +10,7 @@
<link rel="preconnect" href="https://fonts.gstatic.com"> <link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap" rel="stylesheet"> <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"> <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN" crossorigin="anonymous">
</head> </head>
<body class="mat-typography"> <body class="mat-typography">
<app-root></app-root> <app-root></app-root>