issue-95 #101
@ -7,10 +7,9 @@ import java.time.LocalDateTime;
 | 
			
		||||
 | 
			
		||||
public class ManualScheduleStopInfo {
 | 
			
		||||
    @NotNull
 | 
			
		||||
    @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX")
 | 
			
		||||
    private LocalDateTime endTime;
 | 
			
		||||
    private long duration;
 | 
			
		||||
 | 
			
		||||
    public LocalDateTime getEndTime() {
 | 
			
		||||
        return endTime;
 | 
			
		||||
    public long getDuration() {
 | 
			
		||||
        return duration;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -22,6 +22,7 @@ import java.time.Duration;
 | 
			
		||||
import java.time.LocalDate;
 | 
			
		||||
import java.time.LocalDateTime;
 | 
			
		||||
import java.time.temporal.ChronoUnit;
 | 
			
		||||
import java.time.temporal.TemporalUnit;
 | 
			
		||||
import java.util.*;
 | 
			
		||||
 | 
			
		||||
@Service
 | 
			
		||||
@ -240,7 +241,7 @@ public class TaskScheduleService {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void finishScheduleManual(AbstractSchedule schedule, ManualScheduleStopInfo manualScheduleStopInfo) {
 | 
			
		||||
        schedule.setStopTime(manualScheduleStopInfo.getEndTime());
 | 
			
		||||
        schedule.setStopTime(schedule.getStartTime().plusMinutes(manualScheduleStopInfo.getDuration()));
 | 
			
		||||
        scheduleRepository.save(schedule);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -30,6 +30,7 @@ model/inlineResponse403.ts
 | 
			
		||||
model/inlineResponse409.ts
 | 
			
		||||
model/loginRequest.ts
 | 
			
		||||
model/loginResponse.ts
 | 
			
		||||
model/manualScheduleStopInfo.ts
 | 
			
		||||
model/models.ts
 | 
			
		||||
model/passwordChangeRequest.ts
 | 
			
		||||
model/propertiesInfo.ts
 | 
			
		||||
 | 
			
		||||
@ -21,6 +21,7 @@ import { Observable }                                        from 'rxjs';
 | 
			
		||||
import { AdvancedScheduleFieldInfo } from '../model/models';
 | 
			
		||||
import { BasicScheduleFieldInfo } from '../model/models';
 | 
			
		||||
import { ForgottenActivityRequest } from '../model/models';
 | 
			
		||||
import { ManualScheduleStopInfo } from '../model/models';
 | 
			
		||||
import { ScheduleActivateInfo } from '../model/models';
 | 
			
		||||
import { ScheduleInfo } from '../model/models';
 | 
			
		||||
import { SimpleStatusResponse } from '../model/models';
 | 
			
		||||
@ -699,6 +700,76 @@ export class ScheduleService {
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * load schedule
 | 
			
		||||
     * gets details of schedule
 | 
			
		||||
     * @param scheduleID internal id of schedule
 | 
			
		||||
     * @param manualScheduleStopInfo 
 | 
			
		||||
     * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
 | 
			
		||||
     * @param reportProgress flag to report request and response progress.
 | 
			
		||||
     */
 | 
			
		||||
    public schedulesScheduleIDStopManualPost(scheduleID: number, manualScheduleStopInfo?: ManualScheduleStopInfo, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<ScheduleInfo>;
 | 
			
		||||
    public schedulesScheduleIDStopManualPost(scheduleID: number, manualScheduleStopInfo?: ManualScheduleStopInfo, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<HttpResponse<ScheduleInfo>>;
 | 
			
		||||
    public schedulesScheduleIDStopManualPost(scheduleID: number, manualScheduleStopInfo?: ManualScheduleStopInfo, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<HttpEvent<ScheduleInfo>>;
 | 
			
		||||
    public schedulesScheduleIDStopManualPost(scheduleID: number, manualScheduleStopInfo?: ManualScheduleStopInfo, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<any> {
 | 
			
		||||
        if (scheduleID === null || scheduleID === undefined) {
 | 
			
		||||
            throw new Error('Required parameter scheduleID was null or undefined when calling schedulesScheduleIDStopManualPost.');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let localVarHeaders = this.defaultHeaders;
 | 
			
		||||
 | 
			
		||||
        let localVarCredential: string | undefined;
 | 
			
		||||
        // authentication (API_TOKEN) required
 | 
			
		||||
        localVarCredential = this.configuration.lookupCredential('API_TOKEN');
 | 
			
		||||
        if (localVarCredential) {
 | 
			
		||||
            localVarHeaders = localVarHeaders.set('Authorization', 'Bearer ' + localVarCredential);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept;
 | 
			
		||||
        if (localVarHttpHeaderAcceptSelected === undefined) {
 | 
			
		||||
            // to determine the Accept header
 | 
			
		||||
            const httpHeaderAccepts: string[] = [
 | 
			
		||||
                'application/json'
 | 
			
		||||
            ];
 | 
			
		||||
            localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts);
 | 
			
		||||
        }
 | 
			
		||||
        if (localVarHttpHeaderAcceptSelected !== undefined) {
 | 
			
		||||
            localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let localVarHttpContext: HttpContext | undefined = options && options.context;
 | 
			
		||||
        if (localVarHttpContext === undefined) {
 | 
			
		||||
            localVarHttpContext = new HttpContext();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        // to determine the Content-Type header
 | 
			
		||||
        const consumes: string[] = [
 | 
			
		||||
            'application/json'
 | 
			
		||||
        ];
 | 
			
		||||
        const httpContentTypeSelected: string | undefined = this.configuration.selectHeaderContentType(consumes);
 | 
			
		||||
        if (httpContentTypeSelected !== undefined) {
 | 
			
		||||
            localVarHeaders = localVarHeaders.set('Content-Type', httpContentTypeSelected);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let responseType_: 'text' | 'json' = 'json';
 | 
			
		||||
        if(localVarHttpHeaderAcceptSelected && localVarHttpHeaderAcceptSelected.startsWith('text')) {
 | 
			
		||||
            responseType_ = 'text';
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return this.httpClient.post<ScheduleInfo>(`${this.configuration.basePath}/schedules/${encodeURIComponent(String(scheduleID))}/stopManual`,
 | 
			
		||||
            manualScheduleStopInfo,
 | 
			
		||||
            {
 | 
			
		||||
                context: localVarHttpContext,
 | 
			
		||||
                responseType: <any>responseType_,
 | 
			
		||||
                withCredentials: this.configuration.withCredentials,
 | 
			
		||||
                headers: localVarHeaders,
 | 
			
		||||
                observe: observe,
 | 
			
		||||
                reportProgress: reportProgress
 | 
			
		||||
            }
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * deletes multiple schedules
 | 
			
		||||
     * deletes multiple schedules at once
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										20
									
								
								frontend/src/api/model/manualScheduleStopInfo.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								frontend/src/api/model/manualScheduleStopInfo.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,20 @@
 | 
			
		||||
/**
 | 
			
		||||
 * API Title
 | 
			
		||||
 * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
 | 
			
		||||
 *
 | 
			
		||||
 * The version of the OpenAPI document: 1.0
 | 
			
		||||
 * 
 | 
			
		||||
 *
 | 
			
		||||
 * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
 | 
			
		||||
 * https://openapi-generator.tech
 | 
			
		||||
 * Do not edit the class manually.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
export interface ManualScheduleStopInfo { 
 | 
			
		||||
    /**
 | 
			
		||||
     * duration in minutes
 | 
			
		||||
     */
 | 
			
		||||
    duration: number;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -14,6 +14,7 @@ export * from './inlineResponse403';
 | 
			
		||||
export * from './inlineResponse409';
 | 
			
		||||
export * from './loginRequest';
 | 
			
		||||
export * from './loginResponse';
 | 
			
		||||
export * from './manualScheduleStopInfo';
 | 
			
		||||
export * from './passwordChangeRequest';
 | 
			
		||||
export * from './propertiesInfo';
 | 
			
		||||
export * from './propertyInfo';
 | 
			
		||||
 | 
			
		||||
@ -88,6 +88,7 @@ import { HeatmapActivityComponent } from './statistics/taskgroup-activity/heatma
 | 
			
		||||
import { ScheduleHistoryComponent } from './statistics/schedule-history/schedule-history.component';
 | 
			
		||||
import {MatButtonToggleModule} from "@angular/material/button-toggle";
 | 
			
		||||
import {MatGridListModule} from "@angular/material/grid-list";
 | 
			
		||||
import { StopScheduleManuallyComponent } from './dashboard/active-schedule/stop-schedule-manually/stop-schedule-manually.component';
 | 
			
		||||
@NgModule({
 | 
			
		||||
  declarations: [
 | 
			
		||||
    AppComponent,
 | 
			
		||||
@ -132,6 +133,7 @@ import {MatGridListModule} from "@angular/material/grid-list";
 | 
			
		||||
    SimpleActivityDiagramComponent,
 | 
			
		||||
    HeatmapActivityComponent,
 | 
			
		||||
    ScheduleHistoryComponent,
 | 
			
		||||
    StopScheduleManuallyComponent,
 | 
			
		||||
  ],
 | 
			
		||||
  imports: [
 | 
			
		||||
    BrowserModule,
 | 
			
		||||
 | 
			
		||||
@ -4,6 +4,7 @@ import {StopActiveScheduleInfo} from "./StopActiveScheduleInfo";
 | 
			
		||||
import {TaskOverviewComponent} from "../task-overview/task-overview.component";
 | 
			
		||||
import {MatDialog} from "@angular/material/dialog";
 | 
			
		||||
import {ForgottenTaskStartDialogComponent} from "../forgotten-task-start-dialog/forgotten-task-start-dialog.component";
 | 
			
		||||
import {StopScheduleManuallyComponent} from "./stop-schedule-manually/stop-schedule-manually.component";
 | 
			
		||||
 | 
			
		||||
export interface StopActiveScheduleEmitterInfo {
 | 
			
		||||
  stopactiveScheduleResponse: StopActiveScheduleInfo,
 | 
			
		||||
@ -99,7 +100,23 @@ export class ActiveScheduleComponent implements OnInit{
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  finishManual() {
 | 
			
		||||
    const dialogRef = this.dialog.open(StopScheduleManuallyComponent, {
 | 
			
		||||
      data: this.activeSchedule,
 | 
			
		||||
      minWidth: "400px"})
 | 
			
		||||
    dialogRef.afterClosed().subscribe(res => {
 | 
			
		||||
      if(res != undefined) {
 | 
			
		||||
        this.scheduleStopEmitter.emit({
 | 
			
		||||
          finish: false,
 | 
			
		||||
          taskID: this.activeSchedule!.scheduleID,
 | 
			
		||||
          stopactiveScheduleResponse: {
 | 
			
		||||
            schedule: this.activeSchedule!,
 | 
			
		||||
            workedMinutes: res
 | 
			
		||||
          }
 | 
			
		||||
        })
 | 
			
		||||
 | 
			
		||||
        this.activeSchedule = undefined;
 | 
			
		||||
      }
 | 
			
		||||
    })
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  openForgettedActivityDialog() {
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,4 @@
 | 
			
		||||
.dialog-padding {
 | 
			
		||||
  padding-left: 5px;
 | 
			
		||||
  padding-right: 5px;
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,11 @@
 | 
			
		||||
<h1 mat-dialog-title>Set Stoptime Manually</h1>
 | 
			
		||||
<mat-dialog-content>
 | 
			
		||||
  <mat-form-field appearance="outline" class="long-form dialog-padding">
 | 
			
		||||
    <mat-label>Spent Minutes</mat-label>
 | 
			
		||||
    <input matInput type="number" [formControl]="formControl">
 | 
			
		||||
  </mat-form-field>
 | 
			
		||||
</mat-dialog-content>
 | 
			
		||||
<mat-dialog-actions align="end">
 | 
			
		||||
  <button mat-raised-button (click)="cancel()">Cancel</button>
 | 
			
		||||
  <button mat-raised-button color="primary" (click)="save()" [disabled]="formControl.invalid">Confirm</button>
 | 
			
		||||
</mat-dialog-actions>
 | 
			
		||||
@ -0,0 +1,21 @@
 | 
			
		||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
 | 
			
		||||
 | 
			
		||||
import { StopScheduleManuallyComponent } from './stop-schedule-manually.component';
 | 
			
		||||
 | 
			
		||||
describe('StopScheduleManuallyComponent', () => {
 | 
			
		||||
  let component: StopScheduleManuallyComponent;
 | 
			
		||||
  let fixture: ComponentFixture<StopScheduleManuallyComponent>;
 | 
			
		||||
 | 
			
		||||
  beforeEach(() => {
 | 
			
		||||
    TestBed.configureTestingModule({
 | 
			
		||||
      declarations: [StopScheduleManuallyComponent]
 | 
			
		||||
    });
 | 
			
		||||
    fixture = TestBed.createComponent(StopScheduleManuallyComponent);
 | 
			
		||||
    component = fixture.componentInstance;
 | 
			
		||||
    fixture.detectChanges();
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should create', () => {
 | 
			
		||||
    expect(component).toBeTruthy();
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
@ -0,0 +1,34 @@
 | 
			
		||||
import {Component, Inject} from '@angular/core';
 | 
			
		||||
import {MAT_DIALOG_DATA, MatDialogRef} from "@angular/material/dialog";
 | 
			
		||||
import {ScheduleInfo, ScheduleService} from "../../../../api";
 | 
			
		||||
import {FormControl, Validators} from "@angular/forms";
 | 
			
		||||
 | 
			
		||||
@Component({
 | 
			
		||||
  selector: 'app-stop-schedule-manually',
 | 
			
		||||
  templateUrl: './stop-schedule-manually.component.html',
 | 
			
		||||
  styleUrls: ['./stop-schedule-manually.component.css']
 | 
			
		||||
})
 | 
			
		||||
export class StopScheduleManuallyComponent {
 | 
			
		||||
 | 
			
		||||
  formControl: FormControl = new FormControl('', [Validators.required])
 | 
			
		||||
  constructor(@Inject(MAT_DIALOG_DATA) public schedule: ScheduleInfo,
 | 
			
		||||
              private scheduleService: ScheduleService,
 | 
			
		||||
              private dialogRef: MatDialogRef<StopScheduleManuallyComponent>) {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  cancel() {
 | 
			
		||||
    this.dialogRef.close();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  save() {
 | 
			
		||||
    console.log(this.schedule.scheduleID)
 | 
			
		||||
    this.scheduleService.schedulesScheduleIDStopManualPost(this.schedule.scheduleID, {
 | 
			
		||||
      duration: this.formControl.value
 | 
			
		||||
    }).subscribe({
 | 
			
		||||
      next: resp => {
 | 
			
		||||
        this.dialogRef.close(Number(this.formControl.value))
 | 
			
		||||
      }
 | 
			
		||||
    })
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@ -2,3 +2,7 @@
 | 
			
		||||
 | 
			
		||||
html, body { height: 100%; }
 | 
			
		||||
body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; }
 | 
			
		||||
 | 
			
		||||
.long-form {
 | 
			
		||||
  width: 100%;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										52
									
								
								openapi.yaml
									
									
									
									
									
								
							
							
						
						
									
										52
									
								
								openapi.yaml
									
									
									
									
									
								
							@ -1882,6 +1882,47 @@ paths:
 | 
			
		||||
            application/json:
 | 
			
		||||
              schema:
 | 
			
		||||
                $ref: '#/components/schemas/SimpleStatusResponse'
 | 
			
		||||
  /schedules/{scheduleID}/stopManual:
 | 
			
		||||
    post:
 | 
			
		||||
      security:
 | 
			
		||||
        - API_TOKEN: []
 | 
			
		||||
      tags:
 | 
			
		||||
        - schedule
 | 
			
		||||
      description: gets details of schedule
 | 
			
		||||
      summary: load schedule
 | 
			
		||||
      parameters:
 | 
			
		||||
        - name: scheduleID
 | 
			
		||||
          in: path
 | 
			
		||||
          description: internal id of schedule
 | 
			
		||||
          required: true
 | 
			
		||||
          schema:
 | 
			
		||||
            type: number
 | 
			
		||||
            example: 1
 | 
			
		||||
      requestBody:
 | 
			
		||||
        content:
 | 
			
		||||
          application/json:
 | 
			
		||||
            schema:
 | 
			
		||||
              $ref: '#/components/schemas/ManualScheduleStopInfo'
 | 
			
		||||
      responses:
 | 
			
		||||
        200:
 | 
			
		||||
          description: Operation successfull
 | 
			
		||||
          content:
 | 
			
		||||
            application/json:
 | 
			
		||||
              schema:
 | 
			
		||||
                $ref: '#/components/schemas/ScheduleInfo'
 | 
			
		||||
        403:
 | 
			
		||||
          description: No permission
 | 
			
		||||
          content:
 | 
			
		||||
            application/json:
 | 
			
		||||
              schema:
 | 
			
		||||
                $ref: '#/components/schemas/SimpleStatusResponse'
 | 
			
		||||
        404:
 | 
			
		||||
          description: Schedule not found
 | 
			
		||||
          content:
 | 
			
		||||
            application/json:
 | 
			
		||||
              schema:
 | 
			
		||||
                $ref: '#/components/schemas/SimpleStatusResponse'
 | 
			
		||||
                
 | 
			
		||||
      
 | 
			
		||||
  /history/workingStatus:
 | 
			
		||||
    get:
 | 
			
		||||
@ -2663,5 +2704,12 @@ components:
 | 
			
		||||
          type: number
 | 
			
		||||
          description: Number of minutes the task was active
 | 
			
		||||
          example: 122
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
    ManualScheduleStopInfo:
 | 
			
		||||
      required:
 | 
			
		||||
        - duration
 | 
			
		||||
      additionalProperties: false
 | 
			
		||||
      properties:
 | 
			
		||||
        duration:
 | 
			
		||||
          type: number
 | 
			
		||||
          description: duration in minutes
 | 
			
		||||
          example: 10
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user