From b531f632741baa16f7717ba153cfedc2d1943664 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Spada=20=E2=9A=94=EF=B8=8F?= <75368540+PierpaoloSpadafora@users.noreply.github.com> Date: Fri, 6 Dec 2024 00:41:17 +0100 Subject: [PATCH] PARE FUNZIONARE TUTTO YAY - ditemi se trovate problemi con lo scheduling --- .../demacs/rdm/controller/JsonController.java | 17 ++-- .../implementation/JsonServiceImpl.java | 5 +- .../service/interfaces/IJsonService.java | 4 +- .../unical/demacs/rdm/utils/TimeWindow.java | 7 +- .../app/components/home/home.component.css | 26 ++++++ .../app/components/home/home.component.html | 77 +++++++++++----- .../src/app/components/home/home.component.ts | 88 +++++++++++++++---- .../api/jsonController.service.ts | 34 +++---- Frontend/src/app/generated-api/encoder.ts | 2 +- .../src/app/generated-api/model/models.ts | 1 + .../model/scheduleWithMachineDTO.ts | 32 +++++++ 11 files changed, 223 insertions(+), 70 deletions(-) create mode 100644 Frontend/src/app/generated-api/model/scheduleWithMachineDTO.ts diff --git a/Backend/src/main/java/unical/demacs/rdm/controller/JsonController.java b/Backend/src/main/java/unical/demacs/rdm/controller/JsonController.java index 0c267e6..180e308 100644 --- a/Backend/src/main/java/unical/demacs/rdm/controller/JsonController.java +++ b/Backend/src/main/java/unical/demacs/rdm/controller/JsonController.java @@ -11,6 +11,7 @@ import unical.demacs.rdm.persistence.dto.MachineDTO; import unical.demacs.rdm.persistence.dto.MachineTypeDTO; import unical.demacs.rdm.persistence.dto.ScheduleDTO; +import unical.demacs.rdm.persistence.dto.ScheduleWithMachineDTO; import unical.demacs.rdm.persistence.entities.Job; import unical.demacs.rdm.persistence.entities.Machine; import unical.demacs.rdm.persistence.entities.MachineType; @@ -112,32 +113,32 @@ public ResponseEntity> exportMachine() { @Operation(summary = "Export Job data to JSON", description = "Export all Job data to JSON.", tags = {"json-controller"}) @GetMapping(value = "/export-job-scheduled-by-priority", produces = MediaType.APPLICATION_JSON_VALUE) - public ResponseEntity> exportJobScheduledPriority() { - List schedules = jsonService.readScheduleFile("./data/job-scheduled-by-priority.json"); + public ResponseEntity> exportJobScheduledPriority() { + List schedules = jsonService.readScheduleFile("./data/job-scheduled-by-priority.json"); return ResponseEntity.ok(schedules); } @Operation(summary = "Export Job data to JSON", description = "Export all Job data to JSON.", tags = {"json-controller"}) @GetMapping(value = "/export-job-scheduled-by-due-date", produces = MediaType.APPLICATION_JSON_VALUE) - public ResponseEntity> exportJobScheduledDueDate() { - List schedules = jsonService.readScheduleFile("./data/job-scheduled-by-due-date.json"); + public ResponseEntity> exportJobScheduledDueDate() { + List schedules = jsonService.readScheduleFile("./data/job-scheduled-by-due-date.json"); return ResponseEntity.ok(schedules); } @Operation(summary = "Export Job data to JSON", description = "Export all Job data to JSON.", tags = {"json-controller"}) @GetMapping(value = "/export-job-scheduled-by-duration", produces = MediaType.APPLICATION_JSON_VALUE) - public ResponseEntity> exportJobScheduledDuration() { - List schedules = jsonService.readScheduleFile("./data/job-scheduled-by-duration.json"); + public ResponseEntity> exportJobScheduledDuration() { + List schedules = jsonService.readScheduleFile("./data/job-scheduled-by-duration.json"); return ResponseEntity.ok(schedules); } @Operation(summary = "Export Job data to JSON", description = "Export all Job data to JSON.", tags = {"json-controller"}) @GetMapping(value = "/export-job-scheduled-ro", produces = MediaType.APPLICATION_JSON_VALUE) - public ResponseEntity> exportJobScheduledRO() { - List schedules = jsonService.readScheduleFile("./data/job-scheduled-ro.json"); + public ResponseEntity> exportJobScheduledRO() { + List schedules = jsonService.readScheduleFile("./data/job-scheduled-ro.json"); return ResponseEntity.ok(schedules); } } \ No newline at end of file diff --git a/Backend/src/main/java/unical/demacs/rdm/persistence/service/implementation/JsonServiceImpl.java b/Backend/src/main/java/unical/demacs/rdm/persistence/service/implementation/JsonServiceImpl.java index 8367af6..1d4fe9f 100644 --- a/Backend/src/main/java/unical/demacs/rdm/persistence/service/implementation/JsonServiceImpl.java +++ b/Backend/src/main/java/unical/demacs/rdm/persistence/service/implementation/JsonServiceImpl.java @@ -16,14 +16,13 @@ public class JsonServiceImpl implements IJsonService { private final ObjectMapper objectMapper; - public List readScheduleFile(String fileName) { + public List readScheduleFile(String fileName) { File file = new File(fileName); try { return objectMapper.readValue(file, - objectMapper.getTypeFactory().constructCollectionType(List.class, ScheduleDTO.class)); + objectMapper.getTypeFactory().constructCollectionType(List.class, ScheduleWithMachineDTO.class)); } catch (IOException e) { throw new RuntimeException(e); } } - } \ No newline at end of file diff --git a/Backend/src/main/java/unical/demacs/rdm/persistence/service/interfaces/IJsonService.java b/Backend/src/main/java/unical/demacs/rdm/persistence/service/interfaces/IJsonService.java index 4a9d2c6..40dae6c 100644 --- a/Backend/src/main/java/unical/demacs/rdm/persistence/service/interfaces/IJsonService.java +++ b/Backend/src/main/java/unical/demacs/rdm/persistence/service/interfaces/IJsonService.java @@ -1,9 +1,9 @@ package unical.demacs.rdm.persistence.service.interfaces; -import unical.demacs.rdm.persistence.dto.ScheduleDTO; +import unical.demacs.rdm.persistence.dto.ScheduleWithMachineDTO; import java.util.List; public interface IJsonService { - public List readScheduleFile(String fileName); + public List readScheduleFile(String fileName); } \ No newline at end of file diff --git a/Backend/src/main/java/unical/demacs/rdm/utils/TimeWindow.java b/Backend/src/main/java/unical/demacs/rdm/utils/TimeWindow.java index 0ae0216..bf77d58 100644 --- a/Backend/src/main/java/unical/demacs/rdm/utils/TimeWindow.java +++ b/Backend/src/main/java/unical/demacs/rdm/utils/TimeWindow.java @@ -3,9 +3,12 @@ import lombok.AllArgsConstructor; import lombok.Data; +/** + * Represents a time interval with start and end times in epoch seconds + */ @Data @AllArgsConstructor public class TimeWindow { - private long startTime; - private long endTime; + private long startTime; // Start time in epoch seconds + private long endTime; // End time in epoch seconds } diff --git a/Frontend/src/app/components/home/home.component.css b/Frontend/src/app/components/home/home.component.css index f11293e..444e5c3 100644 --- a/Frontend/src/app/components/home/home.component.css +++ b/Frontend/src/app/components/home/home.component.css @@ -157,6 +157,22 @@ font-size: 1rem; } +.machine-type-header { + color: #2c3e50; + font-size: 1.5rem; + margin: 1.5rem 0 1rem; + padding-bottom: 0.5rem; + border-bottom: 2px solid #3498db; +} + +.machine-header { + color: #34495e; + font-size: 1.2rem; + margin: 1rem 0; + padding-left: 1rem; + border-left: 3px solid #3498db; +} + @media (max-width: 768px) { .page-container { padding: 1rem; @@ -210,4 +226,14 @@ .schedule-table tr:nth-child(even) { background-color: transparent; } + + .machine-type-header { + font-size: 1.3rem; + margin: 1rem 0 0.5rem; + } + + .machine-header { + font-size: 1.1rem; + margin: 0.5rem 0; + } } diff --git a/Frontend/src/app/components/home/home.component.html b/Frontend/src/app/components/home/home.component.html index 2e6ab11..7b288d8 100644 --- a/Frontend/src/app/components/home/home.component.html +++ b/Frontend/src/app/components/home/home.component.html @@ -32,27 +32,62 @@

Scheduled Jobs

{{ formatDate(date) }}

-
-

{{ machinesMap.get(machineTypeId) || 'Unknown Machine Type' }}

- - - - - - - - - - - - - - - - - -
Job TitleStart TimeDurationStatus
{{ jobsMap.get(schedule.jobId || 0)?.title || 'Unknown Job' }}{{ schedule.startTime | date: 'shortTime' }}{{ schedule.duration ? (schedule.duration / 3600) + ' ore' : 'N/A' }}{{ schedule.status }}
-
+ + + +
+

{{ machinesMap.get(machineTypeId) || 'Unknown Machine Type' }}

+ + + + + + + + + + + + + + + + + + + +
Job TitleStart TimeDurationDue DateStatus
{{ jobsMap.get(schedule.jobId || 0)?.title || 'Unknown Job' }}{{ schedule.startTime | date: 'shortTime' }}{{ schedule.duration ? (schedule.duration / 3600) + ' ore' : 'N/A' }}{{ schedule.dueDate | date: 'short' }}{{ schedule.status }}
+
+
+ + +
+

{{ machineType }}

+
+

{{ getMachineName(machineSchedules[0].machineId) }}

+ + + + + + + + + + + + + + + + + + + +
Job TitleStart TimeDurationDue DateStatus
{{ jobsMap.get(schedule.jobId || 0)?.title || 'Unknown Job' }}{{ schedule.startTime | date: 'shortTime' }}{{ schedule.duration ? (schedule.duration / 3600) + ' ore' : 'N/A' }}{{ schedule.dueDate | date: 'short' }}{{ schedule.status }}
+
+
+
diff --git a/Frontend/src/app/components/home/home.component.ts b/Frontend/src/app/components/home/home.component.ts index a21531f..b8283f7 100644 --- a/Frontend/src/app/components/home/home.component.ts +++ b/Frontend/src/app/components/home/home.component.ts @@ -1,9 +1,9 @@ import { Component, OnInit } from '@angular/core'; -import { ScheduleControllerService } from '../../generated-api'; -import { JobDTO } from '../../generated-api'; -import { ScheduleDTO } from '../../generated-api'; -import { JsonControllerService } from '../../generated-api'; +import { ScheduleControllerService, JobDTO, + JsonControllerService } from '../../generated-api'; import { Router } from '@angular/router'; +import { Observable } from 'rxjs'; +import { ScheduleWithMachineDTO } from '../../generated-api/model/scheduleWithMachineDTO'; @Component({ selector: 'app-home', @@ -11,9 +11,10 @@ import { Router } from '@angular/router'; styleUrls: ['./home.component.css'] }) export class HomeComponent implements OnInit { - scheduleData: ScheduleDTO[] = []; + scheduleData: ScheduleWithMachineDTO[] = []; jobsMap: Map = new Map(); machinesMap: Map = new Map(); + machineNamesMap: Map = new Map(); // New map for machine names scheduleTypes = [ { label: 'All Jobs', value: 'ALL' }, @@ -32,7 +33,7 @@ export class HomeComponent implements OnInit { hasScheduledJobs = false; loading = true; - schedulesByDateAndMachine: Map> = new Map>(); + schedulesByDateAndMachine: Map> = new Map>(); constructor( private scheduleService: ScheduleControllerService, @@ -51,7 +52,7 @@ export class HomeComponent implements OnInit { fetchData() { this.loading = true; - let scheduleObservable; + let scheduleObservable: Observable; switch (this.selectedScheduleType) { case 'PRIORITY': scheduleObservable = this.jsonService.exportJobScheduledPriority(); @@ -70,11 +71,11 @@ export class HomeComponent implements OnInit { } scheduleObservable.subscribe({ - next: (scheduleData: ScheduleDTO[]) => { + next: (scheduleData: ScheduleWithMachineDTO[]) => { this.scheduleData = scheduleData; this.jsonService.exportJob().subscribe({ - next: (jobs) => { + next: (jobs: JobDTO[]) => { this.jobsMap.clear(); jobs.forEach(job => { if (job.id !== undefined) { @@ -91,22 +92,38 @@ export class HomeComponent implements OnInit { } }); - this.processData(); - this.loading = false; + // Fetch machine names + this.jsonService.exportMachine().subscribe({ + next: (machines) => { + this.machineNamesMap.clear(); + machines.forEach(machine => { + if (machine.id !== undefined && machine.name !== undefined) { + this.machineNamesMap.set(machine.id, machine.name); + } + }); + + this.processData(); + this.loading = false; + }, + error: (error: unknown) => { + console.error('Error fetching machines data', error); + this.loading = false; + } + }); }, - error: (error: any) => { + error: (error: unknown) => { console.error('Error fetching machine types data', error); this.loading = false; } }); }, - error: (error: any) => { + error: (error: unknown) => { console.error('Error fetching jobs data', error); this.loading = false; } }); }, - error: (error: any) => { + error: (error: unknown) => { console.error('Error fetching schedule data', error); this.loading = false; } @@ -120,14 +137,14 @@ export class HomeComponent implements OnInit { } this.hasScheduledJobs = true; - const schedulesByDateAndMachine: Map> = new Map(); + const schedulesByDateAndMachine: Map> = new Map(); this.scheduleData.forEach(schedule => { const date = schedule.startTime ? new Date(schedule.startTime).toDateString() : 'Unknown Date'; const machineTypeId = schedule.machineTypeId || 0; if (!schedulesByDateAndMachine.has(date)) { - schedulesByDateAndMachine.set(date, new Map()); + schedulesByDateAndMachine.set(date, new Map()); } const machineMap = schedulesByDateAndMachine.get(date)!; @@ -159,6 +176,40 @@ export class HomeComponent implements OnInit { }); } + getUniqueMachineTypes(date: string): string[] { + const machineTypeIds = Array.from(this.schedulesByDateAndMachine.get(date)?.keys() || []); + const uniqueTypes = new Set(); + + machineTypeIds.forEach(id => { + const machineName = this.machinesMap.get(id) || 'Unknown Machine Type'; + uniqueTypes.add(machineName); + }); + + return Array.from(uniqueTypes); + } + + getSchedulesForMachineType(date: string, machineTypeName: string): ScheduleWithMachineDTO[][] { + const machineTypeId = Array.from(this.machinesMap.entries()) + .find(([_, name]) => name === machineTypeName)?.[0]; + + if (!machineTypeId) return []; + + const schedules = this.schedulesByDateAndMachine.get(date)?.get(machineTypeId) || []; + + // Group schedules by machineId + const groupedSchedules = new Map(); + + schedules.forEach(schedule => { + const machineId = schedule.machineId || 0; + if (!groupedSchedules.has(machineId)) { + groupedSchedules.set(machineId, []); + } + groupedSchedules.get(machineId)?.push(schedule); + }); + + return Array.from(groupedSchedules.values()); + } + get visibleDates(): string[] { const start = this.currentPage * this.selectedDaysPerPage; return this.paginatedDates.slice(start, start + this.selectedDaysPerPage); @@ -199,5 +250,10 @@ export class HomeComponent implements OnInit { return new Intl.DateTimeFormat('it-IT', options).format(date); } + getMachineName(machineId: number | undefined): string { + if (!machineId) return 'Unknown Machine'; + return `${this.machineNamesMap.get(machineId) || 'Unknown'} - ${machineId}`; + } + protected readonly Array = Array; } diff --git a/Frontend/src/app/generated-api/api/jsonController.service.ts b/Frontend/src/app/generated-api/api/jsonController.service.ts index ab39bb7..8f406c1 100644 --- a/Frontend/src/app/generated-api/api/jsonController.service.ts +++ b/Frontend/src/app/generated-api/api/jsonController.service.ts @@ -20,7 +20,7 @@ import { Observable } from 'rxjs'; import { JobDTO } from '../model/jobDTO'; import { MachineDTO } from '../model/machineDTO'; import { MachineTypeDTO } from '../model/machineTypeDTO'; -import { ScheduleDTO } from '../model/scheduleDTO'; +import { ScheduleWithMachineDTO } from '../model/scheduleWithMachineDTO'; import { BASE_PATH, COLLECTION_FORMATS } from '../variables'; import { Configuration } from '../configuration'; @@ -100,9 +100,9 @@ export class JsonControllerService { * @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 exportJobScheduledDueDate(observe?: 'body', reportProgress?: boolean): Observable>; - public exportJobScheduledDueDate(observe?: 'response', reportProgress?: boolean): Observable>>; - public exportJobScheduledDueDate(observe?: 'events', reportProgress?: boolean): Observable>>; + public exportJobScheduledDueDate(observe?: 'body', reportProgress?: boolean): Observable>; + public exportJobScheduledDueDate(observe?: 'response', reportProgress?: boolean): Observable>>; + public exportJobScheduledDueDate(observe?: 'events', reportProgress?: boolean): Observable>>; public exportJobScheduledDueDate(observe: any = 'body', reportProgress: boolean = false ): Observable { let headers = this.defaultHeaders; @@ -120,7 +120,7 @@ export class JsonControllerService { const consumes: string[] = [ ]; - return this.httpClient.request>('get',`${this.basePath}/api/v1/json/export-job-scheduled-by-due-date`, + return this.httpClient.request>('get',`${this.basePath}/api/v1/json/export-job-scheduled-by-due-date`, { withCredentials: this.configuration.withCredentials, headers: headers, @@ -136,9 +136,9 @@ export class JsonControllerService { * @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 exportJobScheduledDuration(observe?: 'body', reportProgress?: boolean): Observable>; - public exportJobScheduledDuration(observe?: 'response', reportProgress?: boolean): Observable>>; - public exportJobScheduledDuration(observe?: 'events', reportProgress?: boolean): Observable>>; + public exportJobScheduledDuration(observe?: 'body', reportProgress?: boolean): Observable>; + public exportJobScheduledDuration(observe?: 'response', reportProgress?: boolean): Observable>>; + public exportJobScheduledDuration(observe?: 'events', reportProgress?: boolean): Observable>>; public exportJobScheduledDuration(observe: any = 'body', reportProgress: boolean = false ): Observable { let headers = this.defaultHeaders; @@ -156,7 +156,7 @@ export class JsonControllerService { const consumes: string[] = [ ]; - return this.httpClient.request>('get',`${this.basePath}/api/v1/json/export-job-scheduled-by-duration`, + return this.httpClient.request>('get',`${this.basePath}/api/v1/json/export-job-scheduled-by-duration`, { withCredentials: this.configuration.withCredentials, headers: headers, @@ -172,9 +172,9 @@ export class JsonControllerService { * @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 exportJobScheduledPriority(observe?: 'body', reportProgress?: boolean): Observable>; - public exportJobScheduledPriority(observe?: 'response', reportProgress?: boolean): Observable>>; - public exportJobScheduledPriority(observe?: 'events', reportProgress?: boolean): Observable>>; + public exportJobScheduledPriority(observe?: 'body', reportProgress?: boolean): Observable>; + public exportJobScheduledPriority(observe?: 'response', reportProgress?: boolean): Observable>>; + public exportJobScheduledPriority(observe?: 'events', reportProgress?: boolean): Observable>>; public exportJobScheduledPriority(observe: any = 'body', reportProgress: boolean = false ): Observable { let headers = this.defaultHeaders; @@ -192,7 +192,7 @@ export class JsonControllerService { const consumes: string[] = [ ]; - return this.httpClient.request>('get',`${this.basePath}/api/v1/json/export-job-scheduled-by-priority`, + return this.httpClient.request>('get',`${this.basePath}/api/v1/json/export-job-scheduled-by-priority`, { withCredentials: this.configuration.withCredentials, headers: headers, @@ -208,9 +208,9 @@ export class JsonControllerService { * @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 exportJobScheduledRO(observe?: 'body', reportProgress?: boolean): Observable>; - public exportJobScheduledRO(observe?: 'response', reportProgress?: boolean): Observable>>; - public exportJobScheduledRO(observe?: 'events', reportProgress?: boolean): Observable>>; + public exportJobScheduledRO(observe?: 'body', reportProgress?: boolean): Observable>; + public exportJobScheduledRO(observe?: 'response', reportProgress?: boolean): Observable>>; + public exportJobScheduledRO(observe?: 'events', reportProgress?: boolean): Observable>>; public exportJobScheduledRO(observe: any = 'body', reportProgress: boolean = false ): Observable { let headers = this.defaultHeaders; @@ -228,7 +228,7 @@ export class JsonControllerService { const consumes: string[] = [ ]; - return this.httpClient.request>('get',`${this.basePath}/api/v1/json/export-job-scheduled-ro`, + return this.httpClient.request>('get',`${this.basePath}/api/v1/json/export-job-scheduled-ro`, { withCredentials: this.configuration.withCredentials, headers: headers, diff --git a/Frontend/src/app/generated-api/encoder.ts b/Frontend/src/app/generated-api/encoder.ts index bea26d3..f506bfb 100644 --- a/Frontend/src/app/generated-api/encoder.ts +++ b/Frontend/src/app/generated-api/encoder.ts @@ -10,7 +10,7 @@ export class CustomHttpUrlEncodingCodec extends HttpUrlEncodingCodec { k = super.encodeKey(k); return k.replace(/\+/gi, '%2B'); } - override encodeValue(v: string): string { + override encodeValue(v: string): string { v = super.encodeValue(v); return v.replace(/\+/gi, '%2B'); } diff --git a/Frontend/src/app/generated-api/model/models.ts b/Frontend/src/app/generated-api/model/models.ts index dfa5aa7..de6e6e5 100644 --- a/Frontend/src/app/generated-api/model/models.ts +++ b/Frontend/src/app/generated-api/model/models.ts @@ -5,5 +5,6 @@ export * from './machineDTO'; export * from './machineType'; export * from './machineTypeDTO'; export * from './scheduleDTO'; +export * from './scheduleWithMachineDTO'; export * from './user'; export * from './userDTO'; diff --git a/Frontend/src/app/generated-api/model/scheduleWithMachineDTO.ts b/Frontend/src/app/generated-api/model/scheduleWithMachineDTO.ts new file mode 100644 index 0000000..6accb75 --- /dev/null +++ b/Frontend/src/app/generated-api/model/scheduleWithMachineDTO.ts @@ -0,0 +1,32 @@ +/** + * OpenAPI definition + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * OpenAPI spec version: v0 + * + * + * NOTE: This class is auto generated by the swagger code generator program. + * https://github.com/swagger-api/swagger-codegen.git + * Do not edit the class manually. + */ + +export interface ScheduleWithMachineDTO { + id?: number; + jobId?: number; + machineTypeId?: number; + machineId?: number; + startTime?: Date; + dueDate?: Date; + duration?: number; + status?: ScheduleWithMachineDTO.StatusEnum; +} +export namespace ScheduleWithMachineDTO { + export type StatusEnum = 'PENDING' | 'SCHEDULED' | 'IN_PROGRESS' | 'COMPLETED' | 'CANCELLED'; + export const StatusEnum = { + PENDING: 'PENDING' as StatusEnum, + SCHEDULED: 'SCHEDULED' as StatusEnum, + INPROGRESS: 'IN_PROGRESS' as StatusEnum, + COMPLETED: 'COMPLETED' as StatusEnum, + CANCELLED: 'CANCELLED' as StatusEnum + }; +} \ No newline at end of file