Skip to content

Commit 1363e0e

Browse files
committed
make group options usable for all profiles
1 parent 203a815 commit 1363e0e

File tree

7 files changed

+917
-102
lines changed

7 files changed

+917
-102
lines changed

src/custom.d.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ declare module 'custom-model-editor/src/index'
77
declare module 'config' {
88
import ol from 'ol/dist/ol'
99
import array = ol.array
10+
import {ProfileGroup, ProfileGroupMap} from "@/stores/QueryStore";
1011
const routingApi: string
1112
const geocodingApi: string
1213
const defaultTiles: string
@@ -33,7 +34,7 @@ declare module 'config' {
3334
}
3435
maxZoom?: number
3536
}
36-
const profile_group_mapping: Record<string, string>
37+
const profile_group_mapping: Record<string, ProfileGroup>
3738
const profiles: object
3839
}
3940

src/sidebar/SettingsBox.module.css

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,27 +26,23 @@
2626
align-items: center;
2727
}
2828

29-
.carProfileOptionsHeader {
29+
.groupProfileOptionsHeader {
3030
font-weight: bold;
3131
}
3232

33-
.carProfileOptions div {
34-
padding: 4px 14px;
33+
.groupProfileOptions div {
34+
padding: 4px 20px;
3535
}
3636

37-
.carProfileOptions label,
37+
.groupProfileOptions label,
3838
input {
3939
cursor: pointer;
4040
}
4141

42-
.carProfileOptions label {
42+
.groupProfileOptions label {
4343
margin-left: 10px;
4444
}
4545

46-
.carProfileOptions {
47-
padding: 12px 5px;
48-
}
49-
5046
.toggleButton {
5147
display: flex;
5248
align-items: center;
@@ -94,7 +90,8 @@ input {
9490

9591
.title,
9692
.infoLine,
97-
.settingsTable {
93+
.settingsTable,
94+
.groupProfileOptionsHeader {
9895
font-size: 14px;
9996
color: gray;
10097
}

src/sidebar/SettingsBox.tsx

Lines changed: 41 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,51 @@
1-
import { SetVehicleProfile, UpdateSettings } from '@/actions/Actions'
1+
import {SetVehicleProfile, UpdateSettings} from '@/actions/Actions'
22
import Dispatcher from '@/stores/Dispatcher'
33
import styles from '@/sidebar/SettingsBox.module.css'
4-
import { tr } from '@/translation/Translation'
4+
import {tr} from '@/translation/Translation'
55
import PlainButton from '@/PlainButton'
66
import OnIcon from '@/sidebar/toggle_on.svg'
77
import OffIcon from '@/sidebar/toggle_off.svg'
8-
import { useContext, useState } from 'react'
9-
import { SettingsContext } from '@/contexts/SettingsContext'
10-
import { RoutingProfile } from '@/api/graphhopper'
8+
import {useContext} from 'react'
9+
import {SettingsContext} from '@/contexts/SettingsContext'
10+
import {RoutingProfile} from '@/api/graphhopper'
11+
import {ProfileGroupMap} from "@/stores/QueryStore";
12+
import * as config from "config";
1113

12-
export default function SettingsBox({ profile }: { profile: RoutingProfile }) {
14+
export default function SettingsBox({profile}: { profile: RoutingProfile }) {
1315
const settings = useContext(SettingsContext)
16+
1417
function setProfile(n: string) {
15-
Dispatcher.dispatch(new SetVehicleProfile({ name: profile.name === n ? 'car' : n }))
18+
Dispatcher.dispatch(new SetVehicleProfile({name: profile.name === n ? 'car' : n}))
1619
}
1720

21+
const groupName = ProfileGroupMap.create(config.profile_group_mapping)[profile.name]
22+
const group = config.profile_group_mapping[groupName]
1823
return (
1924
<div className={styles.parent}>
25+
{groupName && <span className={styles.groupProfileOptionsHeader}>
26+
{tr(group.settings_tr_key)}
27+
</span>}
28+
{groupName && <div className={styles.settingsTable}>
29+
<div className={styles.groupProfileOptions}>
30+
{group.options.map((option) => (
31+
<div key={option.profile}>
32+
<input checked={profile.name === option.profile} type="radio" id={option.profile}
33+
name={groupName} value={option.profile}
34+
onClick={() => setProfile(option.profile)}/>
35+
<label htmlFor={option.profile}>
36+
{tr(group.settings_tr_key + '_' + option.profile)}
37+
</label>
38+
</div>
39+
))}
40+
</div>
41+
</div>}
2042
<div className={styles.title}>{tr('settings')}</div>
2143
<div className={styles.settingsTable}>
22-
{/* TODO make generic so that it could be used to collapse e.g. hike & foot */}
23-
{profile.name.startsWith('car') && (
24-
<div className={styles.carProfileOptions}>
25-
<span className={styles.carProfileOptionsHeader}>{tr('Avoid')}</span>
26-
<div>
27-
{/*prettier-ignore*/}
28-
<input checked={profile.name === 'car_avoid_motorway'} type="radio" id="motorway" name="car" value="motorway" onClick={e => setProfile('car_avoid_motorway')} />
29-
<label htmlFor="motorway">{tr('motorway')}</label>
30-
</div>
31-
<div>
32-
{/*prettier-ignore*/}
33-
<input checked={profile.name === 'car_avoid_ferry'} type="radio" id="ferry" name="car" value="ferry" onClick={e => setProfile('car_avoid_ferry')} />
34-
<label htmlFor="ferry">{tr('ferry')}</label>
35-
</div>
36-
<div>
37-
{/*prettier-ignore*/}
38-
<input checked={profile.name === 'car_avoid_toll'} type="radio" id="toll" name="car" value="toll" onClick={e => setProfile('car_avoid_toll')} />
39-
<label htmlFor="toll">{tr('toll and ferry')}</label>
40-
</div>
41-
</div>
42-
)}
4344
<SettingsToggle
4445
title={tr('distance_unit', [tr(settings.showDistanceInMiles ? 'mi' : 'km')])}
4546
enabled={settings.showDistanceInMiles}
4647
onClick={() =>
47-
Dispatcher.dispatch(new UpdateSettings({ showDistanceInMiles: !settings.showDistanceInMiles }))
48+
Dispatcher.dispatch(new UpdateSettings({showDistanceInMiles: !settings.showDistanceInMiles}))
4849
}
4950
/>
5051
</div>
@@ -55,23 +56,23 @@ export default function SettingsBox({ profile }: { profile: RoutingProfile }) {
5556
title={tr('settings_gpx_export_trk')}
5657
enabled={settings.gpxExportTrk}
5758
onClick={() =>
58-
Dispatcher.dispatch(new UpdateSettings({ gpxExportTrk: !settings.gpxExportTrk }))
59+
Dispatcher.dispatch(new UpdateSettings({gpxExportTrk: !settings.gpxExportTrk}))
5960
}
6061
/>
6162

6263
<SettingsCheckbox
6364
title={tr('settings_gpx_export_rte')}
6465
enabled={settings.gpxExportRte}
6566
onClick={() =>
66-
Dispatcher.dispatch(new UpdateSettings({ gpxExportRte: !settings.gpxExportRte }))
67+
Dispatcher.dispatch(new UpdateSettings({gpxExportRte: !settings.gpxExportRte}))
6768
}
6869
/>
6970

7071
<SettingsCheckbox
7172
title={tr('settings_gpx_export_wpt')}
7273
enabled={settings.gpxExportWpt}
7374
onClick={() =>
74-
Dispatcher.dispatch(new UpdateSettings({ gpxExportWpt: !settings.gpxExportWpt }))
75+
Dispatcher.dispatch(new UpdateSettings({gpxExportWpt: !settings.gpxExportWpt}))
7576
}
7677
/>
7778
</div>
@@ -87,22 +88,23 @@ export default function SettingsBox({ profile }: { profile: RoutingProfile }) {
8788
)
8889
}
8990

90-
function SettingsToggle({ title, enabled, onClick }: { title: string; enabled: boolean; onClick: () => void }) {
91+
function SettingsToggle({title, enabled, onClick}: { title: string; enabled: boolean; onClick: () => void }) {
9192
return (
9293
<div className={styles.settingsToggle} onClick={onClick}>
93-
<PlainButton style={{ color: enabled ? '' : 'lightgray' }} className={styles.toggleButton}>
94-
{enabled ? <OnIcon /> : <OffIcon />}
94+
<PlainButton style={{color: enabled ? '' : 'lightgray'}} className={styles.toggleButton}>
95+
{enabled ? <OnIcon/> : <OffIcon/>}
9596
</PlainButton>
96-
<div style={{ color: enabled ? '#5b616a' : 'gray' }}>{title}</div>
97+
<div style={{color: enabled ? '#5b616a' : 'gray'}}>{title}</div>
9798
</div>
9899
)
99100
}
100101

101-
function SettingsCheckbox({ title, enabled, onClick }: { title: string; enabled: boolean; onClick: () => void }) {
102+
function SettingsCheckbox({title, enabled, onClick}: { title: string; enabled: boolean; onClick: () => void }) {
102103
return (
103104
<div className={styles.settingsCheckbox} onClick={onClick}>
104-
<input type="checkbox" checked={enabled} onChange={ignore => {}}></input>
105-
<label style={{ color: enabled ? '#5b616a' : 'gray' }}>{title}</label>
105+
<input type="checkbox" checked={enabled} onChange={ignore => {
106+
}}></input>
107+
<label style={{color: enabled ? '#5b616a' : 'gray'}}>{title}</label>
106108
</div>
107109
)
108110
}

src/sidebar/search/Search.module.css

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,22 @@
4949
grid-column: 1 / span 3;
5050
}
5151

52-
.addSearchBox,
53-
.settingsButton {
52+
.addSearchBox {
5453
font-size: 14px;
5554
color: gray;
5655
}
5756

57+
.settingsButton,
58+
.settingsButton:hover {
59+
font-size: 14px;
60+
font-weight: bold;
61+
color: rgba(39, 100, 200, 0.85);
62+
}
63+
64+
.settingsButton:hover {
65+
color: rgb(35, 92, 185);
66+
}
67+
5868
.lastSearchLine {
5969
display: flex;
6070
flex-direction: row;

src/sidebar/search/routingProfiles/RoutingProfiles.tsx

Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,25 @@
1-
import React, { useEffect, useState } from 'react'
1+
import React, {useEffect, useState} from 'react'
22
import styles from './RoutingProfiles.module.css'
33
import Dispatcher from '@/stores/Dispatcher'
4-
import { SetVehicleProfile } from '@/actions/Actions'
5-
import { RoutingProfile } from '@/api/graphhopper'
4+
import {SetVehicleProfile} from '@/actions/Actions'
5+
import {RoutingProfile} from '@/api/graphhopper'
66
import PlainButton from '@/PlainButton'
77
import Chevron from './chevron.svg'
8-
import { tr } from '@/translation/Translation'
8+
import {tr} from '@/translation/Translation'
99
import CustomModelBoxSVG from '@/sidebar/open_custom_model.svg'
10-
import { icons } from '@/sidebar/search/routingProfiles/profileIcons'
10+
import {icons} from '@/sidebar/search/routingProfiles/profileIcons'
11+
import {ProfileGroup, ProfileGroupMap} from "@/stores/QueryStore";
1112

1213
export default function ({
13-
routingProfiles,
14-
profileGroupMapping,
15-
selectedProfile,
16-
showCustomModelBox,
17-
toggleCustomModelBox,
18-
customModelBoxEnabled,
19-
}: {
14+
routingProfiles,
15+
profileGroupMapping,
16+
selectedProfile,
17+
showCustomModelBox,
18+
toggleCustomModelBox,
19+
customModelBoxEnabled,
20+
}: {
2021
routingProfiles: RoutingProfile[]
21-
profileGroupMapping: Record<string, string>
22+
profileGroupMapping: Record<string, ProfileGroup>
2223
selectedProfile: RoutingProfile
2324
showCustomModelBox: boolean
2425
toggleCustomModelBox: () => void
@@ -82,14 +83,15 @@ export default function ({
8283
if (!icons[p.name]) customProfiles[key] = [...(customProfiles[key] || []), p.name]
8384
})
8485

86+
let profileToGroup = ProfileGroupMap.create(profileGroupMapping)
8587
return (
8688
<div className={styles.profilesParent}>
8789
<PlainButton
8890
title={tr('open_custom_model_box')}
8991
className={showCustomModelBox ? styles.enabledCMBox : styles.cmBox}
9092
onClick={toggleCustomModelBox}
9193
>
92-
<CustomModelBoxSVG />
94+
<CustomModelBoxSVG/>
9395
</PlainButton>
9496
<div className={styles.carousel}>
9597
<PlainButton
@@ -98,13 +100,12 @@ export default function ({
98100
onClick={() => move(false)}
99101
disabled={profileScroll <= 0}
100102
>
101-
<Chevron />
103+
<Chevron/>
102104
</PlainButton>
103105
<ul className={styles.profiles} id="profiles_carousel_items" onScroll={onScroll}>
104-
{routingProfiles.map(profile => {
106+
{routingProfiles.filter(profile => !profileToGroup[profile.name] || profile.name == profileToGroup[profile.name]).map(profile => {
105107
const isProfileSelected =
106-
profile.name === selectedProfile.name ||
107-
profile.name === profileGroupMapping[selectedProfile.name]
108+
profile.name === selectedProfile.name || profile.name == profileToGroup[selectedProfile.name]
108109
const className = isProfileSelected
109110
? styles.selectedProfile + ' ' + styles.profileBtn
110111
: styles.profileBtn
@@ -116,7 +117,7 @@ export default function ({
116117
className={className}
117118
>
118119
{customModelBoxEnabled && profile.name === selectedProfile.name && (
119-
<CustomModelBoxSVG className={styles.asIndicator} />
120+
<CustomModelBoxSVG className={styles.asIndicator}/>
120121
)}
121122
{getIcon(profile.name, customProfiles)}
122123
</PlainButton>
@@ -130,7 +131,7 @@ export default function ({
130131
onClick={() => move()}
131132
disabled={profileScroll >= profileWidth}
132133
>
133-
<Chevron />
134+
<Chevron/>
134135
</PlainButton>
135136
</div>
136137
</div>
@@ -147,25 +148,25 @@ function getIcon(profileName: string, customProfiles: Record<string, Array<strin
147148
if (index >= 1) {
148149
let icon = icons[key.slice(0, -1)] // slice to remove underscore from key
149150
if (!icon) icon = icons.question_mark
150-
return key === '_' ? <NumberIcon number={index} /> : <IconWithBatchNumber baseIcon={icon} number={index} />
151+
return key === '_' ? <NumberIcon number={index}/> : <IconWithBatchNumber baseIcon={icon} number={index}/>
151152
}
152153
}
153154

154155
// this is the very last fallback, should never be reached
155156
return React.createElement(icons.question_mark)
156157
}
157158

158-
function IconWithBatchNumber({ baseIcon, number }: { baseIcon: any; number: number }) {
159+
function IconWithBatchNumber({baseIcon, number}: { baseIcon: any; number: number }) {
159160
return (
160161
<div className={styles.iconContainer}>
161162
{React.createElement(baseIcon)}
162163
<div className={styles.batchNumber}>
163-
<NumberIcon number={number} />
164+
<NumberIcon number={number}/>
164165
</div>
165166
</div>
166167
)
167168
}
168169

169-
function NumberIcon({ number }: { number: number }) {
170+
function NumberIcon({number}: { number: number }) {
170171
return <span>{number}</span>
171172
}

0 commit comments

Comments
 (0)