Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
908d9d1
Add vertical transportation use steps to indoor routing.
VillePihlava Sep 26, 2025
5495430
Add indoor routing to other views.
VillePihlava Dec 10, 2025
536af69
Remove and reword TODO comments.
VillePihlava Dec 10, 2025
3e133d0
Add focusAction on onClick to indoor route step in navigator.
VillePihlava Dec 10, 2025
52df0a9
Change zIndex, add documentation, and change class names.
VillePihlava Dec 11, 2025
6c5ef31
Merge branch 'next' of github.com:HSLdevcom/digitransit-ui into impro…
VillePihlava Dec 11, 2025
247a190
Remove relativeDirection from indoor route related queries.
VillePihlava Dec 12, 2025
d1a5731
Merge branch 'improve-indoor-routing-level-info-v3' into improve-indo…
VillePihlava Dec 12, 2025
fb868b0
Fix styling for itinerary details when only one indoor step or no ind…
VillePihlava Dec 22, 2025
93f252a
Create NaviIndoorButtonContainer and NaviIndoorCard components.
VillePihlava Dec 22, 2025
e813c9b
Refactor names with indoorRoute to indoor.
VillePihlava Dec 22, 2025
8f73fa3
Refactor how itinerary circle lines are used.
VillePihlava Dec 22, 2025
ca6a707
Rename getIndoorStepsWithVerticalTransportationUse to getIndoorStepsW…
VillePihlava Dec 23, 2025
3171ef9
Move useEffect to useState initialization.
VillePihlava Dec 23, 2025
d01d55d
Refactoring related to indoorUtils.
VillePihlava Dec 23, 2025
94088cb
Don't copy object.
VillePihlava Dec 23, 2025
e8c9312
Merge branch 'improve-indoor-routing-level-info-v3' of github.com:HSL…
VillePihlava Dec 23, 2025
72e1f7f
Refactor functions to use getEntranceObject to ensure consistency.
VillePihlava Dec 23, 2025
3111d79
Merge branch 'improve-indoor-routing-level-info-v3' of github.com:HSL…
VillePihlava Dec 23, 2025
87aadad
Remove unnecessary <g> tags from SVGs.
VillePihlava Dec 23, 2025
5d1d81b
Rename variables for clarity and remove props if not necessary.
VillePihlava Dec 23, 2025
f6795fd
Merge branch 'improve-indoor-routing-level-info-v3' of github.com:HSL…
VillePihlava Dec 23, 2025
6528926
Change showIndoorRoute boolean to currentCard enum.
VillePihlava Dec 23, 2025
1f0bb4d
Merge branch 'improve-indoor-routing-level-info-v3' of github.com:HSL…
VillePihlava Dec 23, 2025
4208861
Merge branch 'next' of github.com:HSLdevcom/digitransit-ui into impro…
VillePihlava Dec 23, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 78 additions & 0 deletions app/component/itinerary/IndoorInfo.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import React from 'react';
import PropTypes from 'prop-types';
import cx from 'classnames';
import { FormattedMessage } from 'react-intl';
import { configShape } from '../../util/shapes';
import { isKeyboardSelectionEvent } from '../../util/browser';
import Icon from '../Icon';

export default function IndoorInfo(
{ intermediateStepCount, showIntermediateSteps, toggleFunction },
{ config },
) {
const message = (showIntermediateSteps && (
<FormattedMessage
id="itinerary-hide-indoor-route"
defaultMessage="Hide indoor route"
/>
)) || (
<FormattedMessage
id="itinerary-indoor-route"
defaultMessage="Indoor route"
/>
);
return (
<div
role="button"
tabIndex="0"
className={cx('intermediate-steps-clickable', {
'cursor-pointer': intermediateStepCount > 0,
})}
onClick={e => {
e.stopPropagation();
if (intermediateStepCount > 0) {
toggleFunction();
}
}}
onKeyPress={e => {
if (isKeyboardSelectionEvent(e)) {
e.stopPropagation();
toggleFunction();
}
}}
>
<div
className={cx('intermediate-step-info-container', {
open: showIntermediateSteps,
})}
>
{intermediateStepCount === 0 ? (
<span className="intermediate-steps-message-no-steps">{message}</span>
) : (
<span className="intermediate-steps-message">{message}</span>
)}{' '}
{intermediateStepCount !== 0 && (
<Icon
img="icon_arrow-collapse--right"
className="itinerary-search-icon"
color={config.colors.primary}
/>
)}
</div>
</div>
);
}

IndoorInfo.contextTypes = {
config: configShape.isRequired,
};

IndoorInfo.propTypes = {
intermediateStepCount: PropTypes.number.isRequired,
toggleFunction: PropTypes.func.isRequired,
showIntermediateSteps: PropTypes.bool,
};

IndoorInfo.defaultProps = {
showIntermediateSteps: false,
};
119 changes: 119 additions & 0 deletions app/component/itinerary/IndoorStep.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import PropTypes from 'prop-types';
import React from 'react';
import { FormattedMessage } from 'react-intl';
import cx from 'classnames';
import { configShape } from '../../util/shapes';
import Icon from '../Icon';
import {
getIndoorTranslationId,
getVerticalTransportationUseIconId,
} from '../../util/indoorUtils';
import {
IndoorLegType,
IndoorStepType,
VerticalDirection,
} from '../../constants';
import ItineraryMapAction from './ItineraryMapAction';

function IndoorStep({
focusAction,
type,
verticalDirection,
toLevelName,
isLastPlace,
onlyOneStep,
indoorLegType,
}) {
const indoorTranslationId = getIndoorTranslationId(
type,
verticalDirection,
toLevelName,
);

return (
<div
style={{ width: '100%', position: 'relative' }}
className="row itinerary-row"
>
<div className="small-offset-2 leg-before indoor-step">
<div
className={cx('leg-before-circle', 'circle-fill', 'indoor-step', {
'only-one-step': onlyOneStep,
})}
>
<svg xmlns="http://www.w3.org/2000/svg" width={28} height={28}>
<circle
className="indoor-step-marker"
width={28}
cx={11}
cy={18}
r={6}
strokeWidth={4}
/>
</svg>
</div>
<div
className={cx(
'leg-before-line',
'indoor-step',
{
'only-one-step': onlyOneStep,
},
isLastPlace &&
indoorLegType === IndoorLegType.StepsBeforeEntranceInside
? 'default-dotted-line'
: 'indoor-dotted-line',
)}
/>
</div>
<div className="small-9 columns itinerary-instruction-column intermediate indoor-step">
<div
className={cx('itinerary-leg-row-intermediate-indoor-step', {
'only-one-step': onlyOneStep,
})}
>
<Icon
img={getVerticalTransportationUseIconId(
verticalDirection,
type,
false,
)}
className="itinerary-intermediate-indoor-icon"
/>
<div className="itinerary-intermediate-indoor-step-info">
<FormattedMessage
id={indoorTranslationId}
defaultMessage="Indoor step"
values={{ toLevelName }}
/>
</div>
<ItineraryMapAction target="" focusAction={focusAction} />
</div>
</div>
</div>
);
}

IndoorStep.propTypes = {
focusAction: PropTypes.func.isRequired,
type: PropTypes.oneOf(Object.values(IndoorStepType)).isRequired,
verticalDirection: PropTypes.oneOf(Object.values(VerticalDirection)),
toLevelName: PropTypes.string,
isLastPlace: PropTypes.bool,
onlyOneStep: PropTypes.bool,
indoorLegType: PropTypes.oneOf(Object.values(IndoorLegType)),
};

IndoorStep.defaultProps = {
verticalDirection: undefined,
toLevelName: undefined,
isLastPlace: false,
onlyOneStep: false,
indoorLegType: IndoorLegType.NoStepsInside,
};

IndoorStep.contextTypes = {
config: configShape.isRequired,
};

export default IndoorStep;
20 changes: 3 additions & 17 deletions app/component/itinerary/ItineraryCircleLine.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,22 +25,6 @@ class ItineraryCircleLine extends React.Component {
isStop: PropTypes.bool,
};

constructor(props) {
super(props);

this.state = {
imageUrl: 'none',
};
}

componentDidMount() {
import(
/* webpackChunkName: "dotted-line" */ `../../configurations/images/default/dotted-line.svg`
).then(imageUrl => {
this.setState({ imageUrl: `url(${imageUrl.default})` });
});
}

isFirstChild = () => {
return this.props.index === 0 && !this.props.viaType;
};
Expand Down Expand Up @@ -115,11 +99,12 @@ class ItineraryCircleLine extends React.Component {
const topMarker = this.getMarker(true);
const bottomMarker = this.getMarker(false);
const legBeforeLineStyle = { color: this.props.color };
let backgroundClass = '';
if (
this.props.modeClassName === 'car-park-walk' ||
this.props.modeClassName === 'walk'
) {
legBeforeLineStyle.backgroundImage = this.state.imageUrl;
backgroundClass = 'default-dotted-line';
}

return (
Expand All @@ -137,6 +122,7 @@ class ItineraryCircleLine extends React.Component {
'leg-before-line',
this.props.modeClassName,
this.props.appendClass,
backgroundClass,
)}
/>
{this.props.renderBottomMarker && bottomMarker}
Expand Down
17 changes: 5 additions & 12 deletions app/component/itinerary/ItineraryCircleLineLong.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,12 @@
import PropTypes from 'prop-types';
import React, { useState, useEffect } from 'react';
import React from 'react';
import cx from 'classnames';
import Icon from '../Icon';
import RouteNumber from '../RouteNumber';
import { legShape } from '../../util/shapes';
import { ViaLocationType } from '../../constants';

const ItineraryCircleLineLong = props => {
const [imgUrl, setImgUrl] = useState('');

useEffect(() => {
import(
/* webpackChunkName: "dotted-line" */ `../../configurations/images/default/dotted-line.svg`
).then(imageUrl => {
setImgUrl(`url(${imageUrl.default})`);
});
}, []);

const isFirstChild = () => {
return props.index === 0;
};
Expand Down Expand Up @@ -66,7 +56,6 @@ const ItineraryCircleLineLong = props => {
const carBoardingRouteNumber = (
<RouteNumber mode="car" icon="icon_car" vertical />
);
legBeforeLineStyle.backgroundImage = imgUrl;
return (
<div
className={cx('leg-before long', props.modeClassName, {
Expand All @@ -81,6 +70,7 @@ const ItineraryCircleLineLong = props => {
'leg-before-line top',
positionRelativeToTransit,
firstModeClassName,
'default-dotted-line',
)}
/>
<div
Expand All @@ -103,6 +93,7 @@ const ItineraryCircleLineLong = props => {
'leg-before-line middle',
positionRelativeToTransit,
props.modeClassName,
'default-dotted-line',
)}
/>
<div
Expand All @@ -127,6 +118,7 @@ const ItineraryCircleLineLong = props => {
'leg-before-line second-middle',
positionRelativeToTransit,
props.modeClassName,
'default-dotted-line',
)}
/>
)}
Expand All @@ -151,6 +143,7 @@ const ItineraryCircleLineLong = props => {
positionRelativeToTransit === 'between-transit'
? firstModeClassName
: secondModeClassName,
'default-dotted-line',
)}
/>
{props.renderBottomMarker && bottomMarker}
Expand Down
Loading