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 715e488..667be76 100644 --- a/Backend/src/main/java/unical/demacs/rdm/controller/JsonController.java +++ b/Backend/src/main/java/unical/demacs/rdm/controller/JsonController.java @@ -6,21 +6,15 @@ import org.springframework.http.*; import org.springframework.web.bind.annotation.*; import unical.demacs.rdm.config.ModelMapperExtended; -import unical.demacs.rdm.persistence.dto.JobDTO; -import unical.demacs.rdm.persistence.dto.MachineDTO; -import unical.demacs.rdm.persistence.dto.MachineTypeDTO; -import unical.demacs.rdm.persistence.dto.ScheduleWithMachineDTO; +import unical.demacs.rdm.persistence.dto.*; import unical.demacs.rdm.persistence.entities.Job; import unical.demacs.rdm.persistence.entities.Machine; import unical.demacs.rdm.persistence.entities.MachineType; -import unical.demacs.rdm.persistence.service.interfaces.IJobService; -import unical.demacs.rdm.persistence.service.interfaces.IJsonService; -import unical.demacs.rdm.persistence.service.interfaces.IMachineService; -import unical.demacs.rdm.persistence.service.interfaces.IMachineTypeService; +import unical.demacs.rdm.persistence.entities.Schedule; +import unical.demacs.rdm.persistence.service.interfaces.*; import java.util.List; import java.util.Map; -import java.util.Optional; @RestController @RequestMapping(value = "/api/v1/json", produces = "application/json") @@ -33,6 +27,7 @@ public class JsonController { private final IMachineService machineService; private final IMachineTypeService machineTypeService; private final IJsonService jsonService; + private final IScheduleService scheduleService; private final ModelMapperExtended modelMapperExtended; @Operation(summary = "Import Job data from JSON", description = "Import Job data into the system from JSON content.", @@ -144,15 +139,9 @@ public ResponseEntity> exportJobScheduledRO() { @Operation(summary = "Download all Schedules as JSON", description = "Download all Schedules as a JSON file.", tags = {"json-controller"}) @GetMapping(value = "/download-schedules", produces = MediaType.APPLICATION_JSON_VALUE) - public ResponseEntity downloadSchedules() { - try { - byte[] jsonContent = jsonService.exportSchedulesToJson(); - HttpHeaders headers = new HttpHeaders(); - headers.setContentDisposition(ContentDisposition.builder("attachment").filename("schedules.json").build()); - headers.setContentType(MediaType.APPLICATION_JSON); - return new ResponseEntity<>(jsonContent, headers, HttpStatus.OK); - } catch (Exception e) { - return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Error exporting schedules: ".getBytes()); - } + public ResponseEntity> downloadSchedules() { + List schedules = scheduleService.getAllSchedules(); + return ResponseEntity.ok(modelMapperExtended.mapList(schedules, ScheduleDTO.class)); } + } \ 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 895f309..eb446a2 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 @@ -4,14 +4,12 @@ import lombok.AllArgsConstructor; import org.springframework.stereotype.Service; import unical.demacs.rdm.persistence.dto.*; -import unical.demacs.rdm.persistence.entities.Schedule; import unical.demacs.rdm.persistence.repository.ScheduleRepository; import unical.demacs.rdm.persistence.service.interfaces.IJsonService; import java.io.File; import java.io.IOException; import java.util.List; -import java.util.stream.Collectors; @Service @AllArgsConstructor @@ -30,30 +28,4 @@ public List readScheduleFile(String fileName) { } } - public List getAllSchedules() { - List schedules = scheduleRepository.findAll(); - return schedules.stream() - .map(schedule -> new ScheduleDTO( - schedule.getId(), - schedule.getJob().getId(), - schedule.getMachineType().getId(), - schedule.getDueDate(), - schedule.getStartTime(), - schedule.getDuration(), - schedule.getStatus(), - schedule.getMachine() != null ? schedule.getMachine().getId() : null, - schedule.getMachine() != null ? schedule.getMachine().getName() : null - )) - .collect(Collectors.toList()); - } - - public byte[] exportSchedulesToJson() { - try { - List schedules = getAllSchedules(); - return objectMapper.writeValueAsBytes(schedules); - } catch (IOException e) { - throw new RuntimeException("Errore durante l'esportazione degli schedule in JSON", 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 3e46ba2..d80feb4 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,12 +1,10 @@ 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 getAllSchedules(); - public byte[] exportSchedulesToJson(); } \ No newline at end of file diff --git a/Frontend/package-lock.json b/Frontend/package-lock.json index 7d010b7..a036f70 100644 --- a/Frontend/package-lock.json +++ b/Frontend/package-lock.json @@ -9153,7 +9153,6 @@ "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true, "license": "MIT" }, "node_modules/lodash.debounce": { diff --git a/Frontend/src/app/components/schedule/schedule.component.ts b/Frontend/src/app/components/schedule/schedule.component.ts index 4000bf1..e4dc5de 100644 --- a/Frontend/src/app/components/schedule/schedule.component.ts +++ b/Frontend/src/app/components/schedule/schedule.component.ts @@ -431,13 +431,22 @@ export class ScheduleComponent implements OnInit { protected readonly Number = Number; downloadSchedules() { - this.jsonService.downloadSchedules().subscribe(response => { - const blob = new Blob([response], { type: 'application/json' }); + this.jsonService.downloadSchedules('body').subscribe(response => { + const jsonResponse = JSON.stringify(response); + const blob = new Blob([jsonResponse], { type: 'application/json' }); const link = document.createElement('a'); link.href = URL.createObjectURL(blob); link.download = 'schedules.json'; link.click(); }); - } - + this.jsonService.exportMachine('body').subscribe(machineResponse => { + const machineJsonResponse = JSON.stringify(machineResponse); + const machineBlob = new Blob([machineJsonResponse], { type: 'application/json' }); + const machineLink = document.createElement('a'); + machineLink.href = URL.createObjectURL(machineBlob); + machineLink.download = 'machines.json'; + machineLink.click(); + }); + } + } diff --git a/Frontend/src/app/generated-api/api/jsonController.service.ts b/Frontend/src/app/generated-api/api/jsonController.service.ts index 7a0ee2e..1a81468 100644 --- a/Frontend/src/app/generated-api/api/jsonController.service.ts +++ b/Frontend/src/app/generated-api/api/jsonController.service.ts @@ -20,6 +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'; @@ -59,15 +60,15 @@ export class JsonControllerService { /** - * Export Job data to JSON - * Export all Job data to JSON. + * Download all Schedules as JSON + * Download all Schedules as a JSON file. * @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 exportJob(observe?: 'body', reportProgress?: boolean): Observable>; - public exportJob(observe?: 'response', reportProgress?: boolean): Observable>>; - public exportJob(observe?: 'events', reportProgress?: boolean): Observable>>; - public exportJob(observe: any = 'body', reportProgress: boolean = false ): Observable { + public downloadSchedules(observe?: 'body', reportProgress?: boolean): Observable>; + public downloadSchedules(observe?: 'response', reportProgress?: boolean): Observable>>; + public downloadSchedules(observe?: 'events', reportProgress?: boolean): Observable>>; + public downloadSchedules(observe: any = 'body', reportProgress: boolean = false ): Observable { let headers = this.defaultHeaders; @@ -84,7 +85,7 @@ export class JsonControllerService { const consumes: string[] = [ ]; - return this.httpClient.request>('get',`${this.basePath}/api/v1/json/exportJob`, + return this.httpClient.request>('get',`${this.basePath}/api/v1/json/download-schedules`, { withCredentials: this.configuration.withCredentials, headers: headers, @@ -95,18 +96,19 @@ export class JsonControllerService { } /** - * Download schedules as a JSON file - * This method triggers the download of the schedules JSON file. - * @param observe set whether or not to return the data Observable as the body, response or events. + * Export Job data to JSON + * Export all Job data to JSON. + * @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 downloadSchedules(observe?: 'body', reportProgress?: boolean): Observable; - public downloadSchedules(observe?: 'response', reportProgress?: boolean): Observable>; - public downloadSchedules(observe?: 'events', reportProgress?: boolean): Observable>; - public downloadSchedules(observe: any = 'body', reportProgress: boolean = false ): Observable { + public exportJob(observe?: 'body', reportProgress?: boolean): Observable>; + public exportJob(observe?: 'response', reportProgress?: boolean): Observable>>; + public exportJob(observe?: 'events', reportProgress?: boolean): Observable>>; + public exportJob(observe: any = 'body', reportProgress: boolean = false ): Observable { let headers = this.defaultHeaders; + // to determine the Accept header let httpHeaderAccepts: string[] = [ 'application/json' ]; @@ -115,13 +117,18 @@ export class JsonControllerService { headers = headers.set('Accept', httpHeaderAcceptSelected); } - return this.httpClient.request('get', `${this.basePath}/api/v1/json/download-schedules`, { - withCredentials: this.configuration.withCredentials, - headers: headers, - observe: observe, - responseType: 'blob', - reportProgress: reportProgress - }); + // to determine the Content-Type header + const consumes: string[] = [ + ]; + + return this.httpClient.request>('get',`${this.basePath}/api/v1/json/exportJob`, + { + withCredentials: this.configuration.withCredentials, + headers: headers, + observe: observe, + reportProgress: reportProgress + } + ); } /** @@ -233,8 +240,8 @@ export class JsonControllerService { } /** - * Export Job data to JSON - * Export all Job data to JSON. + * Export RO scheduled jobs + * Export all RO scheduled jobs to JSON. * @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. */ @@ -492,4 +499,62 @@ export class JsonControllerService { ); } + /** + * Import Schedules from JSON + * Upload and import Schedules from a JSON file. + * @param file + * @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 importSchedulesForm(file?: Blob, observe?: 'body', reportProgress?: boolean): Observable<{ [key: string]: string; }>; + public importSchedulesForm(file?: Blob, observe?: 'response', reportProgress?: boolean): Observable>; + public importSchedulesForm(file?: Blob, observe?: 'events', reportProgress?: boolean): Observable>; + public importSchedulesForm(file?: Blob, observe: any = 'body', reportProgress: boolean = false ): Observable { + + + let headers = this.defaultHeaders; + + // to determine the Accept header + let httpHeaderAccepts: string[] = [ + 'application/json' + ]; + const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(httpHeaderAccepts); + if (httpHeaderAcceptSelected != undefined) { + headers = headers.set('Accept', httpHeaderAcceptSelected); + } + + // to determine the Content-Type header + const consumes: string[] = [ + 'multipart/form-data' + ]; + + const canConsumeForm = this.canConsumeForm(consumes); + + let formParams: { append(param: string, value: any): void; }; + let useForm = false; + let convertFormParamsToString = false; + // use FormData to transmit files using content-type "multipart/form-data" + // see https://stackoverflow.com/questions/4007969/application-x-www-form-urlencoded-or-multipart-form-data + useForm = canConsumeForm; + if (useForm) { + formParams = new FormData(); + } else { + formParams = new HttpParams({encoder: new CustomHttpUrlEncodingCodec()}); + } + + if (file !== undefined) { + formParams = formParams.append('file', file) as any || formParams; + } + + return this.httpClient.request<{ [key: string]: string; }>('post',`${this.basePath}/api/v1/json/upload-schedules`, + { + body: convertFormParamsToString ? formParams.toString() : formParams, + withCredentials: this.configuration.withCredentials, + headers: headers, + observe: observe, + reportProgress: reportProgress + } + ); + } + } diff --git a/Frontend/src/app/generated-api/model/jsonUploadschedulesBody.ts b/Frontend/src/app/generated-api/model/jsonUploadschedulesBody.ts new file mode 100644 index 0000000..4ed505d --- /dev/null +++ b/Frontend/src/app/generated-api/model/jsonUploadschedulesBody.ts @@ -0,0 +1,15 @@ +/** + * 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 JsonUploadschedulesBody { + file: Blob; +} \ No newline at end of file diff --git a/Frontend/src/app/generated-api/model/models.ts b/Frontend/src/app/generated-api/model/models.ts index de6e6e5..9903fb2 100644 --- a/Frontend/src/app/generated-api/model/models.ts +++ b/Frontend/src/app/generated-api/model/models.ts @@ -1,5 +1,6 @@ export * from './job'; export * from './jobDTO'; +export * from './jsonUploadschedulesBody'; export * from './machine'; export * from './machineDTO'; export * from './machineType';