Commit Graph

11 Commits

Author SHA1 Message Date
Maurice 49afee161d feat(mobile): phone styling for tours list, trip settings and admin cards
The tours list in the places browser now uses the same rows as places: a
grade or type tile, the day plan's figure badges and a day badge or plus on
the right. A shared "Planned on desktop" badge replaces the grey hint box
there and sits under the road trip's empty stage.

Trip settings and trip edit open phone sheets instead of the desktop
dialogs; the edit sheet gains the day count of a dateless trip and the
reminder. Questions are asked in phone sheets, not the browser.

Admin on the phone: the paddle regions and school holiday cards are phone
cards on their shared hooks, long addon descriptions fold to two lines,
the addon header keeps the wordmark inside its sentence, the group bands
drop the dash and the permissions actions get a row of their own. The
Tours addon gets its catalog name and description in every locale.

The journey map on the phone shows every layer without the switch bar.
2026-10-22 21:26:41 +02:00
Maurice d3f574f225 fix(tours): match a saved ski route by its ski choice, and keep the planner under the lint limits
The saved ski route compared against an undefined skiKey, so opening a saved
ski tour threw. The held seed now lives in useSavedSkiSeed and is matched by
skiRouteKey(skiChoice). The ski route facts move to skiRouteFacts.ts so the
summary and leg rows only export components, the rail renders
SkiPlannerSummary, and openTour, useTourRoute and useAddonManager shed the
branches and lines the new ski code had added.
2026-10-20 21:43:46 +02:00
Maurice 2d0c0597b3 feat(tours): plan ski tours on the piste router in the planner
A ski tour with a discipline now sends its legs to the piste router and
takes back runs, lifts and trails: each stretch is coloured by its grade
in the area's scheme, links and lift rides down are dotted, and a leg the
router cannot plan stays straight and unrouted with its reason and the one
change that would plan it. Snowshoe and winter hike legs off the piste
data follow summer paths instead, said so. The router's time and heights
are used once every leg is planned, and the options, the build and the
time are saved with the tour.

- skiRouteRepo and api: one request per tour, batched, remembered unless
  the answer may change, offline legs failed as offline
- planner: router options per discipline, leg steps and failure rows with
  fixes, a piste route summary, draft and reopen keep the options
- admin: switch for the piste router under Tours
- i18n: new ski keys in all 27 locales, ski info and time texts rewritten
2026-10-20 21:15:07 +02:00
Maurice 73237ffedb feat(tours): bike tours in the planner, CyclOSM, and the planned cards' last points (BIK-01 to BIK-06, RTE-01, IO-01, LIB-02)
The tour type is a dropdown; a bike tour picks its profile, routes for it,
says when a point lies off every way, and shows what it runs on: surfaces,
kinds of way and, for a mountain bike, the trail grades, each pointed at on
the map. A type's own map (OpenHikingMap for a hike, CyclOSM for a bike tour)
is offered while a tour of that type is open, with an admin switch each.

From the planned cards: a hike avoids steep climbs, steps or ferries, nothing
else; a saved tour can be shared where the platform takes GPX files; and the
tours rail adds a tour from one menu: plan new, import GPX, or take one over
from another trip.
2026-10-19 21:33:49 +02:00
Maurice 06e6e25b25 feat(tours): OpenHikingMap as a hiking base map of the tour planner (MAP-01)
While a hike is planned, the planner's map switch offers "Hiking" beside the
map, topo and satellite: OpenHikingMap, with marked trails over the terrain.
It is a choice of the planner's view alone, like topo: the global map
setting, the tour and its days stay as they are. With no tour open, over an
import viewed as it came in and for a paddle tour it is not offered, and a
choice made earlier falls back to the standard map there.

openmaps.fr's tile usage policy is followed: tiles load only as the map
shows them, with the browser's Referer, from the server's own caching; no
service worker rule keeps them and the 3D flyover's warm-up passes their
source by. Its credit and donation link are on the map; the 3D map, whose
attribution is folded away under the panel, shows them as a line of its own
above its controls.

The service is best effort. A run of failed tiles while it is shown marks
the switch, with a tooltip and a status for screen readers that say it is
not answering and that the tour is untouched; one tile arriving clears it.
The tile health the seamark overlay had is now useTileHealth, shared by both.

The source is free for non-commercial installs up to 500,000 tiles a month.
tours_hiking_map_enabled is an admin switch under Tours (admin tours-hiking-map,
audited), on by default, for an install that is commercial or larger to
switch off until it has an agreement with the operator. /api/addons carries
it as toursHikingMap, true only while Tours is on.

Leaflet, GL and the 3D map read one table of the planner's raster bases
(tourRasterBases), so topo and the hiking map are drawn the same way.
tile.openmaps.fr is on the CSP's connect-src for the GL maps.
2026-10-19 13:07:36 +02:00
Maurice f1c437b8b8 Keep api/client.ts and trips.service.ts within their size baselines
The admin switch for wanderer moves to api/wanderer.ts and the recorded
track restore to api/recordedTrack.ts; trips.service.ts keeps dev's
formatting with only the derived-from remap on copy.
2026-10-15 18:16:25 +02:00
Maurice 782e613506 Tours: day GPX import, wanderer trails and planning over an import
- GPX files drop onto the map or a day; the import lands on that day
- wanderer connection per user in Integrations; the workspace offers the
  user's own trails only, behind an admin switch under the Tours addon
- wanderer difficulty is stored on the SAC scale (T1 to T3), backfilled
- a GPX or wanderer import can be planned as an editable tour, either in
  place (the recorded track is kept and can be restored) or as a new tour
  that remembers the import it came from
- rails, rows and detail dialog follow the plan sidebar's cards and badges
- admin addon shelves with more than one row fold, collapsed by default
- reverse-geocoded waypoint names are cached on the device
2026-10-15 17:44:15 +02:00
Maurice dae20c166a fix(admin): keep an Anthropic Messages gateway as the AI parsing base URL (#2655)
Both admin forms hid the field for Anthropic and the shared hook saved an
empty address, wiping a gateway configured on the server. The field shows for
every provider now and is saved as typed; switching provider empties it, so an
address meant for one never receives another provider's key.
2026-10-14 13:24:27 +02:00
Maurice 66e574fcc0 fix(llm-parse): the local model list and pull send the saved api key to an ollama behind an auth proxy
The admin screen's model list (/api/tags) and pull (/api/pull) went out
without the Authorization header that the extraction and /api/show already
send, so an Ollama behind a Bearer proxy answered 401 and the list came back
as a 502. The controller now adds the key saved with the local provider, read
server side through LlmConfigResolver.readLocalServerAccess, and only when the
requested base URL reaches the same server root as the saved one, so another
address in the form never receives it.

A 401 or 403 now says whether the key was rejected or none is saved for that
address, and the admin form shows the server's reason instead of the axios
status line. A server without /api/tags (LM Studio, vLLM) is asked for its
OpenAI-compatible /v1/models instead, and the list body is read with a size
cap and checked before use.

Refs #2649
2026-10-12 21:04:23 +02:00
Maurice e0fd2c296b refactor(admin): draw the photo provider marks from one icons file
The desktop and the phone addon manager each carried their own copy of the Immich and Synology SVGs. Both now import them from components/Admin/addons/PhotoProviderIcons, which has its own test. The rendered marks are unchanged.
2026-10-09 16:29:40 +02:00
Maurice 7738334fd6 refactor(admin): share the addon manager and the AI parsing config between desktop and phone
useAddonManager now loads and toggles the addons and builds the provider shelves, useLlmParsingConfig holds the AI parsing form with the Ollama model list and pull, and addonModel keeps the shared types, collab sub features, labels and recommended models. Both shells keep their own markup.
2026-10-09 15:19:46 +02:00