Managed mode: keep the journey page suite within its size baseline

- The owner sign-in and the photo provider the suite runs with move into
  tests/helpers/journeyDetail.ts, so the page test is back under its line
  baseline, which drops to 4028.
- Drop help/registry.base.ts, an unused copy of the help registry whose key
  builders the i18n key check could not resolve.
This commit is contained in:
Maurice
2026-11-02 21:54:42 +00:00
committed by Maurice
parent 59e68d81b2
commit f99b40cd81
4 changed files with 21 additions and 157 deletions
+1 -1
View File
@@ -18,7 +18,7 @@
"src/components/Studio/countryShapes.ts": 2595,
"src/index.css": 1636,
"src/mobile/screens/admin/MAdminPluginsPanel.tsx": 1507,
"src/pages/JourneyDetailPage.test.tsx": 4030,
"src/pages/JourneyDetailPage.test.tsx": 4028,
"src/pages/LoginPage.tsx": 1348,
"src/pages/TripPlannerPage.tsx": 1128,
"src/pages/atlas/useAtlas.ts": 1210,
-148
View File
@@ -1,148 +0,0 @@
import type { HelpContext, HelpGuide } from './types'
import { dashboardContext, dashboardGuides } from './contexts/dashboard'
import { vacayContext, vacayGuides } from './contexts/vacay'
import { atlasContext, atlasGuides } from './contexts/atlas'
import { collectionsContext, collectionsGuides } from './contexts/collections'
import { journeyContext, journeyGuides, journalContext, journalGuides, studioContext, studioGuides } from './contexts/journey'
import { settingsContext, settingsTabContexts, settingsGuides } from './contexts/settings'
import { adminContext, adminTabContexts, adminGuides } from './contexts/admin'
import { tripContext, tripGuides } from './contexts/trip'
import { tripPlacesContext, tripPlacesGuides } from './contexts/tripPlaces'
import { tripDaysContext, tripDaysGuides } from './contexts/tripDays'
import { tripRoadtripContext, tripRoadtripGuides } from './contexts/tripRoadtrip'
import { tripCollabContext, tripCollabGuides } from './contexts/tripCollab'
import { tripFilesContext, tripFilesGuides } from './contexts/tripFiles'
import { tripCostsContext, tripCostsGuides } from './contexts/tripCosts'
import { tripListsContext, tripListsGuides } from './contexts/tripLists'
import { tripBookingsContext, tripBookingsGuides } from './contexts/tripBookings'
import { tripTransportsContext, tripTransportsGuides } from './contexts/tripTransports'
import { tripMapContext, tripMapGuides } from './contexts/tripMap'
import { tripDayDetailContext, tripDayDetailGuides } from './contexts/tripDayDetail'
import { tripPlaceContext, tripPlaceGuides } from './contexts/tripPlace'
import { tripToursContext, tripToursGuides } from './contexts/tripTours'
import { tripTourDetailContext, tripTourDetailGuides } from './contexts/tripTourDetail'
import { tripTourPlannerContext, tripTourPlannerGuides } from './contexts/tripTourPlanner'
import { tripTourImportContext, tripTourImportGuides } from './contexts/tripTourImport'
import { tripTourMapContext, tripTourMapGuides } from './contexts/tripTourMap'
import { tripTourStagesContext, tripTourStagesGuides } from './contexts/tripTourStages'
import { tripTourHikeContext, tripTourHikeGuides } from './contexts/tripTourHike'
import { tripTourWalkContext, tripTourWalkGuides } from './contexts/tripTourWalk'
import { tripTourBikeContext, tripTourBikeGuides } from './contexts/tripTourBike'
import { tripTourSkiContext, tripTourSkiGuides } from './contexts/tripTourSki'
import { tripTourPaddleContext, tripTourPaddleGuides } from './contexts/tripTourPaddle'
import { tripTourHorseContext, tripTourHorseGuides } from './contexts/tripTourHorse'
import { notificationsContext, notificationsGuides } from './contexts/notifications'
/**
* Everything the help center knows, composed from one file per screen under
* `contexts/`. A screen announces which context it is with `<HelpAnchor id>`
* (or `useHelpContext`), and the panel looks the rest up here.
*/
// The order of the screen switcher: the trip right under My Trips, where it is opened from.
const CONTEXT_LIST: HelpContext[] = [
dashboardContext,
// The trip and its own screens, in the order a reader meets them: the three
// columns of the plan, the two panels that open over it, then the tabs in the
// order the tab bar has them, and the drive last because an addon decides it.
tripContext, tripDaysContext, tripPlacesContext, tripMapContext,
tripPlaceContext, tripDayDetailContext,
tripTransportsContext, tripBookingsContext, tripListsContext, tripCostsContext, tripFilesContext, tripCollabContext,
tripRoadtripContext,
// Tours: the list and the card on the Plan tab, then the Tours tab with its
// jobs and one screen per kind of tour, in the order the type picker has them.
tripToursContext, tripTourDetailContext,
tripTourPlannerContext, tripTourImportContext, tripTourMapContext, tripTourStagesContext,
tripTourHikeContext, tripTourWalkContext, tripTourBikeContext, tripTourSkiContext, tripTourPaddleContext, tripTourHorseContext,
notificationsContext,
vacayContext, atlasContext, collectionsContext, journeyContext, journalContext, studioContext,
settingsContext, ...settingsTabContexts, adminContext, ...adminTabContexts,
]
const GUIDE_LIST: HelpGuide[] = [
...dashboardGuides, ...vacayGuides, ...atlasGuides, ...collectionsGuides, ...journeyGuides, ...journalGuides, ...studioGuides,
...settingsGuides, ...adminGuides,
...tripGuides, ...tripDaysGuides, ...tripPlacesGuides, ...tripMapGuides,
...tripPlaceGuides, ...tripDayDetailGuides,
...tripTransportsGuides, ...tripBookingsGuides, ...tripListsGuides, ...tripCostsGuides, ...tripFilesGuides, ...tripCollabGuides,
...tripRoadtripGuides,
...tripToursGuides, ...tripTourDetailGuides,
...tripTourPlannerGuides, ...tripTourImportGuides, ...tripTourMapGuides, ...tripTourStagesGuides,
...tripTourHikeGuides, ...tripTourWalkGuides, ...tripTourBikeGuides, ...tripTourSkiGuides, ...tripTourPaddleGuides, ...tripTourHorseGuides,
...notificationsGuides,
]
export const HELP_CONTEXTS: ReadonlyMap<string, HelpContext> = new Map(CONTEXT_LIST.map(c => [c.id, c]))
export const HELP_GUIDES: ReadonlyMap<string, HelpGuide> = new Map(GUIDE_LIST.map(g => [g.id, g]))
export function getHelpContext(id: string | null | undefined): HelpContext | null {
return id ? (HELP_CONTEXTS.get(id) ?? null) : null
}
export function getHelpGuide(id: string | null | undefined): HelpGuide | null {
return id ? (HELP_GUIDES.get(id) ?? null) : null
}
/** The guides of a context, in the order the context lists them. */
export function guidesFor(context: HelpContext): HelpGuide[] {
return context.guides.map(id => HELP_GUIDES.get(id)).filter((g): g is HelpGuide => g !== undefined)
}
export function allHelpGuides(): HelpGuide[] {
return GUIDE_LIST
}
/** Every screen that has help, in registration order, for the screen switcher. */
export function allHelpContexts(): HelpContext[] {
return CONTEXT_LIST
}
/** The screens that stand on their own; their sub-screens hang under them in the switcher. */
export function topLevelHelpContexts(): HelpContext[] {
return CONTEXT_LIST.filter(c => !c.parent)
}
/** The sub-screens of a screen, in registration order. */
export function childHelpContexts(parentId: string): HelpContext[] {
return CONTEXT_LIST.filter(c => c.parent === parentId)
}
/** The screen and the screens above it, outermost first, for a breadcrumb. */
export function helpContextTrail(context: HelpContext): HelpContext[] {
const trail: HelpContext[] = [context]
let parent = context.parent ? HELP_CONTEXTS.get(context.parent) : undefined
while (parent && !trail.includes(parent)) {
trail.unshift(parent)
parent = parent.parent ? HELP_CONTEXTS.get(parent.parent) : undefined
}
return trail
}
// ── Catalogue keys ──────────────────────────────────────────────────────────
export const ctxKey = (id: string, part: 'title' | 'summary'): string => `help.ctx.${id}.${part}`
export const ctxBulletKey = (id: string, n: number): string => `help.ctx.${id}.bullet.${n}`
export const guideKey = (id: string, part: 'title' | 'goal' | 'result' | 'link'): string =>
`help.guide.${id}.${part}`
export const guideStepKey = (id: string, n: number): string => `help.guide.${id}.step.${n}`
export const guideTipKey = (id: string, n: number): string => `help.guide.${id}.tip.${n}`
// ── Media paths ─────────────────────────────────────────────────────────────
/**
* Generated artwork under `public/help-media/`. WebP and WebM on purpose: the
* service worker precaches `png`, and a couple of hundred help pictures do not
* belong in every visitor's first download.
*/
const MEDIA_BASE = '/help-media'
export const helpMedia = {
hero: (contextId: string): string => `${MEDIA_BASE}/ctx/${contextId}.webp`,
step: (guideId: string, n: number): string => `${MEDIA_BASE}/${guideId}/step-${n}.webp`,
result: (guideId: string): string => `${MEDIA_BASE}/${guideId}/result.webp`,
clip: (guideId: string, n: number): string => `${MEDIA_BASE}/${guideId}/step-${n}.loop.webp`,
}
/** Wiki route for a doc link, with the heading anchor when the link names one. */
export function docsRoute(link: { slug: string; anchor?: string }): string {
return `/help/${link.slug}${link.anchor ? `#${link.anchor}` : ''}`
}
+3 -8
View File
@@ -4,11 +4,9 @@ import { render, screen, waitFor, cleanup, within } from '../../tests/helpers/re
import userEvent from '@testing-library/user-event';
import { http, HttpResponse } from 'msw';
import { server } from '../../tests/helpers/msw/server';
import { resetAllStores, seedStore } from '../../tests/helpers/store';
import { useAddonStore } from '../store/addonStore';
import { resetAllStores } from '../../tests/helpers/store';
import { seedJourneyOwner } from '../../tests/helpers/journeyDetail';
import { buildUser } from '../../tests/helpers/factories';
import { useAuthStore } from '../store/authStore';
import { usePermissionsStore } from '../store/permissionsStore';
import { useJourneyStore } from '../store/journeyStore';
import JourneyDetailPage from './JourneyDetailPage';
@@ -239,10 +237,7 @@ beforeEach(() => {
vi.clearAllMocks();
resetAllStores();
useJourneyStore.setState(useJourneyStore.getState(), true);
seedStore(useAuthStore, { isAuthenticated: true, user: ownerUser });
seedStore(usePermissionsStore, { level: 'owner' } as any);
// A photo provider on for the install, so the entry editor offers External photos.
seedStore(useAddonStore, { addons: [{ id: 'immich', name: 'Immich', type: 'photo_provider', enabled: true } as never] });
seedJourneyOwner(ownerUser);
setupDefaultHandlers();
});
+17
View File
@@ -0,0 +1,17 @@
import { useAddonStore } from '../../src/store/addonStore';
import { useAuthStore } from '../../src/store/authStore';
import { usePermissionsStore } from '../../src/store/permissionsStore';
import type { User } from '../../src/types';
import { seedStore } from './store';
/**
* The install the journey page suite runs on: the owner is signed in with full
* rights, and a photo provider is on, so the entry editor offers External photos.
*/
export function seedJourneyOwner(user: User): void {
seedStore(useAuthStore, { isAuthenticated: true, user });
seedStore(usePermissionsStore, { level: 'owner' } as never);
seedStore(useAddonStore, {
addons: [{ id: 'immich', name: 'Immich', type: 'photo_provider', enabled: true } as never],
});
}