Skip to content

Commit

Permalink
front: update column styles in time stops table
Browse files Browse the repository at this point in the history
Signed-off-by: Alice Khoudli <[email protected]>
  • Loading branch information
Synar committed Oct 31, 2024
1 parent a95471f commit f1e7a3c
Show file tree
Hide file tree
Showing 11 changed files with 202 additions and 15 deletions.
4 changes: 2 additions & 2 deletions front/public/locales/en/timesStops.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@
"calculatedDepartureTimeFull": "calculated departure time",
"dayCounter": "D+{{count}}",
"departureTime": "requested depart. time",
"departureTimeFull": "requested depart. time",
"departureTimeFull": "requested departure time",
"diffMargins": "margins diff. (s)",
"diffMarginsFull": "margins difference (s)",
"name": "CI",
"ch": "ch",
"ch": "CH",
"noPathLoaded": "No path loaded",
"realMargin": "real margin (s)",
"receptionOnClosedSignal": "r. closed signal",
Expand Down
2 changes: 1 addition & 1 deletion front/public/locales/fr/timesStops.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"diffMargins": "diff. marges (s)",
"diffMarginsFull": "différence entre les marges (s)",
"name": "CI",
"ch": "ch",
"ch": "CH",
"noPathLoaded": "Aucun chemin chargé",
"realMargin": "marge réelle (s)",
"receptionOnClosedSignal": "r. s. signal fermé",
Expand Down
3 changes: 2 additions & 1 deletion front/src/modules/timesStops/TimesStopsOutput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ const TimesStopsOutput = ({
<TimesStops
rows={enrichedOperationalPoints}
tableType={TableType.Output}
cellClassName={({ rowData: rowData_ }) => {
cellClassName={({ rowData: rowData_, columnId }) => {
const rowData = rowData_ as TimeStopsRow;
const arrivalScheduleNotRespected = rowData.arrival?.time
? rowData.calculatedArrival !== rowData.arrival.time
Expand All @@ -57,6 +57,7 @@ const TimesStopsOutput = ({
return cx({
'warning-schedule': arrivalScheduleNotRespected,
'warning-margin': negativeDiffMargins,
'secondary-code-column': columnId === 'ch',
});
}}
headerRowHeight={40}
Expand Down
Empty file.
185 changes: 185 additions & 0 deletions front/src/modules/timesStops/hooks/useTimeStopsColumns.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
import { useMemo } from 'react';

import cx from 'classnames';
import { keyColumn, type Column, checkboxColumn, createTextColumn } from 'react-datasheet-grid';
import type { CellComponent } from 'react-datasheet-grid/dist/types';
import { useTranslation } from 'react-i18next';

import { marginRegExValidation } from '../consts';
import { disabledTextColumn } from '../helpers/utils';
import ReadOnlyTime from '../ReadOnlyTime';
import TimeInput from '../TimeInput';
import { TableType, type TimeExtraDays, type TimeStopsRow } from '../types';

const timeColumn = (isOutputTable: boolean) =>
({
component: (isOutputTable ? ReadOnlyTime : TimeInput) as CellComponent<
TimeExtraDays | undefined,
string
>,
deleteValue: () => undefined,
copyValue: ({ rowData }) => rowData?.time ?? null,
pasteValue: ({ value }) => ({ time: value }),
minWidth: isOutputTable ? 110 : 170,
isCellEmpty: ({ rowData }) => !rowData,
}) as Partial<Column<TimeExtraDays | undefined, string, string>>;

const fixedWidth = (width: number) => ({ minWidth: width, maxWidth: width });

function headerWithTitleTagIfShortened(shortenedHeader: string, fullHeader: string) {
if (shortenedHeader === fullHeader) return fullHeader;
return <span title={fullHeader}> {shortenedHeader} </span>;
}

export const useTimeStopsColumns = <T extends TimeStopsRow>(
tableType: TableType,
allWaypoints: T[] = []
) => {
const { t } = useTranslation('timesStops');

const columns = useMemo<Column<T>[]>(() => {
const isOutputTable = tableType === TableType.Output;
const extraOutputColumns = (
isOutputTable
? [
{
...disabledTextColumn('theoreticalMarginSeconds', t('theoreticalMarginSeconds'), {
alignRight: true,
}),
headerClassName: 'padded-header',
...fixedWidth(90),
},
{
...disabledTextColumn('calculatedMargin', t('realMargin'), { alignRight: true }),
headerClassName: 'padded-header',
...fixedWidth(90),
},
{
...disabledTextColumn('diffMargins', t('diffMargins'), { alignRight: true }),
title: headerWithTitleTagIfShortened(t('diffMargins'), t('diffMarginsFull')),
headerClassName: 'padded-header',
...fixedWidth(90),
},
{
...disabledTextColumn('calculatedArrival', t('calculatedArrivalTime')),
headerClassName: 'padded-header',
...fixedWidth(105),
},
{
...disabledTextColumn('calculatedDeparture', t('calculatedDepartureTime')),
title: headerWithTitleTagIfShortened(
t('calculatedDepartureTime'),
t('calculatedDepartureTimeFull')
),
headerClassName: 'padded-header',
...fixedWidth(105),
},
]
: []
) as Column<T>[];

return [
{
...keyColumn('name', createTextColumn()),
title: t('name'),
...(isOutputTable && {
component: ({ rowData }) => (
<span title={rowData.name} className="ml-1 text-nowrap overflow-hidden">
{rowData.name}
</span>
),
}),
disabled: true,
minWidth: isOutputTable ? undefined : 300,
},
{
...keyColumn('ch', createTextColumn()),
title: t('ch'),
disabled: true,
...fixedWidth(45),
},
{
...keyColumn('arrival', timeColumn(isOutputTable)),
title: t('arrivalTime'),
headerClassName: 'padded-header',
...fixedWidth(isOutputTable ? 105 : 125),

// We should not be able to edit the arrival time of the origin
disabled: ({ rowIndex }) => isOutputTable || rowIndex === 0,
},
{
...keyColumn(
'stopFor',
createTextColumn({
continuousUpdates: false,
alignRight: true,
})
),
title: t('stopTime'),
headerClassName: 'padded-header',
disabled: isOutputTable,
...fixedWidth(80),
},
{
...keyColumn('departure', timeColumn(isOutputTable)),
title: headerWithTitleTagIfShortened(t('departureTime'), t('departureTimeFull')),
headerClassName: 'padded-header',
...fixedWidth(isOutputTable ? 105 : 125),

// We should not be able to edit the departure time of the origin
disabled: ({ rowIndex }) => isOutputTable || rowIndex === 0,
},
{
...keyColumn('onStopSignal', checkboxColumn as Partial<Column<boolean | undefined>>),
title: headerWithTitleTagIfShortened(
t('receptionOnClosedSignal'),
t('receptionOnClosedSignalFull')
),
headerClassName: 'padded-header',
...fixedWidth(81),

// We should not be able to edit the reception on close signal if stopFor is not filled
// except for the destination
disabled: ({ rowData, rowIndex }) =>
isOutputTable || (rowIndex !== allWaypoints.length - 1 && !rowData.stopFor),
},
{
...keyColumn('shortSlipDistance', checkboxColumn as Partial<Column<boolean | undefined>>),
title: t('shortSlipDistance'),
headerClassName: 'padded-header',
...fixedWidth(81),
disabled: ({ rowData, rowIndex }) =>
isOutputTable || (rowIndex !== allWaypoints.length - 1 && !rowData.onStopSignal),
},
{
...keyColumn(
'theoreticalMargin',
createTextColumn({
continuousUpdates: false,
placeholder: !isOutputTable ? t('theoreticalMarginPlaceholder') : '',
formatBlurredInput: (value) => {
if (!value || value === '0%') return '';
if (!isOutputTable && !marginRegExValidation.test(value)) {
return `${value}${t('theoreticalMarginPlaceholder')}`;
}
return value;
},
alignRight: true,
})
),
cellClassName: ({ rowData }) =>
cx({ invalidCell: !isOutputTable && !rowData.isMarginValid }),
title: t('theoreticalMargin'),
headerClassName: 'padded-header',
minWidth: 100,
maxWidth: 130,
disabled: ({ rowIndex }) => isOutputTable || rowIndex === allWaypoints.length - 1,
},
...extraOutputColumns,
] as Column<T>[];
}, [tableType, t, allWaypoints.length]);

return columns;
};

export default timeColumn;
1 change: 0 additions & 1 deletion front/src/modules/timesStops/styles/_readOnlyTime.scss
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
.read-only-time {
// using px to conform with the padding in the react-datasheet-grid library class .dsg-input
padding: 0 10px;
text-align: right;
width: 100%;
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
.time-stops-datasheet {
padding-bottom: 16px;
border-radius: 10px;
max-width: 1407px;
box-shadow:
0px 1px 0px rgba(255, 255, 255, 1) inset,
0px 4px 7px -3px rgba(255, 171, 88, 0.17),
Expand Down
2 changes: 1 addition & 1 deletion front/tests/011-op-times-and-stops-tab.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,8 @@ test.describe('Times and Stops Tab Verification', () => {
translations.name,
translations.ch,
translations.arrivalTime,
translations.departureTime,
translations.stopTime,
translations.departureTime,
translations.receptionOnClosedSignal,
translations.shortSlipDistance,
translations.theoreticalMargin,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@
},
{
"row": 2,
"values": ["Mid_West_station", "BV", "11:47:40", "11:52:40", "300", "1min/100km"]
"values": ["Mid_West_station", "BV", "11:47:40", "300", "11:52:40", "1min/100km"]
},
{
"row": 3,
"values": ["Mid_East_station", "BV", "12:05:21", "12:07:25", "124", ""]
"values": ["Mid_East_station", "BV", "12:05:21", "124", "12:07:25", ""]
},
{
"row": 4,
"values": ["North_East_station", "BV", "", "", "0", ""]
"values": ["North_East_station", "BV", "", "0", "", ""]
}
]
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@
},
{
"row": 3,
"values": ["Mid_East_station", "BV", "13:58:19", "13:58:40", "21", ""]
"values": ["Mid_East_station", "BV", "13:58:19", "21", "13:58:40", ""]
},
{
"row": 4,
"values": ["North_East_station", "BV", "", "", "0", ""]
"values": ["North_East_station", "BV", "", "0", "", ""]
}
]
9 changes: 6 additions & 3 deletions front/tests/pages/op-output-table-page-model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class OperationalStudiesOutputTablePage {
constructor(page: Page) {
this.page = page;
this.columnHeaders = page.locator(
'[class="dsg-cell dsg-cell-header"] .dsg-cell-header-container'
'.dsg-cell.dsg-cell-header:not(.dsg-cell-gutter) .dsg-cell-header-container'
);
this.tableRows = page.locator('.time-stop-outputs .time-stops-datasheet .dsg-row');
}
Expand Down Expand Up @@ -69,9 +69,12 @@ class OperationalStudiesOutputTablePage {
calculatedDeparture,
] = await Promise.all([
await OperationalStudiesOutputTablePage.getCellValue(
cells.nth(headerIndexMap[translations.name])
cells.nth(headerIndexMap[translations.name]),
false
),
await OperationalStudiesOutputTablePage.getCellValue(
cells.nth(headerIndexMap[translations.ch])
),
await OperationalStudiesOutputTablePage.getCellValue(cells.nth(headerIndexMap.Ch)),
await OperationalStudiesOutputTablePage.getCellValue(
cells.nth(headerIndexMap[translations.arrivalTime]),
false
Expand Down

0 comments on commit f1e7a3c

Please sign in to comment.