Skip to content

Commit 296ebcd

Browse files
committed
refactor: Refine license saga types, improve internal link rendering, and standardize null/undefined checks in FeedSummary.
1 parent 9f9b7ed commit 296ebcd

File tree

3 files changed

+66
-74
lines changed

3 files changed

+66
-74
lines changed

web-app/src/app/screens/Feed/components/CopyLinkElement.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ export default function CopyLinkElement({
5555
<FeedLinkElement>
5656
{title != null && (
5757
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
58-
{linkType === 'internal' ? (
58+
{linkType === 'internal' && internalClickAction != undefined ? (
5959
<Button
6060
variant='text'
6161
sx={{ pl: 0, py: 0.5 }}

web-app/src/app/screens/Feed/components/FeedSummary.tsx

Lines changed: 61 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -108,13 +108,6 @@ export default function FeedSummary({
108108
return hasOtherLinks;
109109
};
110110

111-
const hasLicenseData = (): boolean => {
112-
return (
113-
feed?.source_info?.license_url != undefined &&
114-
feed?.source_info?.license_url !== ''
115-
);
116-
};
117-
118111
return (
119112
<>
120113
<GroupCard variant='outlined'>
@@ -275,7 +268,7 @@ export default function FeedSummary({
275268
)}
276269
</Box>
277270

278-
{totalRoutes !== undefined && routeTypes !== undefined && (
271+
{totalRoutes != undefined && routeTypes != undefined && (
279272
<>
280273
<Typography
281274
variant='subtitle2'
@@ -335,15 +328,15 @@ export default function FeedSummary({
335328
</>
336329
)}
337330
</Box>
338-
{feed?.source_info?.producer_url !== undefined &&
331+
{feed?.source_info?.producer_url != undefined &&
339332
feed?.source_info?.producer_url !== '' && (
340333
<>
341334
<Box sx={{ ml: 2 }}>
342335
<Typography
343336
variant='subtitle2'
344337
sx={{ fontWeight: 700, color: 'text.secondary' }}
345338
>
346-
{feed?.data_type === 'gbfs' && autoDiscoveryUrl !== undefined
339+
{feed?.data_type === 'gbfs' && autoDiscoveryUrl != undefined
347340
? t('feedSummary.autoDiscoveryUrl')
348341
: t('feedSummary.producerUrl')}
349342
</Typography>
@@ -380,7 +373,7 @@ export default function FeedSummary({
380373
<IconButton
381374
component={Link}
382375
href={
383-
feed.data_type === 'gbfs'
376+
feed.data_type === 'gbfs' && autoDiscoveryUrl != undefined
384377
? autoDiscoveryUrl
385378
: feed.source_info.producer_url
386379
}
@@ -436,7 +429,7 @@ export default function FeedSummary({
436429
</Typography>
437430
</Box>
438431
)}
439-
{feed?.feed_contact_email !== undefined &&
432+
{feed?.feed_contact_email != undefined &&
440433
feed?.feed_contact_email !== '' && (
441434
<Box sx={{ ml: 2, mt: 3 }}>
442435
<Typography
@@ -460,7 +453,7 @@ export default function FeedSummary({
460453
)}
461454
</GroupCard>
462455

463-
{feed?.source_info?.authentication_info_url !== undefined &&
456+
{feed?.source_info?.authentication_info_url != undefined &&
464457
feed.source_info.authentication_type !== 0 &&
465458
feed?.source_info.authentication_info_url.trim() !== '' && (
466459
<GroupCard variant='outlined'>
@@ -475,7 +468,7 @@ export default function FeedSummary({
475468
{feed?.source_info?.authentication_type === 2 &&
476469
t('common:httpHeader')}
477470
</Typography>
478-
{feed?.source_info?.authentication_info_url !== undefined && (
471+
{feed?.source_info?.authentication_info_url != undefined && (
479472
<Button
480473
disableElevation
481474
variant='text'
@@ -493,8 +486,8 @@ export default function FeedSummary({
493486
</GroupCard>
494487
)}
495488

496-
{latestDataset?.service_date_range_start !== undefined &&
497-
latestDataset.service_date_range_end !== undefined && (
489+
{latestDataset?.service_date_range_start != undefined &&
490+
latestDataset.service_date_range_end != undefined && (
498491
<GroupCard variant='outlined'>
499492
<GroupHeader variant='body1'>
500493
<CalendarTodayIcon fontSize='inherit' />
@@ -558,7 +551,7 @@ export default function FeedSummary({
558551
}}
559552
>
560553
{/* TODO: nice to have, a placement of the chip relative to the current date */}
561-
{(feed as GTFSFeedType)?.status !== undefined &&
554+
{(feed as GTFSFeedType)?.status != undefined &&
562555
(feed as GTFSFeedType)?.status === 'active' && (
563556
<Box
564557
sx={{
@@ -676,57 +669,58 @@ export default function FeedSummary({
676669
</GroupCard>
677670
)}
678671

679-
{hasLicenseData() && (
680-
<GroupCard variant='outlined'>
681-
<Box
682-
sx={{
683-
display: 'flex',
684-
alignItems: 'center',
685-
justifyContent: 'space-between',
686-
mb: 1,
687-
}}
688-
>
689-
<GroupHeader variant='body1' sx={{ mb: 0 }}>
690-
<GavelIcon fontSize='inherit' />
691-
{t('common:license')}
692-
</GroupHeader>
693-
{feed?.source_info?.license_is_spdx !== undefined &&
694-
feed.source_info.license_is_spdx && (
695-
<Tooltip title={t('license.spdxTooltip')} placement='top'>
696-
<Chip
697-
label='SPDX'
698-
size='small'
699-
color='info'
700-
variant='outlined'
701-
/>
702-
</Tooltip>
703-
)}
704-
</Box>
705-
706-
{feed?.source_info?.license_id != undefined &&
707-
feed.source_info.license_id !== '' ? (
708-
<CopyLinkElement
709-
title={feed.source_info.license_id}
710-
url={feed.source_info.license_url ?? ''}
711-
titleInfo={t('license.licenseTooltip')}
712-
linkType='internal'
713-
internalClickAction={() => {
714-
setOpenLicenseDetails(true);
672+
{feed?.source_info?.license_url != undefined &&
673+
feed?.source_info?.license_url !== '' && (
674+
<GroupCard variant='outlined'>
675+
<Box
676+
sx={{
677+
display: 'flex',
678+
alignItems: 'center',
679+
justifyContent: 'space-between',
680+
mb: 1,
715681
}}
716-
/>
717-
) : (
718-
<Link
719-
href={feed?.source_info?.license_url ?? ''}
720-
target='_blank'
721-
rel='noopener noreferrer'
722-
sx={{ wordBreak: 'break-word' }}
723-
variant='body1'
724682
>
725-
{feed?.source_info?.license_url}
726-
</Link>
727-
)}
728-
</GroupCard>
729-
)}
683+
<GroupHeader variant='body1' sx={{ mb: 0 }}>
684+
<GavelIcon fontSize='inherit' />
685+
{t('common:license')}
686+
</GroupHeader>
687+
{feed?.source_info?.license_is_spdx != undefined &&
688+
feed.source_info.license_is_spdx && (
689+
<Tooltip title={t('license.spdxTooltip')} placement='top'>
690+
<Chip
691+
label='SPDX'
692+
size='small'
693+
color='info'
694+
variant='outlined'
695+
/>
696+
</Tooltip>
697+
)}
698+
</Box>
699+
700+
{feed?.source_info?.license_id != undefined &&
701+
feed.source_info.license_id !== '' ? (
702+
<CopyLinkElement
703+
title={feed.source_info.license_id}
704+
url={feed.source_info.license_url}
705+
titleInfo={t('license.licenseTooltip')}
706+
linkType='internal'
707+
internalClickAction={() => {
708+
setOpenLicenseDetails(true);
709+
}}
710+
/>
711+
) : (
712+
<Link
713+
href={feed?.source_info?.license_url ?? ''}
714+
target='_blank'
715+
rel='noopener noreferrer'
716+
sx={{ wordBreak: 'break-word' }}
717+
variant='body1'
718+
>
719+
{feed?.source_info?.license_url}
720+
</Link>
721+
)}
722+
</GroupCard>
723+
)}
730724

731725
{hasRelatedLinks() && (
732726
<GroupCard variant='outlined'>
@@ -754,7 +748,7 @@ export default function FeedSummary({
754748
onClose={() => {
755749
setOpenLocationDetails(undefined);
756750
}}
757-
open={openLocationDetails !== undefined}
751+
open={openLocationDetails != undefined}
758752
>
759753
<DialogTitle>Feed Locations</DialogTitle>
760754
<IconButton

web-app/src/app/store/saga/license-saga.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,17 +22,15 @@ import { selectLicenseData } from '../license-selectors';
2222

2323
export function* getLicenseSaga({
2424
payload: { licenseId },
25-
}: PayloadAction<{ licenseId: string }>): Generator<
26-
StrictEffect,
27-
void,
28-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
29-
any
30-
> {
25+
}: PayloadAction<{ licenseId: string }>): Generator<StrictEffect, void> {
3126
try {
3227
const licensesData = (yield select(selectLicenseData)) as Record<
3328
string,
3429
{ license: License; fetchedAt: number }
3530
>;
31+
// License data rarely changes, but we use a 1-hour cache duration to ensure
32+
// that any updates (e.g., legal changes, corrections) are picked up within a reasonable time.
33+
// This balances minimizing network requests with keeping data reasonably fresh.
3634
const cachedLicense = licensesData[licenseId];
3735
const now = Date.now();
3836
const oneHour = 60 * 60 * 1000;

0 commit comments

Comments
 (0)