Skip to content

Commit

Permalink
front: clean code for the search filters in timetable
Browse files Browse the repository at this point in the history
  • Loading branch information
RomainValls committed Feb 13, 2024
1 parent c352717 commit 09edfdd
Showing 1 changed file with 79 additions and 127 deletions.
206 changes: 79 additions & 127 deletions front/src/modules/trainschedule/components/Timetable/Timetable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,6 @@ type TimetableProps = {
simulation: SimulationSnapshot;
};

type RollingStocksDictionary = {
[key: string]: number[];
};

export default function Timetable({
setDisplayTrainScheduleManagement,
trainsWithDetails,
Expand All @@ -75,13 +71,11 @@ export default function Timetable({
const [multiselectOn, setMultiselectOn] = useState(false);
const [conflictsListExpanded, setConflictsListExpanded] = useState(false);
const [selectedTrainIds, setSelectedTrainIds] = useState<number[]>([]);
const [rollingStockIds, setRollingStockIds] = useState<number[]>([]);
const [rollingStocksDictionary, setRollingStocksDictionary] = useState<RollingStocksDictionary>(
{}
);
const [rollingStockFilter, setRollingStockFilter] = useState('');
const [validityFilter, setValidityFilter] = useState('both');
const [isFilterPanelOpen, setIsFilterPanelOpen] = useState(false);
const [uniqueTags, setUniqueTags] = useState<string[]>([]);
const [selectedTags, setSelectedTags] = useState(new Set());

const { openModal } = useContext(ModalContext);

Expand All @@ -104,42 +98,11 @@ export default function Timetable({
[timetable]
);

// We fetch all RS to get the data we need for the advanced filters
const { data: { results: rollingStocks } = { results: [] } } =
enhancedEditoastApi.useGetLightRollingStockQuery({ pageSize: 1000 });

useEffect(() => {
const rollingStockIdsSet = new Set(rollingStockIds);
const newRollingStocksDictionary: RollingStocksDictionary = {};

rollingStocks.forEach((rollingStock) => {
if (rollingStockIdsSet.has(rollingStock.id)) {
const { metadata } = rollingStock;
if (metadata) {
if (metadata.detail) {
if (!newRollingStocksDictionary[metadata.detail]) {
newRollingStocksDictionary[metadata.detail] = [];
}
newRollingStocksDictionary[metadata.detail].push(rollingStock.id);
}
if (metadata.series) {
if (!newRollingStocksDictionary[metadata.series]) {
newRollingStocksDictionary[metadata.series] = [];
}
newRollingStocksDictionary[metadata.series].push(rollingStock.id);
}
if (metadata.family) {
if (!newRollingStocksDictionary[metadata.family]) {
newRollingStocksDictionary[metadata.family] = [];
}
newRollingStocksDictionary[metadata.family].push(rollingStock.id);
}
}
}
});

setRollingStocksDictionary(newRollingStocksDictionary);
}, [rollingStocks, rollingStockIds]);

// Filter RS by their names and labels
const keepTrain = (train: ScheduledTrain, searchString: string): boolean => {
if (searchString) {
const searchStringInName = train.train_name
Expand All @@ -154,33 +117,82 @@ export default function Timetable({
return true;
};

const trainsList = useMemo(() => {
if (timetable) {
return timetable.train_schedule_summaries
.filter((train) => keepTrain(train, debouncedFilter))
.map((train) => ({
...train,
duration: durationInSeconds(train.departure_time, train.arrival_time),
}));
const specialCodeDictionary: { [key: string]: string } = {
'Divers - Haut le pied': 'HLP',
'': 'NO CODE',
};

const extractTagCode = (tag: string | null) => {
if (!tag) {
return 'NO CODE';
}
if (tag in specialCodeDictionary) {
return specialCodeDictionary[tag];
}
return [];
}, [timetable, trainsDurationsIntervals, debouncedFilter]);

useEffect(() => {
const extractedRollingStockIds = trainsList.map((train) => train.rolling_stock_id);
setRollingStockIds(extractedRollingStockIds);
}, [trainsList]);
const regex = /\s*(\w+)\s*$/;
const matches = tag.match(regex);
if (matches && matches[1]) {
return matches[1];
}

const trainsWithRollingStockDetail = useMemo(
() =>
trainsList.map((train) => {
return tag;
};

const trainsList = useMemo(() => {
if (!timetable) return [];

return timetable.train_schedule_summaries
.filter((train) => {
if (!keepTrain(train, debouncedFilter)) return false;

// Apply validity filter
if (validityFilter === 'valid' && train.invalid_reasons?.length > 0) return false;
if (
validityFilter === 'invalid' &&
(!train.invalid_reasons || train.invalid_reasons.length === 0)
)
return false;

// Apply tag filter
if (selectedTags.size > 0 && !selectedTags.has(extractTagCode(train.speed_limit_tags)))
return false;

// Apply rolling stock filter
const rollingStock = rollingStocks.find((rs) => rs.id === train.rolling_stock_id);
const rollingStockMetadata = rollingStock?.metadata;
const rollingStockName = rollingStock?.name;
return { ...train, rollingStockMetadata, rollingStockName };
}),
[trainsList, rollingStocks]
);
const rollingStockDetail = rollingStock?.metadata?.detail || '';
const rollingStockSeries = rollingStock?.metadata?.series || '';
const rollingStockFamily = rollingStock?.metadata?.family || '';
const rollingStockName = rollingStock?.name || '';
if (
!(
rollingStockDetail.toLowerCase().includes(debouncedRollingstockFilter.toLowerCase()) ||
rollingStockSeries.toLowerCase().includes(debouncedRollingstockFilter.toLowerCase()) ||
rollingStockName.toLowerCase().includes(debouncedRollingstockFilter.toLowerCase()) ||
rollingStockFamily.toLowerCase().includes(debouncedRollingstockFilter.toLowerCase())
)
)
return false;

return true;
})
.map((train) => {
const rollingStock = rollingStocks.find((rs) => rs.id === train.rolling_stock_id);
return {
...train,
rollingStockMetadata: rollingStock?.metadata,
rollingStockName: rollingStock?.name,
duration: durationInSeconds(train.departure_time, train.arrival_time),
};
});
}, [
timetable,
rollingStocks,
debouncedFilter,
validityFilter,
selectedTags,
debouncedRollingstockFilter,
]);

const toggleConflictsListExpanded = () => {
setConflictsListExpanded(!conflictsListExpanded);
Expand Down Expand Up @@ -297,31 +309,6 @@ export default function Timetable({
dispatch(updateTrainScheduleIDsToModify([]));
}, []);

const specialCodeDictionary: { [key: string]: string } = {
'Divers - Haut le pied': 'HLP',
'': 'NO CODE',
};

const extractTagCode = (tag: string | null) => {
if (!tag) {
return 'NO CODE';
}
if (tag in specialCodeDictionary) {
return specialCodeDictionary[tag];
}

const regex = /\s*(\w+)\s*$/;
const matches = tag.match(regex);
if (matches && matches[1]) {
return matches[1];
}

return tag;
};

const [uniqueTags, setUniqueTags] = useState<string[]>([]);
const [selectedTags, setSelectedTags] = useState(new Set());

const toggleTagSelection = (tag: string | null) => {
setSelectedTags((prevSelectedTags) => {
const newSelectedTags = new Set(prevSelectedTags);
Expand All @@ -334,43 +321,6 @@ export default function Timetable({
});
};

const filteredTrainsList = useMemo(
() =>
trainsWithRollingStockDetail
.filter((train) => keepTrain(train, debouncedFilter))
.filter((train) => {
if (validityFilter === 'valid') {
return !train.invalid_reasons || train.invalid_reasons.length === 0;
}
if (validityFilter === 'invalid') {
return train.invalid_reasons && train.invalid_reasons.length > 0;
}
return true;
})
.filter(
(train) =>
selectedTags.size === 0 || selectedTags.has(extractTagCode(train.speed_limit_tags))
)
.filter((train) => {
const rollingStockDetail = train.rollingStockMetadata?.detail || '';
const rollingStockSeries = train.rollingStockMetadata?.series || '';
const rollingStockName = train.rollingStockName || '';
return (
rollingStockDetail.toLowerCase().includes(debouncedRollingstockFilter.toLowerCase()) ||
rollingStockSeries.toLowerCase().includes(debouncedRollingstockFilter.toLowerCase()) ||
rollingStockName.toLowerCase().includes(debouncedRollingstockFilter.toLowerCase())
);
}),
[
trainsWithRollingStockDetail,
debouncedFilter,
selectedTags,
rollingStocksDictionary,
debouncedRollingstockFilter,
validityFilter,
]
);

useEffect(() => {
const compositionCodes = new Set<string>();
trainsList.forEach((train) => {
Expand Down Expand Up @@ -474,6 +424,7 @@ export default function Timetable({
unit={<i className="icons-search" />}
sm
data-testid="scenarios-filter"
title={t('filterPlaceholder')}
/>
<div className="my-3" />
<InputSNCF
Expand All @@ -488,6 +439,7 @@ export default function Timetable({
unit={<i className="icons-search" />}
sm
data-testid="rolling-stock-filter"
title={t('timetable.rollingStockFilterPlaceholder')}
/>
</div>

Expand Down Expand Up @@ -533,7 +485,7 @@ export default function Timetable({
})}
>
{trainsDurationsIntervals &&
filteredTrainsList
trainsList
.sort((trainA, trainB) => trainA.departure_time - trainB.departure_time)
.map((train: ScheduledTrain, idx: number) => (
<TimetableTrainCard
Expand Down

0 comments on commit 09edfdd

Please sign in to comment.