issue-20 #46
28
frontend/package-lock.json
generated
28
frontend/package-lock.json
generated
@ -23,7 +23,9 @@
|
|||||||
"@angular/router": "^16.2.7",
|
"@angular/router": "^16.2.7",
|
||||||
"angular-calendar": "^0.31.0",
|
"angular-calendar": "^0.31.0",
|
||||||
"date-fns": "^2.29.3",
|
"date-fns": "^2.29.3",
|
||||||
|
"luxon": "^3.4.3",
|
||||||
"moment": "^2.29.4",
|
"moment": "^2.29.4",
|
||||||
|
"ngx-material-timepicker": "^13.1.1",
|
||||||
"rxjs": "~7.5.0",
|
"rxjs": "~7.5.0",
|
||||||
"tslib": "^2.3.0",
|
"tslib": "^2.3.0",
|
||||||
"zone.js": "~0.13.3"
|
"zone.js": "~0.13.3"
|
||||||
@ -4395,6 +4397,12 @@
|
|||||||
"integrity": "sha512-RbSSoHliUbnXj3ny0CNFOoxrIDV6SUGyStHsvDqosw6CkdPV8TtWGlfecuK4ToyMEAql6pzNxgCFKanovUzlgQ==",
|
"integrity": "sha512-RbSSoHliUbnXj3ny0CNFOoxrIDV6SUGyStHsvDqosw6CkdPV8TtWGlfecuK4ToyMEAql6pzNxgCFKanovUzlgQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/luxon": {
|
||||||
|
"version": "3.3.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/luxon/-/luxon-3.3.4.tgz",
|
||||||
|
"integrity": "sha512-H9OXxv4EzJwE75aTPKpiGXJq+y4LFxjpsdgKwSmr503P5DkWc3AG7VAFYrFNVvqemT5DfgZJV9itYhqBHSGujA==",
|
||||||
|
"peer": true
|
||||||
|
},
|
||||||
"node_modules/@types/mime": {
|
"node_modules/@types/mime": {
|
||||||
"version": "1.3.3",
|
"version": "1.3.3",
|
||||||
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.3.tgz",
|
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.3.tgz",
|
||||||
@ -9170,6 +9178,14 @@
|
|||||||
"yallist": "^3.0.2"
|
"yallist": "^3.0.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/luxon": {
|
||||||
|
"version": "3.4.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/luxon/-/luxon-3.4.3.tgz",
|
||||||
|
"integrity": "sha512-tFWBiv3h7z+T/tDaoxA8rqTxy1CHV6gHS//QdaH4pulbq/JuBSGgQspQQqcgnwdAx6pNI7cmvz5Sv/addzHmUg==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/magic-string": {
|
"node_modules/magic-string": {
|
||||||
"version": "0.30.1",
|
"version": "0.30.1",
|
||||||
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.1.tgz",
|
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.1.tgz",
|
||||||
@ -9737,6 +9753,18 @@
|
|||||||
"integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
|
"integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/ngx-material-timepicker": {
|
||||||
|
"version": "13.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ngx-material-timepicker/-/ngx-material-timepicker-13.1.1.tgz",
|
||||||
|
"integrity": "sha512-GST4IBFXrPSBB5VP5LVxoOk1yHbdSnaB293tjuyu+vusg+pQ/3+AtcxQEIadk6Nmsdt8zKsbXNgvLrI4nbYRKQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"tslib": "^2.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/luxon": ">= 1.11.1",
|
||||||
|
"luxon": ">= 1.24.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/nice-napi": {
|
"node_modules/nice-napi": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/nice-napi/-/nice-napi-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/nice-napi/-/nice-napi-1.0.2.tgz",
|
||||||
|
@ -25,7 +25,9 @@
|
|||||||
"@angular/router": "^16.2.7",
|
"@angular/router": "^16.2.7",
|
||||||
"angular-calendar": "^0.31.0",
|
"angular-calendar": "^0.31.0",
|
||||||
"date-fns": "^2.29.3",
|
"date-fns": "^2.29.3",
|
||||||
|
"luxon": "^3.4.3",
|
||||||
"moment": "^2.29.4",
|
"moment": "^2.29.4",
|
||||||
|
"ngx-material-timepicker": "^13.1.1",
|
||||||
"rxjs": "~7.5.0",
|
"rxjs": "~7.5.0",
|
||||||
"tslib": "^2.3.0",
|
"tslib": "^2.3.0",
|
||||||
"zone.js": "~0.13.3"
|
"zone.js": "~0.13.3"
|
||||||
|
@ -75,6 +75,8 @@ import { OverdueTaskOverviewComponent } from './overdue-task-overview/overdue-ta
|
|||||||
import { UpcomingTaskOverviewComponent } from './upcoming-task-overview/upcoming-task-overview.component';
|
import { UpcomingTaskOverviewComponent } from './upcoming-task-overview/upcoming-task-overview.component';
|
||||||
import { ActiveTaskOverviewComponent } from './active-task-overview/active-task-overview.component';
|
import { ActiveTaskOverviewComponent } from './active-task-overview/active-task-overview.component';
|
||||||
import { AdvancedSchedulerComponent } from './schedules/advanced-scheduler/advanced-scheduler.component';
|
import { AdvancedSchedulerComponent } from './schedules/advanced-scheduler/advanced-scheduler.component';
|
||||||
|
import {NgxMaterialTimepickerModule} from "ngx-material-timepicker";
|
||||||
|
import { DateTimePickerComponent } from './date-time-picker/date-time-picker.component';
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
AppComponent,
|
AppComponent,
|
||||||
@ -112,7 +114,8 @@ import { AdvancedSchedulerComponent } from './schedules/advanced-scheduler/advan
|
|||||||
OverdueTaskOverviewComponent,
|
OverdueTaskOverviewComponent,
|
||||||
UpcomingTaskOverviewComponent,
|
UpcomingTaskOverviewComponent,
|
||||||
ActiveTaskOverviewComponent,
|
ActiveTaskOverviewComponent,
|
||||||
AdvancedSchedulerComponent
|
AdvancedSchedulerComponent,
|
||||||
|
DateTimePickerComponent
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
BrowserModule,
|
BrowserModule,
|
||||||
@ -149,7 +152,8 @@ import { AdvancedSchedulerComponent } from './schedules/advanced-scheduler/advan
|
|||||||
CalendarModule.forRoot({provide: DateAdapter, useFactory: adapterFactory}),
|
CalendarModule.forRoot({provide: DateAdapter, useFactory: adapterFactory}),
|
||||||
MatSelectModule,
|
MatSelectModule,
|
||||||
MatTreeModule,
|
MatTreeModule,
|
||||||
MatAutocompleteModule
|
MatAutocompleteModule,
|
||||||
|
NgxMaterialTimepickerModule
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
HttpClientModule,
|
HttpClientModule,
|
||||||
|
@ -0,0 +1,3 @@
|
|||||||
|
mat-form-field {
|
||||||
|
width: 50%;
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
<mat-form-field appearance="fill">
|
||||||
|
<input matInput readonly [matDatepicker]="picker" (dateChange)="openTimePicker()" [formControl]="dateControl">
|
||||||
|
<mat-datepicker #picker></mat-datepicker>
|
||||||
|
<mat-datepicker-toggle matIconSuffix [for]="picker" ></mat-datepicker-toggle>
|
||||||
|
</mat-form-field>
|
||||||
|
<mat-form-field appearance="fill">
|
||||||
|
<input [ngxTimepicker]="toggleTimepicker" [disableClick]="true" readonly matInput [format]="24" [formControl]="timeControl" >
|
||||||
|
<ngx-material-timepicker-toggle matSuffix [for]="toggleTimepicker"></ngx-material-timepicker-toggle>
|
||||||
|
<ngx-material-timepicker #toggleTimepicker (timeSet)="onTimeSet($event)"></ngx-material-timepicker>
|
||||||
|
</mat-form-field>
|
@ -0,0 +1,21 @@
|
|||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { DateTimePickerComponent } from './date-time-picker.component';
|
||||||
|
|
||||||
|
describe('DateTimePickerComponent', () => {
|
||||||
|
let component: DateTimePickerComponent;
|
||||||
|
let fixture: ComponentFixture<DateTimePickerComponent>;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [DateTimePickerComponent]
|
||||||
|
});
|
||||||
|
fixture = TestBed.createComponent(DateTimePickerComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
@ -0,0 +1,43 @@
|
|||||||
|
import {Component, EventEmitter, Output, ViewChild} from "@angular/core";
|
||||||
|
import {MatDatepicker} from "@angular/material/datepicker";
|
||||||
|
import {NgxMaterialTimepickerComponent, NgxMaterialTimepickerToggleComponent} from "ngx-material-timepicker";
|
||||||
|
import {FormControl, Validators} from "@angular/forms";
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-date-time-picker',
|
||||||
|
templateUrl: './date-time-picker.component.html',
|
||||||
|
styleUrls: ['./date-time-picker.component.css']
|
||||||
|
})
|
||||||
|
export class DateTimePickerComponent {
|
||||||
|
@ViewChild('picker') picker?: MatDatepicker<any>;
|
||||||
|
@ViewChild('toggleTimepicker') toggleTimepicker?: NgxMaterialTimepickerComponent
|
||||||
|
@Output('onTimeSet') timeSet: EventEmitter<Date> = new EventEmitter<Date>();
|
||||||
|
|
||||||
|
dateControl: FormControl = new FormControl('', [Validators.required])
|
||||||
|
timeControl: FormControl = new FormControl('', [Validators.required])
|
||||||
|
constructor() { }
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
setDateTime(date: Date) {
|
||||||
|
console.log(date)
|
||||||
|
this.dateControl.setValue(date);
|
||||||
|
const timeString = date.toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit', hour12: false });
|
||||||
|
this.timeControl.setValue(timeString);
|
||||||
|
}
|
||||||
|
|
||||||
|
openTimePicker() {
|
||||||
|
this.toggleTimepicker!.open();
|
||||||
|
}
|
||||||
|
|
||||||
|
onTimeSet(time: string) {
|
||||||
|
let selectedDate = new Date(this.dateControl.value)
|
||||||
|
const [hours, minutes] = time.split(":")
|
||||||
|
selectedDate.setHours(parseInt(hours, 10));
|
||||||
|
selectedDate.setMinutes(parseInt(minutes, 10));
|
||||||
|
|
||||||
|
this.timeSet.emit(selectedDate);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
app-date-time-picker {
|
||||||
|
margin-right: 20px;
|
||||||
|
}
|
@ -1,16 +1,12 @@
|
|||||||
<div class="scheduler-container">
|
<div class="scheduler-container">
|
||||||
<mat-form-field>
|
<!--<input [ngxTimepicker]="picker" [format]="24">
|
||||||
<input matInput [matDatepicker]="picker" [formControl]="startCtrl">
|
<ngx-material-timepicker #picker ></ngx-material-timepicker>-->
|
||||||
<mat-hint>MM/DD/YYYY</mat-hint>
|
<!---->
|
||||||
<mat-datepicker-toggle matIconSuffix [for]="picker"></mat-datepicker-toggle>
|
<div>
|
||||||
<mat-datepicker #picker></mat-datepicker>
|
<app-date-time-picker #startTimePicker (onTimeSet)="onStartTimeSet($event)"></app-date-time-picker>
|
||||||
</mat-form-field>
|
<app-date-time-picker #stopTimePicker (onTimeSet)="onStopTimeSet($event)"></app-date-time-picker>
|
||||||
<mat-form-field>
|
</div>
|
||||||
<input matInput [matDatepicker]="endPicker" [formControl]="endCtrl">
|
|
||||||
<mat-hint>MM/DD/YYYY</mat-hint>
|
|
||||||
<mat-datepicker-toggle matIconSuffix [for]="endPicker"></mat-datepicker-toggle>
|
|
||||||
<mat-datepicker #endPicker></mat-datepicker>
|
|
||||||
</mat-form-field>
|
|
||||||
|
|
||||||
<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,7 @@
|
|||||||
import {Component, Input} from '@angular/core';
|
import {Component, Input, ViewChild} from '@angular/core';
|
||||||
import {TaskgroupEntityInfo, TaskShortInfo} from "../../../api";
|
import {TaskgroupEntityInfo, TaskShortInfo} from "../../../api";
|
||||||
import {FormControl, Validators} from "@angular/forms";
|
import {FormControl, Validators} from "@angular/forms";
|
||||||
|
import {DateTimePickerComponent} from "../../date-time-picker/date-time-picker.component";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-advanced-scheduler',
|
selector: 'app-advanced-scheduler',
|
||||||
@ -12,15 +13,28 @@ export class AdvancedSchedulerComponent {
|
|||||||
@Input() task: TaskShortInfo | undefined;
|
@Input() task: TaskShortInfo | undefined;
|
||||||
@Input() taskgroup: TaskgroupEntityInfo | undefined
|
@Input() taskgroup: TaskgroupEntityInfo | undefined
|
||||||
|
|
||||||
|
@ViewChild('startTimePicker') startTimePicker?: DateTimePickerComponent;
|
||||||
|
@ViewChild('stopTimePicker') stopTimePicker?: DateTimePickerComponent;
|
||||||
|
|
||||||
startCtrl = new FormControl('', [Validators.required])
|
|
||||||
endCtrl = new FormControl('', [Validators.required])
|
selectedStartTime: Date | undefined
|
||||||
|
selectedStopTime: Date | undefined
|
||||||
|
|
||||||
setDate(clickedDate: Date) {
|
setDate(clickedDate: Date) {
|
||||||
if(this.startCtrl.value == undefined) {
|
if(this.selectedStartTime == undefined) {
|
||||||
this.startCtrl.setValue(clickedDate.toISOString());
|
this.startTimePicker!.setDateTime(clickedDate);
|
||||||
} else if(new Date(Date.parse(this.startCtrl.value)) < clickedDate) {
|
this.selectedStartTime = clickedDate;
|
||||||
this.endCtrl.setValue(clickedDate.toISOString());
|
} else {
|
||||||
|
this.stopTimePicker!.setDateTime(clickedDate);
|
||||||
|
this.selectedStopTime = clickedDate;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onStartTimeSet(selectedDate: Date) {
|
||||||
|
this.selectedStartTime = selectedDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
onStopTimeSet(selectedDate: Date) {
|
||||||
|
this.selectedStopTime = selectedDate;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user