diff --git a/frontend/src/lib/components/collections/CollectionItineraryPlanner.svelte b/frontend/src/lib/components/collections/CollectionItineraryPlanner.svelte index 319452ab..2b8fb118 100644 --- a/frontend/src/lib/components/collections/CollectionItineraryPlanner.svelte +++ b/frontend/src/lib/components/collections/CollectionItineraryPlanner.svelte @@ -576,6 +576,9 @@ ): ResolvedItineraryItem | null { for (let index = currentIndex + 1; index < items.length; index += 1) { const candidate = items[index]; + if (candidate?.[SHADOW_ITEM_MARKER_PROPERTY_NAME]) { + continue; + } if ((candidate?.item?.type || '') === 'location') { return candidate; } @@ -590,6 +593,9 @@ for (const dayGroup of dayGroups) { for (let index = 0; index < dayGroup.items.length - 1; index += 1) { const currentItem = dayGroup.items[index]; + if (currentItem?.[SHADOW_ITEM_MARKER_PROPERTY_NAME]) { + continue; + } const nextLocationItem = findNextLocationItem(dayGroup.items, index); const pair = getConnectorPair(currentItem, nextLocationItem); if (pair) pairs.push(pair); @@ -696,7 +702,9 @@ } catch (error) { if (fetchVersion !== activeConnectorFetchVersion) return; console.error('Failed to fetch connector route metrics:', error); - connectorMetricsMap = {}; + if (connectorPairs.length === 0) { + connectorMetricsMap = {}; + } } } @@ -754,6 +762,41 @@ return getFallbackLocationConnector(currentItem, nextItem); } + function buildDirectionsUrl( + currentItem: ResolvedItineraryItem, + nextItem: ResolvedItineraryItem | null, + mode: 'walking' | 'driving' = 'walking' + ): string | null { + if (!nextItem) return null; + + const currentType = currentItem.item?.type || ''; + const nextType = nextItem.item?.type || ''; + if (currentType !== 'location' || nextType !== 'location') return null; + + const currentLocation = currentItem.resolvedObject as Location | null; + const nextLocation = nextItem.resolvedObject as Location | null; + if (!currentLocation || !nextLocation) return null; + + const fromLatitude = normalizeCoordinate(currentLocation.latitude); + const fromLongitude = normalizeCoordinate(currentLocation.longitude); + const toLatitude = normalizeCoordinate(nextLocation.latitude); + const toLongitude = normalizeCoordinate(nextLocation.longitude); + + if ( + fromLatitude === null || + fromLongitude === null || + toLatitude === null || + toLongitude === null + ) { + return null; + } + + const engine = mode === 'driving' ? 'car' : 'foot'; + const route = `${fromLatitude},${fromLongitude};${toLatitude},${toLongitude}`; + + return `https://www.openstreetmap.org/directions?engine=fossgis_osrm_${engine}&route=${encodeURIComponent(route)}`; + } + function getI18nText(key: string, fallback: string): string { const translated = $t(key); return translated && translated !== key ? translated : fallback; @@ -1413,6 +1456,13 @@ return it; }); collection.itinerary = updatedItinerary; + + // Rebuild canonical local state immediately after persisting reorder + days = groupItemsByDay(collection); + globalItems = (collection.itinerary || []) + .filter((it) => it.is_global) + .map((it) => resolveItineraryItem(it, collection)) + .sort((a, b) => a.order - b.order); } catch (error) { console.error('Error saving itinerary order:', error); // Optionally show error notification to user @@ -2406,6 +2456,11 @@ {@const multiDay = isMultiDay(item)} {@const nextLocationItem = findNextLocationItem(day.items, index)} {@const locationConnector = getLocationConnector(item, nextLocationItem)} + {@const directionsUrl = buildDirectionsUrl( + item, + nextLocationItem, + locationConnector?.mode || 'walking' + )} {@const isDraggingShadow = item[SHADOW_ITEM_MARKER_PROPERTY_NAME]}
{locationConnector.durationLabel} - • - -