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-calendar": "^0.31.0",
 | 
			
		||||
        "date-fns": "^2.29.3",
 | 
			
		||||
        "luxon": "^3.4.3",
 | 
			
		||||
        "moment": "^2.29.4",
 | 
			
		||||
        "ngx-material-timepicker": "^13.1.1",
 | 
			
		||||
        "rxjs": "~7.5.0",
 | 
			
		||||
        "tslib": "^2.3.0",
 | 
			
		||||
        "zone.js": "~0.13.3"
 | 
			
		||||
@ -4395,6 +4397,12 @@
 | 
			
		||||
      "integrity": "sha512-RbSSoHliUbnXj3ny0CNFOoxrIDV6SUGyStHsvDqosw6CkdPV8TtWGlfecuK4ToyMEAql6pzNxgCFKanovUzlgQ==",
 | 
			
		||||
      "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": {
 | 
			
		||||
      "version": "1.3.3",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.3.tgz",
 | 
			
		||||
@ -9170,6 +9178,14 @@
 | 
			
		||||
        "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": {
 | 
			
		||||
      "version": "0.30.1",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.1.tgz",
 | 
			
		||||
@ -9737,6 +9753,18 @@
 | 
			
		||||
      "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
 | 
			
		||||
      "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": {
 | 
			
		||||
      "version": "1.0.2",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/nice-napi/-/nice-napi-1.0.2.tgz",
 | 
			
		||||
 | 
			
		||||
@ -25,7 +25,9 @@
 | 
			
		||||
    "@angular/router": "^16.2.7",
 | 
			
		||||
    "angular-calendar": "^0.31.0",
 | 
			
		||||
    "date-fns": "^2.29.3",
 | 
			
		||||
    "luxon": "^3.4.3",
 | 
			
		||||
    "moment": "^2.29.4",
 | 
			
		||||
    "ngx-material-timepicker": "^13.1.1",
 | 
			
		||||
    "rxjs": "~7.5.0",
 | 
			
		||||
    "tslib": "^2.3.0",
 | 
			
		||||
    "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 { ActiveTaskOverviewComponent } from './active-task-overview/active-task-overview.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({
 | 
			
		||||
  declarations: [
 | 
			
		||||
    AppComponent,
 | 
			
		||||
@ -112,7 +114,8 @@ import { AdvancedSchedulerComponent } from './schedules/advanced-scheduler/advan
 | 
			
		||||
    OverdueTaskOverviewComponent,
 | 
			
		||||
    UpcomingTaskOverviewComponent,
 | 
			
		||||
    ActiveTaskOverviewComponent,
 | 
			
		||||
    AdvancedSchedulerComponent
 | 
			
		||||
    AdvancedSchedulerComponent,
 | 
			
		||||
    DateTimePickerComponent
 | 
			
		||||
  ],
 | 
			
		||||
  imports: [
 | 
			
		||||
    BrowserModule,
 | 
			
		||||
@ -149,7 +152,8 @@ import { AdvancedSchedulerComponent } from './schedules/advanced-scheduler/advan
 | 
			
		||||
    CalendarModule.forRoot({provide: DateAdapter, useFactory: adapterFactory}),
 | 
			
		||||
    MatSelectModule,
 | 
			
		||||
    MatTreeModule,
 | 
			
		||||
    MatAutocompleteModule
 | 
			
		||||
    MatAutocompleteModule,
 | 
			
		||||
    NgxMaterialTimepickerModule
 | 
			
		||||
  ],
 | 
			
		||||
  providers: [
 | 
			
		||||
    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">
 | 
			
		||||
  <mat-form-field>
 | 
			
		||||
    <input matInput [matDatepicker]="picker" [formControl]="startCtrl">
 | 
			
		||||
    <mat-hint>MM/DD/YYYY</mat-hint>
 | 
			
		||||
    <mat-datepicker-toggle matIconSuffix [for]="picker"></mat-datepicker-toggle>
 | 
			
		||||
    <mat-datepicker #picker></mat-datepicker>
 | 
			
		||||
  </mat-form-field>
 | 
			
		||||
  <mat-form-field>
 | 
			
		||||
    <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>
 | 
			
		||||
  <!--<input [ngxTimepicker]="picker" [format]="24">
 | 
			
		||||
  <ngx-material-timepicker #picker ></ngx-material-timepicker>-->
 | 
			
		||||
  <!---->
 | 
			
		||||
  <div>
 | 
			
		||||
    <app-date-time-picker #startTimePicker (onTimeSet)="onStartTimeSet($event)"></app-date-time-picker>
 | 
			
		||||
    <app-date-time-picker #stopTimePicker (onTimeSet)="onStopTimeSet($event)"></app-date-time-picker>
 | 
			
		||||
  </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  <button class="scheduleBtn" mat-raised-button color="primary" >Schedule</button>
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,7 @@
 | 
			
		||||
import {Component, Input} from '@angular/core';
 | 
			
		||||
import {Component, Input, ViewChild} from '@angular/core';
 | 
			
		||||
import {TaskgroupEntityInfo, TaskShortInfo} from "../../../api";
 | 
			
		||||
import {FormControl, Validators} from "@angular/forms";
 | 
			
		||||
import {DateTimePickerComponent} from "../../date-time-picker/date-time-picker.component";
 | 
			
		||||
 | 
			
		||||
@Component({
 | 
			
		||||
  selector: 'app-advanced-scheduler',
 | 
			
		||||
@ -12,15 +13,28 @@ export class AdvancedSchedulerComponent {
 | 
			
		||||
  @Input() task: TaskShortInfo | 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) {
 | 
			
		||||
    if(this.startCtrl.value == undefined) {
 | 
			
		||||
      this.startCtrl.setValue(clickedDate.toISOString());
 | 
			
		||||
    } else if(new Date(Date.parse(this.startCtrl.value)) < clickedDate) {
 | 
			
		||||
      this.endCtrl.setValue(clickedDate.toISOString());
 | 
			
		||||
    if(this.selectedStartTime == undefined) {
 | 
			
		||||
      this.startTimePicker!.setDateTime(clickedDate);
 | 
			
		||||
      this.selectedStartTime = clickedDate;
 | 
			
		||||
    } 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