Skip to content

Commit

Permalink
front: display trip duration and trip total distance on tab navigatio…
Browse files Browse the repository at this point in the history
…n of simulation

Signed-off-by: nncluzu <[email protected]>
  • Loading branch information
kmer2016 committed Nov 22, 2024
1 parent 83706cb commit 9579941
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 41 deletions.
6 changes: 6 additions & 0 deletions front/public/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,12 @@
"title": "Failed to save modifications",
"text": "Failed to publish your modifications"
}
},
"units": {
"day": "d",
"hour": "h",
"km": "km",
"minute": "min"
}
},
"Editor": {
Expand Down
6 changes: 6 additions & 0 deletions front/public/locales/fr/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,12 @@
"title": "Echec de l'enregistrement des modifications",
"text": "Vos modifications n'ont pas été publiées"
}
},
"units": {
"day": "j",
"hour": "h",
"km": "km",
"minute": "min"
}
},
"Editor": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ import { useTranslation } from 'react-i18next';

import useHorizontalScroll from 'applications/stdcm/hooks/useHorizontalScroll';
import type { StdcmSimulation } from 'applications/stdcm/types';
import { hasConflicts } from 'applications/stdcm/utils/simulationOutputUtils';
import { formatDateToString } from 'utils/date';
import { hasConflicts, hasResults } from 'applications/stdcm/utils/simulationOutputUtils';
import { formatDateToString, formatTimeDifference } from 'utils/date';
import { mmToKm } from 'utils/physics';

export const SIMULATION_ITEM_CLASSNAME = 'simulation-item';
const ITEM_TO_SHOW_COUNT_ON_SCROLL = 3;
Expand All @@ -27,7 +28,7 @@ const StdcmSimulationNavigator = ({
isCalculationFailed,
onSelectSimulation,
}: StdcmSimulationNavigatorProps) => {
const { t } = useTranslation('stdcm', { keyPrefix: 'simulation.results' });
const { t } = useTranslation();

const { scrollableRef, showLeftBtn, showRightBtn, scrollLeft, scrollRight } = useHorizontalScroll(
SIMULATION_ITEM_CLASSNAME,
Expand All @@ -53,40 +54,64 @@ const StdcmSimulationNavigator = ({
</div>
)}
<div className="simulation-list" ref={scrollableRef}>
{simulationsList?.map(({ id, creationDate, outputs }, index) => (
<div
role="button"
tabIndex={0}
key={index}
className={cx(SIMULATION_ITEM_CLASSNAME, {
retained: retainedSimulationIndex === index,
selected: selectedSimulationIndex === index,
anyRetained: retainedSimulationIndex !== -1,
})}
onClick={() => onSelectSimulation(index)}
>
<div className="simulation-name">
<div>
{outputs && !hasConflicts(outputs)
? t('simulationName.withOutputs', { id })
: t('simulationName.withoutOutputs')}
{simulationsList?.map(({ id, creationDate, outputs }, index) => {
let formatedTotalLength = '';
let formatedTripDuration = '';

if (hasResults(outputs)) {
const { results } = outputs;
const lastPointTime = results.simulation.final_output.times.at(-1)!;
const departureTimeInMs = new Date(results.departure_time).getTime();

formatedTotalLength = `${Math.round(mmToKm(results.path.length))} ${t('common.units.km', { ns: 'translation' })} `;
formatedTripDuration = formatTimeDifference(
departureTimeInMs,
lastPointTime + departureTimeInMs
);
}

return (
<div
role="button"
tabIndex={0}
key={index}
className={cx(SIMULATION_ITEM_CLASSNAME, {
retained: retainedSimulationIndex === index,
selected: selectedSimulationIndex === index,
anyRetained: retainedSimulationIndex !== -1,
})}
onClick={() => onSelectSimulation(index)}
>
<div className="simulation-name">
<span>
{outputs && !hasConflicts(outputs)
? t('simulation.results.simulationName.withOutputs', {
id,
ns: 'stdcm',
})
: t('simulation.results.simulationName.withoutOutputs', {
ns: 'stdcm',
})}
</span>
{retainedSimulationIndex === index && (
<CheckCircle className="check-circle" variant="fill" />
)}
</div>
{retainedSimulationIndex === index && (
<span className="check-circle">
<CheckCircle variant="fill" />
<div className="simulation-metadata" key={id}>
<span className="creation-date">
{t('simulation.results.formatCreationDate', {
...formatDateToString(creationDate, true),
ns: 'stdcm',
})}
</span>
<span className="total-length-trip-duration">{`${formatedTotalLength}${formatedTripDuration}`}</span>
</div>
{selectedSimulationIndex === index && (
<div className="selected-simulation-indicator" />
)}
</div>
<div className="creation-date">
<span key={index}>
{t('formatCreationDate', formatDateToString(creationDate, true))}
</span>
</div>
{selectedSimulationIndex === index && (
<div className="selected-simulation-indicator" />
)}
</div>
))}
);
})}
</div>
{showRightBtn && (
<div
Expand Down
1 change: 1 addition & 0 deletions front/src/styles/scss/_variables.scss
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ $colors: (
'primary90': #180f47,
'selection20': #fff2b3,
'success30': #3cca80,
'success60': #0b723c,
'warning5': #fdf5e1,
'warning30': #eaa72b,
'warning60': #7d521e,
Expand Down
29 changes: 21 additions & 8 deletions front/src/styles/scss/applications/stdcm/_results.scss
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,12 @@
overflow-x: hidden;

.simulation-item {
width: 125px;
width: 160px;
display: inline-block;
margin: 9px 64px 0 0;
margin-right: 32px;
cursor: pointer;

.creation-date {
.simulation-metadata {
color: rgba(182, 178, 175, 1);
font-weight: 400;
font-size: 14px;
Expand All @@ -65,6 +65,16 @@
text-align: left;
padding-top: 4px;
padding-bottom: 11px;
display: flex;
flex-direction: column;

.creation-date {
margin-bottom: 4px;
}

.total-length-trip-duration {
margin-right: 10px;
}
}

.simulation-name {
Expand All @@ -75,14 +85,16 @@
white-space: nowrap;

.check-circle {
display: flex;
align-items: center;
margin-left: 8px;
color: rgb(60, 202, 128);
padding-left: 8px;
}
}

&.selected {
.creation-date {
color: rgb(121, 118, 113);
.simulation-metadata {
color: var(--grey50);
}

.simulation-name {
Expand All @@ -97,8 +109,9 @@
}

&.retained {
.simulation-name {
color: rgb(11, 114, 60);
.simulation-name,
.simulation-metadata {
color: var(--success60);
}
}

Expand Down
22 changes: 22 additions & 0 deletions front/src/utils/date.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import 'dayjs/locale/fr';
import customParseFormat from 'dayjs/plugin/customParseFormat';
import timezone from 'dayjs/plugin/timezone';
import utc from 'dayjs/plugin/utc';
import i18next from 'i18next';

import type { ScheduleConstraint } from 'applications/stdcm/types';
import type { IsoDateTimeString, IsoDurationString } from 'common/types';
Expand Down Expand Up @@ -254,3 +255,24 @@ export const formatLocaleDate = (date: Date) => date.toLocaleString().substring(

export const isEqualDate = (searchDate: Date, startDate: Date) =>
formatLocaleDate(searchDate) === formatLocaleDate(startDate);

/**
* @param start timestamp or Date object
* @param end timestamp or Date object
* @returns string "Xj Yh Zmin"
*/
export const formatTimeDifference = (_start: number | Date, _end: number | Date): string => {
const start = dayjs(_start);
const end = dayjs(_end);

const diffInDays = end.diff(start, 'day');
const diffInHours = end.diff(start, 'hour') % 24;
const diffInMinutes = end.diff(start, 'minute') % 60;

const parts = [];
if (diffInDays > 0) parts.push(`${diffInDays}${i18next.t('common.units.day')}`);
if (diffInHours > 0) parts.push(`${diffInHours}${i18next.t('common.units.hour')}`);
if (diffInMinutes > 0) parts.push(`${diffInMinutes}${i18next.t('common.units.minute')}`);

return parts.join(' ');
};

0 comments on commit 9579941

Please sign in to comment.