Skip to content

Commit

Permalink
Some changes to formatting and a bit other minor changes.
Browse files Browse the repository at this point in the history
  • Loading branch information
a-limyr committed Jan 22, 2025
1 parent d448c8b commit 0b4f5d5
Show file tree
Hide file tree
Showing 14 changed files with 209 additions and 240 deletions.
10 changes: 1 addition & 9 deletions client/codegen-preprocess.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,14 @@ import type { CodegenConfig } from '@graphql-codegen/cli';

import * as path from 'node:path';



const config: CodegenConfig = {
overwrite: true,
schema: 'https://otp2debug.dev.entur.org/otp/transmodel/v3/schema.graphql',
documents: 'src/**/*.{ts,tsx}',
generates: {
'src/static/query/tripQuery.tsx': {
'src/gql/tripQuery.tsx': {
plugins: [path.resolve(__dirname, './src/util/generate-queries.cjs')],
},
'src/gql/query-arguments.json': {
plugins: [path.resolve(__dirname, './src/util/generate-arguments.cjs')],
config: {
excludeDeprecated: true, // Ensure this is set to true
},
},
},
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,7 @@ export function ItineraryListContainer({
return (
<section className="left-pane-container below-content" ref={containerRef}>
<>
<div className="panel-header">
Itinerary results
</div>
<div className="panel-header">Itinerary results</div>
<div className="pagination-controls">
<ItineraryPaginationControl
onPagination={pageResults}
Expand Down
313 changes: 151 additions & 162 deletions client/src/components/MapView/LayerControl.tsx
Original file line number Diff line number Diff line change
@@ -1,180 +1,169 @@
import React, { useEffect, useState, useCallback } from 'react';
import type {AnyLayer, ControlPosition} from 'react-map-gl';
import type { AnyLayer, ControlPosition } from 'react-map-gl';
import type { MapRef } from 'react-map-gl/maplibre';

interface Layer {
id: string;
name: string;
id: string;
name: string;
}

interface LayerControlProps {
mapRef: MapRef | null;
position: ControlPosition; // not used in inline styling, but you might use it if you want
setInteractiveLayerIds: (interactiveLayerIds: string[]) => void;
mapRef: MapRef | null;
position: ControlPosition; // not used in inline styling, but you might use it if you want
setInteractiveLayerIds: (interactiveLayerIds: string[]) => void;
}

/**
* A React component to control:
* 1. Background (raster) layers (select exactly one to show).
* 2. Debug layers (vector-like layers) with groupings, toggle on/off individually.
*/
const LayerControl: React.FC<LayerControlProps> = ({
mapRef,
setInteractiveLayerIds,
}) => {
const [rasterLayers, setRasterLayers] = useState<Layer[]>([]);
const [layerGroups, setLayerGroups] =
useState<Record<string, Layer[]>>({});

/**
* Load background + debug layers from the style once the map is ready.
*/
useEffect(() => {
if (!mapRef) return;
const mapInstance = mapRef.getMap();

const loadLayers = () => {
const style = mapInstance.getStyle();
if (!style || !style.layers) return;

// 1. Gather all raster layers (for the background selector).
const rasters = style.layers
.filter((layer) => layer.type === 'raster')
.map((layer) => {
// Try to pick up a pretty name from metadata if available.
let name = layer.id;
if ((layer as AnyLayer).metadata?.name) {
name = (layer as AnyLayer).metadata.name;
}
return { id: layer.id, name };
});
setRasterLayers(rasters);

// 2. Gather all "debug" layers (i.e. not raster, not "jsx").
// Group them by metadata.group (falling back to "Misc").
const groups: Record<string, Layer[]> = {};
style.layers
.filter((layer) => layer.type !== 'raster' && !layer.id.startsWith('jsx'))
.reverse() // so that the topmost layers appear first
.forEach((layer) => {
const groupName = (layer as AnyLayer).metadata?.group || 'Misc';
if (!groups[groupName]) {
groups[groupName] = [];
}
groups[groupName].push({ id: layer.id, name: layer.id });
});

setLayerGroups(groups);
};

if (mapInstance.isStyleLoaded()) {
loadLayers();
} else {
mapInstance.on('styledata', loadLayers);
}

return () => {
mapInstance.off('styledata', loadLayers);
};
}, [mapRef]);

/**
* Toggle the visibility of an individual debug layer.
*/
const toggleLayerVisibility = useCallback(
(layerId: string, isVisible: boolean) => {
if (!mapRef) return;
const mapInstance = mapRef.getMap();
mapInstance.setLayoutProperty(layerId, 'visibility', isVisible ? 'visible' : 'none');

// After toggling, recalculate which interactive layers are visible.
const style = mapInstance.getStyle();
if (!style || !style.layers) return;

const visibleInteractive = style.layers
.filter((l) => l.type !== 'raster' && !l.id.startsWith('jsx'))
.filter((l) => mapInstance.getLayoutProperty(l.id, 'visibility') !== 'none')
.map((l) => l.id);

setInteractiveLayerIds(visibleInteractive);
},
[mapRef, setInteractiveLayerIds]
);

/**
* Show exactly one background (raster) layer at a time.
*/
const setBackgroundLayer = useCallback(
(layerId: string) => {
if (!mapRef) return;
const mapInstance = mapRef.getMap();
rasterLayers.forEach((r) => {
mapInstance.setLayoutProperty(
r.id,
'visibility',
r.id === layerId ? 'visible' : 'none'
);
});
},
[mapRef, rasterLayers]
);

return (
<div
style={{
display: 'flex',
flexDirection: 'column',
padding: '10px',
width: '250px',
borderRadius: '4px',
overflowY: 'auto',
}}
>
{/* BACKGROUND (RASTER) LAYERS */}
<h4 style={{ marginTop: 0 }}>Background</h4>
<select onChange={(e) => setBackgroundLayer(e.target.value)}>
{rasterLayers.map((layer) => (
<option key={layer.id} value={layer.id}>
{layer.name}
</option>
))}
</select>

{/* DEBUG (VECTOR) LAYERS */}
<h4 style={{ marginTop: '1rem' }}>Debug Layers</h4>
{Object.entries(layerGroups).map(([groupName, layers]) => (
<div key={groupName} style={{ marginBottom: '10px' }}>
<h6 style={{ margin: '0 0 5px' }}>{groupName}</h6>
{layers.map((layer) => {
// Grab the map property for whether it’s visible or not:
const isVisible =
mapRef?.getMap().getLayoutProperty(layer.id, 'visibility') !== 'none';

return (
<label
key={layer.id}
style={{
display: 'block',
cursor: 'pointer',
marginBottom: '5px',
}}
>
<input
type="checkbox"
checked={isVisible}
onChange={(e) =>
toggleLayerVisibility(layer.id, e.target.checked)
}
style={{ marginRight: '5px' }}
/>
{layer.name}
</label>
);
})}
</div>
))}
const LayerControl: React.FC<LayerControlProps> = ({ mapRef, setInteractiveLayerIds }) => {
const [rasterLayers, setRasterLayers] = useState<Layer[]>([]);
const [layerGroups, setLayerGroups] = useState<Record<string, Layer[]>>({});

/**
* Load background + debug layers from the style once the map is ready.
*/
useEffect(() => {
if (!mapRef) return;
const mapInstance = mapRef.getMap();

const loadLayers = () => {
const style = mapInstance.getStyle();
if (!style || !style.layers) return;

// 1. Gather all raster layers (for the background selector).
const rasters = style.layers
.filter((layer) => layer.type === 'raster')
.map((layer) => {
// Try to pick up a pretty name from metadata if available.
let name = layer.id;
if ((layer as AnyLayer).metadata?.name) {
name = (layer as AnyLayer).metadata.name;
}
return { id: layer.id, name };
});
setRasterLayers(rasters);

// 2. Gather all "debug" layers (i.e. not raster, not "jsx").
// Group them by metadata.group (falling back to "Misc").
const groups: Record<string, Layer[]> = {};
style.layers
.filter((layer) => layer.type !== 'raster' && !layer.id.startsWith('jsx'))
.reverse() // so that the topmost layers appear first
.forEach((layer) => {
const groupName = (layer as AnyLayer).metadata?.group || 'Misc';
if (!groups[groupName]) {
groups[groupName] = [];
}
groups[groupName].push({ id: layer.id, name: layer.id });
});

setLayerGroups(groups);
};

if (mapInstance.isStyleLoaded()) {
loadLayers();
} else {
mapInstance.on('styledata', loadLayers);
}

return () => {
mapInstance.off('styledata', loadLayers);
};
}, [mapRef]);

/**
* Toggle the visibility of an individual debug layer.
*/
const toggleLayerVisibility = useCallback(
(layerId: string, isVisible: boolean) => {
if (!mapRef) return;
const mapInstance = mapRef.getMap();
mapInstance.setLayoutProperty(layerId, 'visibility', isVisible ? 'visible' : 'none');

// After toggling, recalculate which interactive layers are visible.
const style = mapInstance.getStyle();
if (!style || !style.layers) return;

const visibleInteractive = style.layers
.filter((l) => l.type !== 'raster' && !l.id.startsWith('jsx'))
.filter((l) => mapInstance.getLayoutProperty(l.id, 'visibility') !== 'none')
.map((l) => l.id);

setInteractiveLayerIds(visibleInteractive);
},
[mapRef, setInteractiveLayerIds],
);

/**
* Show exactly one background (raster) layer at a time.
*/
const setBackgroundLayer = useCallback(
(layerId: string) => {
if (!mapRef) return;
const mapInstance = mapRef.getMap();
rasterLayers.forEach((r) => {
mapInstance.setLayoutProperty(r.id, 'visibility', r.id === layerId ? 'visible' : 'none');
});
},
[mapRef, rasterLayers],
);

return (
<div
style={{
display: 'flex',
flexDirection: 'column',
padding: '10px',
width: '250px',
borderRadius: '4px',
overflowY: 'auto',
}}
>
{/* BACKGROUND (RASTER) LAYERS */}
<h4 style={{ marginTop: 0 }}>Background</h4>
<select onChange={(e) => setBackgroundLayer(e.target.value)}>
{rasterLayers.map((layer) => (
<option key={layer.id} value={layer.id}>
{layer.name}
</option>
))}
</select>

{/* DEBUG (VECTOR) LAYERS */}
<h4 style={{ marginTop: '1rem' }}>Debug Layers</h4>
{Object.entries(layerGroups).map(([groupName, layers]) => (
<div key={groupName} style={{ marginBottom: '10px' }}>
<h6 style={{ margin: '0 0 5px' }}>{groupName}</h6>
{layers.map((layer) => {
// Grab the map property for whether it’s visible or not:
const isVisible = mapRef?.getMap().getLayoutProperty(layer.id, 'visibility') !== 'none';

return (
<label
key={layer.id}
style={{
display: 'block',
cursor: 'pointer',
marginBottom: '5px',
}}
>
<input
type="checkbox"
checked={isVisible}
onChange={(e) => toggleLayerVisibility(layer.id, e.target.checked)}
style={{ marginRight: '5px' }}
/>
{layer.name}
</label>
);
})}
</div>
);
))}
</div>
);
};

export default LayerControl;
2 changes: 1 addition & 1 deletion client/src/components/MapView/MapView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ export function MapView({
// 2) Add the native MapLibre attribution control
onLoad(e);
}

const mapRef = useRef<MapRef>(null); // Create a ref for MapRef
return (
<div className="map-container below-content">
Expand Down
2 changes: 1 addition & 1 deletion client/src/components/SearchBar/GraphiQLRouteButton.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Button } from 'react-bootstrap';
import { TripQueryVariables } from '../../gql/graphql.ts';
import { queryAsString } from '../../static/query/tripQuery.tsx';
import { queryAsString } from '../../gql/tripQuery.tsx';
import graphqlIcon from '../../static/img/graphql-solid.svg';

const graphiQLUrl = import.meta.env.VITE_GRAPHIQL_URL;
Expand Down
Loading

0 comments on commit 0b4f5d5

Please sign in to comment.