Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

front: refacto infras list module #4680

Merged
merged 8 commits into from
Aug 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 18 additions & 2 deletions editoast/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2486,6 +2486,22 @@ paths:
description: Check if Editoast is running correctly
/infra/:
get:
parameters:
- description: Page number
in: query
name: page
schema:
default: 1
minimum: 1
type: integer
- description: Number of elements by page
in: query
name: page_size
schema:
default: 25
maximum: 10000
minimum: 1
type: integer
responses:
'200':
content:
Expand All @@ -2505,8 +2521,8 @@ paths:
- next
- previous
type: object
description: The infra list
summary: List all available infra
description: The infras list
summary: Paginated list of all available infras
tags:
- infra
post:
Expand Down
20 changes: 18 additions & 2 deletions editoast/openapi_legacy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -173,10 +173,26 @@ paths:
get:
tags:
- infra
summary: List all available infra
summary: Paginated list of all available infras
parameters:
- description: Page number
in: query
name: page
schema:
default: 1
minimum: 1
type: integer
- description: Number of elements by page
in: query
name: page_size
schema:
default: 25
maximum: 10000
minimum: 1
type: integer
responses:
200:
description: The infra list
description: The infras list
content:
application/json:
schema:
Expand Down
1 change: 1 addition & 0 deletions front/public/locales/fr/infraManagement.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"goToEditionMode": "Éditer",
"goToStandardMode": "Retour à la sélection",
"infraChoice": "Infrastructures",
"infraDeleted": "L'infrastructure {{name}} a bien été supprimée.",
"infraManagement": "Gestion des infrastructures",
"infraName": "Nom de l'infrastructure",
"infrasFound_zero": "Aucune insfrastructure trouvée",
Expand Down
2 changes: 0 additions & 2 deletions front/src/common/InfraSelector/Consts.jsx

This file was deleted.

83 changes: 57 additions & 26 deletions front/src/common/InfraSelector/InfraSelectorEditionActionsBar.tsx
Original file line number Diff line number Diff line change
@@ -1,40 +1,51 @@
import React, { useState } from 'react';
import { FaCopy, FaDownload, FaLock, FaLockOpen, FaPencilAlt } from 'react-icons/fa';
import { useTranslation } from 'react-i18next';
import { post, get, put } from 'common/requests';
import { MdCancel, MdCheck } from 'react-icons/md';
import fileDownload from 'js-file-download';
import { Infra, osrdEditoastApi } from 'common/api/osrdEditoastApi';
import { INFRA_URL } from './Consts';
import { useDispatch } from 'react-redux';
import { setFailure } from 'reducers/main';
import InfraLockState from './consts';

type ActionBarProps = {
infra: Infra;
isFocused?: number;
setIsFocused: (focus?: number) => void;
getInfrasList: () => void;
inputValue: string;
};

export default function ActionsBar({
infra,
isFocused,
setIsFocused,
getInfrasList,
inputValue,
}: ActionBarProps) {
export default function ActionsBar({ infra, isFocused, setIsFocused, inputValue }: ActionBarProps) {
const { t } = useTranslation('infraManagement');
const [isWaiting, setIsWaiting] = useState(false);
const dispatch = useDispatch();

const [lockInfra] = osrdEditoastApi.usePostInfraByIdLockMutation();
const [unlockInfra] = osrdEditoastApi.usePostInfraByIdUnlockMutation();
const [getRailjson] = osrdEditoastApi.useLazyGetInfraByIdRailjsonQuery();
const [cloneInfra] = osrdEditoastApi.usePostInfraByIdCloneMutation();
const [updateInfra] = osrdEditoastApi.usePutInfraByIdMutation();

async function handleLockedState(action: string) {
async function handleLockedState(action: InfraLockState) {
if (!isWaiting) {
setIsWaiting(true);
try {
await post(`${INFRA_URL}${infra.id}/${action}/`, {});
getInfrasList();
setIsWaiting(false);
if (action === InfraLockState.LOCK) {
await lockInfra({ id: infra.id });
}
if (action === InfraLockState.UNLOCK) {
await unlockInfra({ id: infra.id });
}
} catch (e) {
if (e instanceof Error) {
dispatch(
setFailure({
name: e.name,
message: e.message,
})
);
}
} finally {
setIsWaiting(false);
}
}
Expand All @@ -44,10 +55,18 @@ export default function ActionsBar({
if (!isWaiting) {
setIsWaiting(true);
try {
const railjson = await get(`${INFRA_URL}${infra.id}/railjson/`);
const railjson = await getRailjson({ id: infra.id });
fileDownload(JSON.stringify(railjson), `${infra.name}.id${infra.id}.railjson.json`);
setIsWaiting(false);
} catch (e) {
if (e instanceof Error) {
dispatch(
setFailure({
name: e.name,
message: e.message,
})
);
}
} finally {
setIsWaiting(false);
}
}
Expand All @@ -57,26 +76,38 @@ export default function ActionsBar({
if (!isWaiting) {
setIsWaiting(true);
try {
await cloneInfra({ id: infra.id, name: `${infra.name}_copy` }).unwrap();
setIsWaiting(false);
await cloneInfra({ id: infra.id, name: `${infra.name}_copy` });
} catch (e) {
if (e instanceof Error) {
dispatch(
setFailure({
name: e.name,
message: e.message,
})
);
}
} finally {
setIsWaiting(false);
}
setTimeout(() => {
getInfrasList();
}, 1000);
}
}

async function handleRename() {
if (!isWaiting) {
setIsWaiting(true);
try {
await put(`${INFRA_URL}${infra.id}/`, { name: inputValue });
getInfrasList();
await updateInfra({ id: infra.id, body: { name: inputValue } });
setIsFocused(undefined);
setIsWaiting(false);
} catch (e) {
if (e instanceof Error) {
dispatch(
setFailure({
name: e.name,
message: e.message,
})
);
}
} finally {
setIsWaiting(false);
}
}
Expand Down Expand Up @@ -122,7 +153,7 @@ export default function ActionsBar({
className="infraslist-item-action unlock"
type="button"
title={t('infraManagement:actions.unlock')}
onClick={() => handleLockedState('unlock')}
onClick={() => handleLockedState(InfraLockState.UNLOCK)}
>
<FaLockOpen />
</button>
Expand All @@ -131,7 +162,7 @@ export default function ActionsBar({
className="infraslist-item-action lock"
type="button"
title={t('infraManagement:actions.lock')}
onClick={() => handleLockedState('lock')}
onClick={() => handleLockedState(InfraLockState.LOCK)}
>
<FaLock />
</button>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,31 +1,53 @@
import React from 'react';
import PropTypes from 'prop-types';
import { deleteRequest } from 'common/requests';
import { useTranslation } from 'react-i18next';
import Countdown from 'react-countdown';
import { INFRA_URL } from './Consts';
import { Infra, osrdEditoastApi } from 'common/api/osrdEditoastApi';
import { useDispatch } from 'react-redux';
import { setFailure, setSuccess } from 'reducers/main';

export default function InfraSelectorEditionActionsBarDelete(props) {
const { getInfrasList, setRunningDelete, infra } = props;
type InfraSelectorEditionActionsBarDeleteProps = {
infra: Infra;
setRunningDelete: (infraId?: number) => void;
};

export default function InfraSelectorEditionActionsBarDelete({
infra,
setRunningDelete,
}: InfraSelectorEditionActionsBarDeleteProps) {
const { t } = useTranslation('infraManagement');
const dispatch = useDispatch();

const [deleteInfra] = osrdEditoastApi.useDeleteInfraByIdMutation();

async function deleteInfra() {
async function handleDeleteInfra() {
try {
await deleteRequest(`${INFRA_URL}${infra.id}/`);
await deleteInfra({ id: infra.id });
setRunningDelete(undefined);
getInfrasList();
dispatch(
setSuccess({
title: t('infraDeleted', { name: infra.name }),
text: '',
})
);
} catch (e) {
/* empty */
if (e instanceof Error) {
dispatch(
setFailure({
name: e.name,
message: e.message,
})
);
}
}
}

const countDownDelete = ({ seconds, completed }) => {
const countDownDelete = ({ seconds, completed }: { seconds: number; completed: boolean }) => {
if (completed) {
return (
<button
type="button"
className="infraslist-item-edition-delete-buttons yes"
onClick={deleteInfra}
onClick={handleDeleteInfra}
>
{t('yes')}
</button>
Expand Down Expand Up @@ -59,9 +81,3 @@ export default function InfraSelectorEditionActionsBarDelete(props) {
</div>
);
}

InfraSelectorEditionActionsBarDelete.propTypes = {
getInfrasList: PropTypes.func.isRequired,
infra: PropTypes.object.isRequired,
setRunningDelete: PropTypes.func.isRequired,
};
Original file line number Diff line number Diff line change
@@ -1,16 +1,26 @@
import React, { useState } from 'react';
import PropTypes from 'prop-types';
import nextId from 'react-id-generator';
import { FaLock, FaTrash } from 'react-icons/fa';
import InputSNCF from 'common/BootstrapSNCF/InputSNCF';
import { useTranslation } from 'react-i18next';
import { editoastUpToDateIndicator } from './InfraSelectorModalBodyStandard';
import { Infra } from 'common/api/osrdEditoastApi';
import ActionsBar from './InfraSelectorEditionActionsBar';
import { editoastUpToDateIndicator } from './InfraSelectorModalBodyStandard';
import InfraSelectorEditionActionsBarDelete from './InfraSelectorEditionActionsBarDelete';

export default function InfraSelectorEditionItem(props) {
const { infra, isFocused, setIsFocused, runningDelete, setRunningDelete, getInfrasList } = props;
type InfraSelectorEditionItemProps = {
infra: Infra;
isFocused?: number;
setIsFocused: (infraId?: number) => void;
};

export default function InfraSelectorEditionItem({
infra,
isFocused,
setIsFocused,
}: InfraSelectorEditionItemProps) {
const [value, setValue] = useState(infra.name);
const [runningDelete, setRunningDelete] = useState<number | undefined>(undefined);
const { t } = useTranslation('infraManagement');

const handleRunningDelete = () => {
Expand All @@ -24,11 +34,7 @@ export default function InfraSelectorEditionItem(props) {
<div className="infralist-item-edition-disabled" />
) : null}
{runningDelete === infra.id ? (
<InfraSelectorEditionActionsBarDelete
setRunningDelete={setRunningDelete}
infra={infra}
getInfrasList={getInfrasList}
/>
<InfraSelectorEditionActionsBarDelete setRunningDelete={setRunningDelete} infra={infra} />
) : null}
{isFocused === infra.id ? null : (
<button
Expand Down Expand Up @@ -81,24 +87,9 @@ export default function InfraSelectorEditionItem(props) {
infra={infra}
isFocused={isFocused}
setIsFocused={setIsFocused}
getInfrasList={getInfrasList}
inputValue={value}
/>
</div>
</div>
);
}

InfraSelectorEditionItem.defaultProps = {
isFocused: undefined,
runningDelete: undefined,
};

InfraSelectorEditionItem.propTypes = {
infra: PropTypes.object.isRequired,
isFocused: PropTypes.number,
setIsFocused: PropTypes.func.isRequired,
runningDelete: PropTypes.number,
setRunningDelete: PropTypes.func.isRequired,
getInfrasList: PropTypes.func.isRequired,
};
Loading