diff --git a/editoast/openapi.yaml b/editoast/openapi.yaml index 6b0e937ecfc..c0c7710a5f4 100644 --- a/editoast/openapi.yaml +++ b/editoast/openapi.yaml @@ -2748,7 +2748,7 @@ paths: application/json: schema: $ref: '#/components/schemas/WorkScheduleCreateResponse' - /work_schedules/project: + /work_schedules/project_path: post: tags: - work_schedules @@ -2756,17 +2756,63 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/WorkScheduleProjectForm' + type: object + required: + - work_schedule_group_id + - path_track_ranges + properties: + path_track_ranges: + type: array + items: + $ref: '#/components/schemas/TrackRange' + work_schedule_group_id: + type: integer + format: int64 required: true responses: '201': - description: Returns a list of work schedule whose track ranges intersect the given path + description: Returns a list of work schedules whose track ranges intersect the given path content: application/json: schema: type: array items: - $ref: '#/components/schemas/WorkScheduleProjection' + type: object + description: |- + This struct represents the projection of one work_schedule on a path. + it takes the type, start time, end time of the work_schedule + as well as a list of ranges (a, b), + where a and b are the distance of the beginning and end of the track range + relatively to the beginning of the path. + required: + - type + - start_date_time + - end_date_time + - path_position_ranges + properties: + end_date_time: + type: string + format: date-time + path_position_ranges: + type: array + items: + type: array + items: + allOf: + - type: integer + format: int64 + minimum: 0 + - type: integer + format: int64 + minimum: 0 + start_date_time: + type: string + format: date-time + type: + type: string + enum: + - CATENARY + - TRACK components: schemas: AddOperation: @@ -9894,58 +9940,6 @@ components: enum: - CATENARY - TRACK - WorkScheduleProjectForm: - type: object - required: - - work_schedule_group_id - - path_track_ranges - properties: - path_track_ranges: - type: array - items: - $ref: '#/components/schemas/TrackRange' - work_schedule_group_id: - type: integer - format: int64 - WorkScheduleProjection: - type: object - description: |- - This struct represents the projection of one work_schedule on a path. - it takes the type, start time, end time of the work_schedule - as well as a list of ranges (a, b), - where a and b are the distance of the beginning and end of the track range - relatively to the beginning of the path. - required: - - type - - start_date_time - - end_date_time - - path_position_ranges - properties: - end_date_time: - type: string - format: date-time - path_position_ranges: - type: array - items: - type: array - items: - allOf: - - type: integer - format: int64 - minimum: 0 - - type: integer - format: int64 - minimum: 0 - start_date_time: - type: string - format: date-time - type: - $ref: '#/components/schemas/WorkScheduleType' - WorkScheduleType: - type: string - enum: - - CATENARY - - TRACK ZoneUpdate: type: object required: diff --git a/editoast/src/models/fixtures.rs b/editoast/src/models/fixtures.rs index 2a48b771d2a..a15b5c45048 100644 --- a/editoast/src/models/fixtures.rs +++ b/editoast/src/models/fixtures.rs @@ -30,7 +30,6 @@ use crate::models::Study; use crate::models::Tags; use crate::views::rolling_stock::form::RollingStockForm; use crate::views::train_schedule::TrainScheduleForm; -use crate::views::work_schedules::WorkScheduleItemForm; use crate::ElectricalProfileSet; pub fn project_changeset(name: &str) -> Changeset { @@ -311,26 +310,18 @@ pub async fn create_work_schedule_group(conn: &mut DbConnection) -> WorkSchedule .expect("Failed to create empty work schedule group") } -pub struct WorkSchedulesFixtureSet { - pub work_schedule_group: WorkScheduleGroup, - pub work_schedules: Vec, -} - pub async fn create_work_schedules_fixture_set( conn: &mut DbConnection, - work_schedules: Vec, -) -> WorkSchedulesFixtureSet { + work_schedules: Vec>, +) -> (WorkScheduleGroup, Vec) { let work_schedule_group = create_work_schedule_group(conn).await; let work_schedules_changesets = work_schedules .into_iter() - .map(|work_schedule| work_schedule.into_work_schedule_changeset(work_schedule_group.id)) + .map(|ws| ws.work_schedule_group_id(work_schedule_group.id)) .collect::>(); let work_schedules = WorkSchedule::create_batch(conn, work_schedules_changesets) .await .expect("Failed to create work test schedules"); - WorkSchedulesFixtureSet { - work_schedule_group, - work_schedules, - } + (work_schedule_group, work_schedules) } diff --git a/editoast/src/views/work_schedules.rs b/editoast/src/views/work_schedules.rs index b93d6fb472d..5220faa6798 100644 --- a/editoast/src/views/work_schedules.rs +++ b/editoast/src/views/work_schedules.rs @@ -6,6 +6,7 @@ use chrono::Utc; use derivative::Derivative; use editoast_authz::BuiltinRole; use editoast_derive::EditoastError; +use editoast_models::DbConnectionPoolV2; use serde::de::Error as SerdeError; use serde::Deserialize; use serde::Serialize; @@ -29,17 +30,14 @@ use editoast_schemas::infra::{Direction, TrackRange}; crate::routes! { "/work_schedules" => { create, - "/project" => project, + "/project_path" => project_path, }, } editoast_common::schemas! { WorkScheduleCreateForm, WorkScheduleCreateResponse, - WorkScheduleProjectForm, - WorkScheduleProjection, WorkScheduleItemForm, - WorkScheduleType, } #[derive(Debug, Error, EditoastError)] @@ -64,7 +62,7 @@ pub fn map_diesel_error(e: InternalError, name: impl AsRef) -> InternalErro } #[derive(Serialize, Derivative, ToSchema)] -pub struct WorkScheduleItemForm { +struct WorkScheduleItemForm { pub start_date_time: NaiveDateTime, pub end_date_time: NaiveDateTime, pub track_ranges: Vec, @@ -198,6 +196,7 @@ struct WorkScheduleProjectForm { #[derive(Serialize, Deserialize, ToSchema, PartialEq, Debug)] struct WorkScheduleProjection { #[serde(rename = "type")] + #[schema(inline)] pub work_schedule_type: WorkScheduleType, pub start_date_time: NaiveDateTime, pub end_date_time: NaiveDateTime, @@ -207,17 +206,17 @@ struct WorkScheduleProjection { #[utoipa::path( post, path = "", tag = "work_schedules", - request_body = WorkScheduleProjectForm, + request_body = inline(WorkScheduleProjectForm), responses( ( status = 201, - body = Vec, - description = "Returns a list of work schedule whose track ranges intersect the given path" + body = inline(Vec), + description = "Returns a list of work schedules whose track ranges intersect the given path" ), ) )] -async fn project( - State(app_state): State, +async fn project_path( + State(db_pool): State, Extension(authorizer): AuthorizerExt, Json(WorkScheduleProjectForm { work_schedule_group_id, @@ -233,7 +232,6 @@ async fn project( } // get all work_schedule of the group - let db_pool = app_state.db_pool_v2.clone(); let conn = &mut db_pool.get().await?; let settings: SelectionSettings = SelectionSettings::new() .filter(move || WorkSchedule::WORK_SCHEDULE_GROUP_ID.eq(work_schedule_group_id)); @@ -241,8 +239,9 @@ async fn project( let projections = work_schedules .into_iter() - .filter_map(|ws| { + .map(|ws| { let ws_track_ranges: Vec<_> = ws + .clone() .track_ranges .into_iter() .map(|tr| CoreTrackRange { @@ -255,7 +254,9 @@ async fn project( let path_projection = PathProjection::new(&ws_track_ranges); // project this work_schedule on the path - let path_position_ranges = path_projection.get_intersections(&path_track_ranges); + (ws, path_projection.get_intersections(&path_track_ranges)) + }) + .filter_map(|(ws, path_position_ranges)| { if path_position_ranges.is_empty() { None } else { @@ -281,8 +282,7 @@ pub mod test { use super::*; use crate::{ - models::fixtures::{create_work_schedules_fixture_set, WorkSchedulesFixtureSet}, - views::test_app::TestAppBuilder, + models::fixtures::create_work_schedules_fixture_set, views::test_app::TestAppBuilder, }; #[rstest] @@ -426,30 +426,33 @@ pub mod test { let conn = &mut pool.get_ok(); // create work schedules - let working_schedules_form = work_schedule_track_ranges + let working_schedules_changeset = work_schedule_track_ranges .into_iter() .enumerate() - .map(|(index, track_ranges)| WorkScheduleItemForm { - start_date_time: NaiveDate::from_ymd_opt(2024, 1, (index + 1).try_into().unwrap()) - .unwrap() - .and_hms_opt(0, 0, 0) - .unwrap(), - end_date_time: NaiveDate::from_ymd_opt(2024, 1, (index + 2).try_into().unwrap()) - .unwrap() - .and_hms_opt(0, 0, 0) - .unwrap(), - track_ranges, - obj_id: format!("work_schedule_{}", index), - work_schedule_type: WorkScheduleType::Track, + .map(|(index, track_ranges)| { + let start_date_time = + NaiveDate::from_ymd_opt(2024, 1, (index + 1).try_into().unwrap()) + .unwrap() + .and_hms_opt(0, 0, 0) + .unwrap(); + let end_date_time = + NaiveDate::from_ymd_opt(2024, 1, (index + 2).try_into().unwrap()) + .unwrap() + .and_hms_opt(0, 0, 0) + .unwrap(); + WorkSchedule::changeset() + .start_date_time(start_date_time) + .end_date_time(end_date_time) + .track_ranges(track_ranges) + .obj_id(format!("work_schedule_{}", index)) + .work_schedule_type(WorkScheduleType::Track) }) .collect(); - let WorkSchedulesFixtureSet { - work_schedule_group, - work_schedules, - } = create_work_schedules_fixture_set(conn, working_schedules_form).await; + let (work_schedule_group, work_schedules) = + create_work_schedules_fixture_set(conn, working_schedules_changeset).await; - let request = app.post("/work_schedules/project").json(&json!({ + let request = app.post("/work_schedules/project_path").json(&json!({ "work_schedule_group_id": work_schedule_group.id, "path_track_ranges": [ { diff --git a/front/src/common/api/generatedEditoastApi.ts b/front/src/common/api/generatedEditoastApi.ts index 7af7a3e2471..ccd7011a200 100644 --- a/front/src/common/api/generatedEditoastApi.ts +++ b/front/src/common/api/generatedEditoastApi.ts @@ -811,16 +811,16 @@ const injectedRtkApi = api }), invalidatesTags: ['work_schedules'], }), - postWorkSchedulesProject: build.mutation< - PostWorkSchedulesProjectApiResponse, - PostWorkSchedulesProjectApiArg + postWorkSchedulesProjectPath: build.query< + PostWorkSchedulesProjectPathApiResponse, + PostWorkSchedulesProjectPathApiArg >({ query: (queryArg) => ({ - url: `/work_schedules/project`, + url: `/work_schedules/project_path`, method: 'POST', - body: queryArg.workScheduleProjectForm, + body: queryArg.body, }), - invalidatesTags: ['work_schedules'], + providesTags: ['work_schedules'], }), }), overrideExisting: false, @@ -1490,10 +1490,18 @@ export type PostWorkSchedulesApiResponse = export type PostWorkSchedulesApiArg = { workScheduleCreateForm: WorkScheduleCreateForm; }; -export type PostWorkSchedulesProjectApiResponse = - /** status 201 Returns a list of work schedule whose track ranges intersect the given path */ WorkScheduleProjection[]; -export type PostWorkSchedulesProjectApiArg = { - workScheduleProjectForm: WorkScheduleProjectForm; +export type PostWorkSchedulesProjectPathApiResponse = + /** status 201 Returns a list of work schedules whose track ranges intersect the given path */ { + end_date_time: string; + path_position_ranges: (number & number)[][]; + start_date_time: string; + type: 'CATENARY' | 'TRACK'; + }[]; +export type PostWorkSchedulesProjectPathApiArg = { + body: { + path_track_ranges: TrackRange[]; + work_schedule_group_id: number; + }; }; export type NewDocumentResponse = { document_key: number; @@ -3045,14 +3053,3 @@ export type WorkScheduleCreateForm = { work_schedule_group_name: string; work_schedules: WorkScheduleItemForm[]; }; -export type WorkScheduleType = 'CATENARY' | 'TRACK'; -export type WorkScheduleProjection = { - end_date_time: string; - path_position_ranges: (number & number)[][]; - start_date_time: string; - type: WorkScheduleType; -}; -export type WorkScheduleProjectForm = { - path_track_ranges: TrackRange[]; - work_schedule_group_id: number; -}; diff --git a/front/src/config/openapi-editoast-config.ts b/front/src/config/openapi-editoast-config.ts index 87e8f7805bf..8cf109f257e 100644 --- a/front/src/config/openapi-editoast-config.ts +++ b/front/src/config/openapi-editoast-config.ts @@ -14,6 +14,7 @@ const config: ConfigFile = { 'postTrainSchedule', 'postTrainScheduleSimulationSummary', 'postTrainScheduleProjectPath', + 'postWorkSchedulesProjectPath', ], type: 'query', },