|
1 |
| -import { useMemo } from 'react'; |
2 |
| - |
3 |
| -import cx from 'classnames'; |
4 |
| -import { keyColumn, type Column, checkboxColumn, createTextColumn } from 'react-datasheet-grid'; |
5 |
| -import type { CellComponent } from 'react-datasheet-grid/dist/types'; |
6 |
| -import { useTranslation } from 'react-i18next'; |
7 |
| - |
8 |
| -import { marginRegExValidation } from '../consts'; |
9 |
| -import { disabledTextColumn } from '../helpers/utils'; |
10 |
| -import ReadOnlyTime from '../ReadOnlyTime'; |
11 |
| -import TimeInput from '../TimeInput'; |
12 |
| -import { TableType, type TimeExtraDays, type TimeStopsRow } from '../types'; |
13 |
| - |
14 |
| -const timeColumn = (isOutputTable: boolean) => |
15 |
| - ({ |
16 |
| - component: (isOutputTable ? ReadOnlyTime : TimeInput) as CellComponent< |
17 |
| - TimeExtraDays | undefined, |
18 |
| - string |
19 |
| - >, |
20 |
| - deleteValue: () => undefined, |
21 |
| - copyValue: ({ rowData }) => rowData?.time ?? null, |
22 |
| - pasteValue: ({ value }) => ({ time: value }), |
23 |
| - minWidth: isOutputTable ? 110 : 170, |
24 |
| - isCellEmpty: ({ rowData }) => !rowData, |
25 |
| - }) as Partial<Column<TimeExtraDays | undefined, string, string>>; |
26 |
| - |
27 |
| -const fixedWidth = (width: number) => ({ minWidth: width, maxWidth: width }); |
28 |
| - |
29 |
| -export const useTimeStopsColumns = <T extends TimeStopsRow>( |
30 |
| - tableType: TableType, |
31 |
| - allWaypoints: T[] = [] |
32 |
| -) => { |
33 |
| - const { t } = useTranslation('timesStops'); |
34 |
| - |
35 |
| - const columns = useMemo<Column<T>[]>(() => { |
36 |
| - const isOutputTable = tableType === TableType.Output; |
37 |
| - const extraOutputColumns = ( |
38 |
| - isOutputTable |
39 |
| - ? [ |
40 |
| - { |
41 |
| - ...disabledTextColumn('theoreticalMarginSeconds', t('theoreticalMarginSeconds'), { |
42 |
| - alignRight: true, |
43 |
| - }), |
44 |
| - ...fixedWidth(110), |
45 |
| - }, |
46 |
| - { |
47 |
| - ...disabledTextColumn('calculatedMargin', t('realMargin'), { |
48 |
| - alignRight: true, |
49 |
| - }), |
50 |
| - ...fixedWidth(120), |
51 |
| - }, |
52 |
| - { |
53 |
| - ...disabledTextColumn('diffMargins', t('diffMargins'), { alignRight: true }), |
54 |
| - ...fixedWidth(120), |
55 |
| - }, |
56 |
| - { |
57 |
| - ...disabledTextColumn('calculatedArrival', t('calculatedArrivalTime')), |
58 |
| - ...fixedWidth(95), |
59 |
| - }, |
60 |
| - { |
61 |
| - ...disabledTextColumn('calculatedDeparture', t('calculatedDepartureTime')), |
62 |
| - ...fixedWidth(97), |
63 |
| - }, |
64 |
| - ] |
65 |
| - : [] |
66 |
| - ) as Column<T>[]; |
67 |
| - |
68 |
| - return [ |
69 |
| - { |
70 |
| - ...keyColumn('name', createTextColumn()), |
71 |
| - title: t('name'), |
72 |
| - disabled: true, |
73 |
| - minWidth: isOutputTable ? 180 : 300, |
74 |
| - }, |
75 |
| - { |
76 |
| - ...keyColumn('ch', createTextColumn()), |
77 |
| - title: t('ch'), |
78 |
| - disabled: true, |
79 |
| - maxWidth: 45, |
80 |
| - }, |
81 |
| - { |
82 |
| - ...keyColumn('arrival', timeColumn(isOutputTable)), |
83 |
| - alignRight: true, |
84 |
| - title: t('arrivalTime'), |
85 |
| - |
86 |
| - // We should not be able to edit the arrival time of the origin |
87 |
| - disabled: ({ rowIndex }) => isOutputTable || rowIndex === 0, |
88 |
| - }, |
89 |
| - { |
90 |
| - ...keyColumn('departure', timeColumn(isOutputTable)), |
91 |
| - title: t('departureTime'), |
92 |
| - |
93 |
| - // We should not be able to edit the departure time of the origin |
94 |
| - disabled: ({ rowIndex }) => isOutputTable || rowIndex === 0, |
95 |
| - }, |
96 |
| - { |
97 |
| - ...keyColumn( |
98 |
| - 'stopFor', |
99 |
| - createTextColumn({ |
100 |
| - continuousUpdates: false, |
101 |
| - alignRight: true, |
102 |
| - }) |
103 |
| - ), |
104 |
| - title: t('stopTime'), |
105 |
| - disabled: isOutputTable, |
106 |
| - maxWidth: isOutputTable ? 90 : undefined, |
107 |
| - grow: 0.6, |
108 |
| - }, |
109 |
| - { |
110 |
| - ...keyColumn('onStopSignal', checkboxColumn as Partial<Column<boolean | undefined>>), |
111 |
| - title: t('receptionOnClosedSignal'), |
112 |
| - |
113 |
| - // We should not be able to edit the reception on close signal if stopFor is not filled |
114 |
| - // except for the destination |
115 |
| - ...fixedWidth(94), |
116 |
| - disabled: ({ rowData, rowIndex }) => |
117 |
| - isOutputTable || (rowIndex !== allWaypoints.length - 1 && !rowData.stopFor), |
118 |
| - }, |
119 |
| - { |
120 |
| - ...keyColumn('shortSlipDistance', checkboxColumn as Partial<Column<boolean | undefined>>), |
121 |
| - title: t('shortSlipDistance'), |
122 |
| - ...fixedWidth(94), |
123 |
| - disabled: ({ rowData, rowIndex }) => |
124 |
| - isOutputTable || (rowIndex !== allWaypoints.length - 1 && !rowData.onStopSignal), |
125 |
| - }, |
126 |
| - { |
127 |
| - ...keyColumn( |
128 |
| - 'theoreticalMargin', |
129 |
| - createTextColumn({ |
130 |
| - continuousUpdates: false, |
131 |
| - alignRight: true, |
132 |
| - placeholder: !isOutputTable ? t('theoreticalMarginPlaceholder') : '', |
133 |
| - formatBlurredInput: (value) => { |
134 |
| - if (!value || value === '0%') return ''; |
135 |
| - if (!isOutputTable && !marginRegExValidation.test(value)) { |
136 |
| - return `${value}${t('theoreticalMarginPlaceholder')}`; |
137 |
| - } |
138 |
| - return value; |
139 |
| - }, |
140 |
| - }) |
141 |
| - ), |
142 |
| - cellClassName: ({ rowData }) => |
143 |
| - cx({ invalidCell: !isOutputTable && !rowData.isMarginValid }), |
144 |
| - title: t('theoreticalMargin'), |
145 |
| - disabled: ({ rowIndex }) => isOutputTable || rowIndex === allWaypoints.length - 1, |
146 |
| - ...fixedWidth(110), |
147 |
| - }, |
148 |
| - ...extraOutputColumns, |
149 |
| - ] as Column<T>[]; |
150 |
| - }, [tableType, t, allWaypoints.length]); |
151 |
| - |
152 |
| - return columns; |
153 |
| -}; |
154 |
| - |
155 |
| -export default timeColumn; |
0 commit comments