Skip to content

Commit

Permalink
dynamic modal
Browse files Browse the repository at this point in the history
  • Loading branch information
SharglutDev committed Oct 9, 2024
1 parent ab53bdb commit 65f7fd5
Show file tree
Hide file tree
Showing 13 changed files with 290 additions and 94 deletions.
32 changes: 29 additions & 3 deletions front/src/applications/operationalStudies/Home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { Spinner } from 'common/Loaders';
import SelectionToolbar from 'common/SelectionToolbar';
import ProjectCard from 'modules/project/components/ProjectCard';
import ProjectCardEmpty from 'modules/project/components/ProjectCardEmpty';
import { cleanScenarioLocalStorage } from 'modules/scenario/helpers/utils';
import { getUserSafeWord } from 'reducers/user/userSelectors';
import { getLogo } from 'utils/logo';

Expand All @@ -29,24 +30,47 @@ type SortOptions =
| 'LastModifiedAsc'
| 'LastModifiedDesc';

export default function HomeOperationalStudies() {
const HomeOperationalStudies = () => {
const { t } = useTranslation('operationalStudies/home');
const safeWord = useSelector(getUserSafeWord);
const [sortOption, setSortOption] = useState<SortOptions>('LastModifiedDesc');
const [filter, setFilter] = useState('');
const [filterChips, setFilterChips] = useState('');
const [deleteProject] = osrdEditoastApi.endpoints.deleteProjectsByProjectId.useMutation();

const [getStudies] = osrdEditoastApi.endpoints.getProjectsByProjectIdStudies.useLazyQuery();
const [getScenarios] =
osrdEditoastApi.endpoints.getProjectsByProjectIdStudiesAndStudyIdScenarios.useLazyQuery();

const {
selectedItemIds: selectedProjectIds,
setSelectedItemIds: setSelectedProjectIds,
items: projectsList,
setItems: setProjectsList,
toggleSelection: toggleProjectSelection,
deleteItems,
} = useMultiSelection<ProjectWithStudies | SearchResultItemProject>((projectId) => {
} = useMultiSelection<ProjectWithStudies | SearchResultItemProject>(async (projectId) => {
// For each scenario in the selected projects, clean the local storage if a manchette is saved
const { data: studies } = await getStudies({ projectId });
if (studies) {
const promisedScenarios = studies.results.map(async (study) => {
const { data } = await getScenarios({
projectId,
studyId: study.id,
});
return data?.results;
});

const scenarios = await Promise.all(promisedScenarios);

scenarios.flat().forEach((scenario) => {
if (scenario) cleanScenarioLocalStorage(scenario.timetable_id);
});
}

deleteProject({ projectId });
});

const handleDeleteProjects = () => {
if (selectedProjectIds.length > 0) {
deleteItems();
Expand Down Expand Up @@ -187,4 +211,6 @@ export default function HomeOperationalStudies() {
</main>
</>
);
}
};

export default HomeOperationalStudies;
66 changes: 42 additions & 24 deletions front/src/applications/operationalStudies/views/Project.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import OptionsSNCF from 'common/BootstrapSNCF/OptionsSNCF';
import { Loader, Spinner } from 'common/Loaders';
import SelectionToolbar from 'common/SelectionToolbar';
import AddOrEditProjectModal from 'modules/project/components/AddOrEditProjectModal';
import { cleanScenarioLocalStorage } from 'modules/scenario/helpers/utils';
import StudyCard from 'modules/study/components/StudyCard';
import StudyCardEmpty from 'modules/study/components/StudyCardEmpty';
import { budgetFormat } from 'utils/numbers';
Expand All @@ -40,7 +41,7 @@ type ProjectParams = {
projectId: string;
};

export default function Project() {
const Project = () => {
const { t } = useTranslation(['operationalStudies/project']);
const { openModal } = useModal();
const [filter, setFilter] = useState('');
Expand All @@ -61,15 +62,46 @@ export default function Project() {
[urlProjectId]
);

const {
data: project,
isError: isProjectError,
error: projectError,
} = osrdEditoastApi.endpoints.getProjectsByProjectId.useQuery(
{ projectId: +projectId! },
{
skip: !projectId,
}
);

const { data: projectStudies } = osrdEditoastApi.endpoints.getProjectsByProjectIdStudies.useQuery(
{
projectId: Number(projectId),
ordering: sortOption,
pageSize: 1000,
},
{ skip: !projectId }
);

const [getScenarios] =
osrdEditoastApi.endpoints.getProjectsByProjectIdStudiesAndStudyIdScenarios.useLazyQuery();

const {
selectedItemIds: selectedStudyIds,
setSelectedItemIds: setSelectedStudyIds,
items: studiesList,
setItems: setStudiesList,
toggleSelection: toggleStudySelection,
deleteItems,
} = useMultiSelection<StudyWithScenarios>((studyId) => {
} = useMultiSelection<StudyWithScenarios>(async (studyId) => {
deleteStudy({ projectId: projectId!, studyId });

// For each scenario in the selected studies, clean the local storage if a manchette is saved
const { data: scenarios } = await getScenarios({ projectId: projectId!, studyId });
if (scenarios) {
scenarios.results.forEach((scenario) => {
cleanScenarioLocalStorage(scenario.timetable_id);
});
}
});

const handleDeleteStudy = () => {
Expand All @@ -88,26 +120,6 @@ export default function Project() {
},
];

const {
data: project,
isError: isProjectError,
error: projectError,
} = osrdEditoastApi.endpoints.getProjectsByProjectId.useQuery(
{ projectId: +projectId! },
{
skip: !projectId,
}
);

const { data: projectStudies } = osrdEditoastApi.endpoints.getProjectsByProjectIdStudies.useQuery(
{
projectId: Number(projectId),
ordering: sortOption,
pageSize: 1000,
},
{ skip: !projectId }
);

const updateImage = async () => {
if (project?.image) {
const image = await getDocument(project.image);
Expand Down Expand Up @@ -226,7 +238,11 @@ export default function Project() {
type="button"
onClick={() =>
openModal(
<AddOrEditProjectModal editionMode project={project} />,
<AddOrEditProjectModal
editionMode
project={project}
projectStudies={projectStudies?.results}
/>,
'xl',
'no-close-modal'
)
Expand Down Expand Up @@ -330,4 +346,6 @@ export default function Project() {
</main>
</>
);
}
};

export default Project;
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,11 @@ const SimulationResults = ({
infraId
);

const projectedOperationalPoints = useGetProjectedTrainOperationalPoints(
const {
operationalPoints: projectedOperationalPoints,
filteredOperationalPoints,
setFilteredOperationalPoints,
} = useGetProjectedTrainOperationalPoints(
projectionData?.trainSchedule,
projectionData?.trainSchedule.id,
infraId
Expand Down Expand Up @@ -153,6 +157,11 @@ const SimulationResults = ({
operationalPoints={projectedOperationalPoints}
projectPathTrainResult={projectPathTrainResult}
selectedTrainScheduleId={selectedTrainSchedule?.id}
waypointsModalData={{
filteredOperationalPoints,
setFilteredOperationalPoints,
projectedTrainPath: projectionData.trainSchedule.path,
}}
/>
</div>
</div>
Expand Down
17 changes: 14 additions & 3 deletions front/src/applications/operationalStudies/views/Study.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { Loader, Spinner } from 'common/Loaders';
import SelectionToolbar from 'common/SelectionToolbar';
import ScenarioCard from 'modules/scenario/components/ScenarioCard';
import ScenarioCardEmpty from 'modules/scenario/components/ScenarioCardEmpty';
import { cleanScenarioLocalStorage } from 'modules/scenario/helpers/utils';
import AddOrEditStudyModal from 'modules/study/components/AddOrEditStudyModal';
import { budgetFormat } from 'utils/numbers';

Expand All @@ -40,7 +41,7 @@ type studyParams = {
studyId: string;
};

export default function Study() {
const Study = () => {
const { t } = useTranslation(['operationalStudies/study']);
const { openModal } = useModal();
const { projectId: urlProjectId, studyId: urlStudyId } = useParams() as studyParams;
Expand Down Expand Up @@ -98,6 +99,10 @@ export default function Study() {
deleteItems,
} = useMultiSelection<ScenarioWithDetails>((scenarioId) => {
deleteScenario({ projectId: projectId!, studyId: studyId!, scenarioId });

// For each scenarios, clean the local storage if a manchette is saved
const deletedScenario = scenarios!.results.find((scenario) => scenario.id === scenarioId);
cleanScenarioLocalStorage(deletedScenario!.timetable_id);
});
const handleDeleteScenario = () => {
if (selectedScenarioIds.length > 0 && studyId && projectId) {
Expand Down Expand Up @@ -247,7 +252,11 @@ export default function Study() {
type="button"
onClick={() =>
openModal(
<AddOrEditStudyModal editionMode study={study} />,
<AddOrEditStudyModal
editionMode
study={study}
scenarios={scenarios?.results}
/>,
'xl',
'no-close-modal'
)
Expand Down Expand Up @@ -370,4 +379,6 @@ export default function Study() {
</main>
</>
);
}
};

export default Study;
71 changes: 48 additions & 23 deletions front/src/modules/project/components/AddOrEditProjectModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@ import remarkGfm from 'remark-gfm';
import PictureUploader from 'applications/operationalStudies/components/Project/PictureUploader';
import { postDocument } from 'common/api/documentApi';
import { osrdEditoastApi } from 'common/api/osrdEditoastApi';
import type { ProjectWithStudies, ProjectCreateForm } from 'common/api/osrdEditoastApi';
import type {
ProjectWithStudies,
ProjectCreateForm,
StudyWithScenarios,
} from 'common/api/osrdEditoastApi';
import ChipsSNCF from 'common/BootstrapSNCF/ChipsSNCF';
import InputSNCF from 'common/BootstrapSNCF/InputSNCF';
import { ConfirmModal } from 'common/BootstrapSNCF/ModalSNCF';
Expand All @@ -24,6 +28,7 @@ import ModalHeaderSNCF from 'common/BootstrapSNCF/ModalSNCF/ModalHeaderSNCF';
import { ModalContext } from 'common/BootstrapSNCF/ModalSNCF/ModalProvider';
import TextareaSNCF from 'common/BootstrapSNCF/TextareaSNCF';
import { useOsrdConfActions } from 'common/osrdContext';
import { cleanScenarioLocalStorage } from 'modules/scenario/helpers/utils';
import { setFailure, setSuccess } from 'reducers/main';
import { getUserSafeWord } from 'reducers/user/userSelectors';
import { useAppDispatch } from 'store';
Expand Down Expand Up @@ -53,12 +58,14 @@ type AddOrEditProjectModalProps = {
editionMode?: boolean;
project?: ProjectWithStudies;
getProject?: (v: boolean) => void;
projectStudies?: StudyWithScenarios[];
};

export default function AddOrEditProjectModal({
editionMode,
project,
getProject,
projectStudies,
}: AddOrEditProjectModalProps) {
const { t } = useTranslation(['operationalStudies/project', 'translation']);
const { closeModal, isOpen } = useContext(ModalContext);
Expand All @@ -70,6 +77,8 @@ export default function AddOrEditProjectModal({
const navigate = useNavigate();
const safeWord = useSelector(getUserSafeWord);

const [getScenarios] =
osrdEditoastApi.endpoints.getProjectsByProjectIdStudiesAndStudyIdScenarios.useLazyQuery();
const [postProject] = osrdEditoastApi.endpoints.postProjects.useMutation();
const [patchProject] = osrdEditoastApi.endpoints.patchProjectsByProjectId.useMutation();
const [deleteProject] = osrdEditoastApi.endpoints.deleteProjectsByProjectId.useMutation();
Expand Down Expand Up @@ -204,30 +213,46 @@ export default function AddOrEditProjectModal({
};

const removeProject = async () => {
if (project) {
await deleteProject({ projectId: project.id })
.unwrap()
.then(() => {
dispatch(updateProjectID(undefined));
navigate(`/operational-studies/projects/`);
closeModal();
dispatch(
setSuccess({
title: t('projectDeleted'),
text: t('projectDeletedDetails', { name: project.name }),
})
);
})
.catch((e) => {
dispatch(
setFailure(
castErrorToFailure(e, {
name: t('error.unableToDeleteProject'),
})
)
);
if (projectStudies) {
// For each scenario in the project, clean the local storage if a manchette is saved
const promisedScenarios = projectStudies.map(async (study) => {
const { data } = await getScenarios({
projectId: project!.id,
studyId: study.id,
});
return data?.results;
});

const scenarios = await Promise.all(promisedScenarios);

scenarios.flat().forEach((scenario) => {
if (scenario) cleanScenarioLocalStorage(scenario.timetable_id);
});
}

await deleteProject({ projectId: project!.id })
.unwrap()
.then(async () => {
dispatch(updateProjectID(undefined));

navigate(`/operational-studies/projects/`);
closeModal();
dispatch(
setSuccess({
title: t('projectDeleted'),
text: t('projectDeletedDetails', { name: project!.name }),
})
);
})
.catch((e) => {
dispatch(
setFailure(
castErrorToFailure(e, {
name: t('error.unableToDeleteProject'),
})
)
);
});
};

const debouncedObjectives = useDebounce(currentProject.objectives, 500);
Expand Down
Loading

0 comments on commit 65f7fd5

Please sign in to comment.