issue-20 #46
@ -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>
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
@ -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>
|
||||||
|
@ -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();
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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>
|
||||||
|
Loading…
Reference in New Issue
Block a user