# Module group: `mission-planner/` > **Single consolidated doc** for the entire `mission-planner/` sub-project (37 modules across `services/`, `flightPlanning/`, `icons/`, `constants/`, `types/`, `utils.ts`, `config.ts`, `main.tsx`, `App.tsx`). > > **Why a single doc**: `mission-planner/` is **port-source, not deployed product** (per workspace `README.md` + `00_discovery.md §1`). The Dockerfile builds only the workspace `src/`. Documenting each of the 37 files at the same fidelity as the production SPA would burn context for code that exists only as a reference for the React-19 port. Future deletion of `mission-planner/` is a Step 8 / autodev follow-up once `src/features/flights/` reaches feature-parity. ## Role in the codebase | Aspect | Status | |---|---| | Purpose | Reference implementation of the flight-mission planner UI being mechanically translated into `src/features/flights/`. Stand-alone CRA-flavoured Vite + React 18 + MUI 5 app. | | Build | Has its own `vite.config.ts`, `tsconfig`, `index.html`, `package.json`. No alias path. | | Deployment | None — workspace `Dockerfile` does NOT build it; `nginx.conf` does NOT serve it. | | Tests | `src/test/jsonImport.test.ts` uses `describe/it/expect` style; **Jest is not installed** and there is no `test` script — the test cannot run as-is. Documented gap, no fix planned (out of scope per `00_discovery.md §11.5`). | | Lifecycle | Will be deleted once `src/features/flights/` covers all mission-planner features. Not before. | ## Directory map ``` mission-planner/src/ ├── main.tsx → mounts into #root ├── App.tsx UNUSED — empty CRA stub; main.tsx mounts FlightPlan directly ├── config.ts COORDINATE_PRECISION, downang, upang, defaults ├── utils.ts newGuid (Math.random v4) ├── types/index.ts FlightPoint, CalculatedPointInfo, MapRectangle, AircraftParams, │ WeatherData, MovingPointInfo, ActionMode, MapType, large │ TranslationStrings interface tree ├── constants/ │ ├── actionModes.ts points / workArea / prohibitedArea │ ├── maptypes.ts classic / satellite │ ├── tileUrls.ts OSM + Esri ArcGIS tile URLs │ ├── translations.ts English + Ukrainian dictionaries (raw, no i18next) │ ├── languages.ts ISO codes + flag codes for LanguageSwitcher │ └── purposes.ts tank, artillery ├── services/ │ ├── calculateDistance.ts Haversine + plane climb/cruise/descend │ ├── AircraftService.ts mockGetAirplaneParams (returns hardcoded fixed-wing) │ ├── WeatherService.ts OpenWeatherMap fetch (env-vars: VITE_OWM_API_KEY + VITE_OWM_BASE_URL; fail-soft `null` when key unset, AZ-499) │ └── calculateBatteryUsage.ts Drag + thrust lookup; same algorithm as src/features/flights/flightPlanUtils.calculateBatteryPercentUsed ├── icons/ │ ├── MapIcons.tsx Leaflet icon factories │ ├── PointIcons.tsx Per-purpose marker icons │ ├── SidebarIcons.tsx MUI-styled side-panel SVGs │ └── PhoneIcon.tsx Rotate-phone overlay (mobile orientation hint) └── flightPlanning/ ├── flightPlan.tsx Top-level page (369 lines) — owns state, dialogs, JSON I/O ├── MapView.tsx MapContainer + draw handlers + click-to-add (414 lines) ├── MiniMap.tsx Floating thumbnail; cyclic edge with MapView ├── MapPoint.tsx Draggable waypoint + popup ├── DrawControl.tsx Rectangle draw tool ├── PointsList.tsx Reorderable waypoint list ├── LeftBoard.tsx Side panel composing list + chart + totals + lang switcher ├── AltitudeChart.tsx Chart.js altitude visualizer ├── AltitudeDialog.tsx Add/Edit waypoint modal ├── JsonEditorDialog.tsx Edit-as-JSON modal ├── TotalDistance.tsx Total distance + time + battery readout ├── LanguageContext.tsx React Context for current locale (NOT i18next) ├── LanguageSwitcher.tsx Locale dropdown ├── WindEffect.tsx Wind heading / speed inputs + arrow preview └── Aircraft.ts Aircraft helper (filename casing odd — TypeScript file, capitalised) ``` ## Mapping `mission-planner/` ↔ `src/features/flights/` The React 19 port translates module-for-module wherever possible. Status as of this commit: | `mission-planner/src/...` | Ported to `src/features/flights/...` | Status | |---|---|---| | `flightPlanning/flightPlan.tsx` | `FlightsPage.tsx` | Ported with backend wiring (Flights API + SSE). MP-side has none. | | `flightPlanning/MapView.tsx` | `FlightMap.tsx` | Ported. | | `flightPlanning/MiniMap.tsx` | `MiniMap.tsx` | Ported. | | `flightPlanning/MapPoint.tsx` | `MapPoint.tsx` | Ported. | | `flightPlanning/DrawControl.tsx` | `DrawControl.tsx` | Ported. | | `flightPlanning/PointsList.tsx` | `WaypointList.tsx` | Ported (renamed for parity with backend `Waypoint` entity). | | `flightPlanning/LeftBoard.tsx` | `FlightParamsPanel.tsx` | Partial — MP-side hosts `LanguageSwitcher`, the SPA delegates language to global `Header` + `react-i18next`. | | `flightPlanning/AltitudeChart.tsx` | `AltitudeChart.tsx` | Ported. | | `flightPlanning/AltitudeDialog.tsx` | `AltitudeDialog.tsx` | Ported (file name kept; should be `WaypointDialog`). | | `flightPlanning/JsonEditorDialog.tsx` | `JsonEditorDialog.tsx` | Ported. | | `flightPlanning/WindEffect.tsx` | `WindEffect.tsx` | Ported. | | `flightPlanning/TotalDistance.tsx` | (inlined into `FlightParamsPanel`) | Ported as a `
` strip in the params panel; no separate module. | | `flightPlanning/LanguageContext.tsx` + `LanguageSwitcher.tsx` | (replaced by `react-i18next`) | Not ported as such — language is global via i18next. | | `flightPlanning/Aircraft.ts` | (no equivalent) | Aircraft is server-side; the SPA fetches `/api/flights/aircrafts`. | | `services/calculateDistance.ts` | `flightPlanUtils.calculateDistance` | Ported. | | `services/calculateBatteryUsage.ts` | `flightPlanUtils.calculateBatteryPercentUsed` + `calculateAllPoints` | Ported. | | `services/WeatherService.ts` | `flightPlanUtils.getWeatherData` | Ported. Env-vars `VITE_OWM_API_KEY` + `VITE_OWM_BASE_URL` since AZ-499 (mirrors AZ-448 / AZ-449); same fail-soft `null` contract. | | `services/AircraftService.ts` | `flightPlanUtils.getMockAircraftParams` (mock only) | Real fetch is `/api/flights/aircrafts` in `FlightsPage`. | | `constants/translations.ts` + `LanguageContext.tsx` | `src/i18n/{en,ua}.json` + `i18n/i18n.ts` | Migrated to i18next. | | `constants/{actionModes,maptypes,tileUrls,purposes,languages}.ts` | `features/flights/types.ts` (`PURPOSES`, `TILE_URL`, `ActionMode`) | Consolidated into one file. `TILE_URL` collapsed from the prior classic/satellite pair to a single self-hosted satellite URL by AZ-498. | | `icons/{MapIcons,PointIcons,SidebarIcons,PhoneIcon}.tsx` | `features/flights/mapIcons.ts` | Only the marker icons survived; SidebarIcons + PhoneIcon dropped (no rotate-phone overlay in the SPA today). | | `utils.ts` (`newGuid`) | `flightPlanUtils.newGuid` | Ported. | | `config.ts` | `features/flights/types.COORDINATE_PRECISION` | Single constant migrated. | | `App.tsx` | (none) | Was already an unused CRA stub in MP; nothing to port. | | `main.tsx` | (none) | Replaced by the workspace `src/main.tsx`. | | `setupTests.ts`, `test/jsonImport.test.ts` | (none) | Cannot run; not migrated. | ## Things still in MP that are NOT in the SPA port - **Rotate-phone overlay** (`icons/PhoneIcon.tsx`): MP shows a rotate-phone hint when held in portrait. The SPA does not. - **Per-purpose marker icons** (`icons/PointIcons.tsx`): MP draws a different marker per `meta` purpose. The SPA uses three colour-coded icons (start / mid / end). - **`Aircraft.ts` helper class**: never used in the SPA — aircraft state is fetched and treated as a plain DTO. - **OpenWeather call directly from `WeatherService.ts`**: same flaw as the SPA port (no proxy). Hardcoded key fixed by AZ-499 (env-vars + fail-soft); proxy story still owned by the broader F1 mission-planner deduplication track. - **MUI 5**: MP uses MUI for dialogs / inputs / icons. The SPA replaced everything with hand-rolled Tailwind components matching `_docs/ui_design/README.md`. MUI is not a dep of the workspace. ## Findings carried into Step 4 / 6 / 8 1. **`mission-planner/src/App.tsx` is an unused CRA stub** — `main.tsx` mounts `FlightPlan` directly. Deletion candidate but only after the port is complete (per `00_discovery.md §11.6`). Step 8. 2. **`mission-planner/src/test/jsonImport.test.ts` cannot run** (Jest not installed; no test script). Out of scope. Step 8 deletion or migration to the suite-level e2e harness. 3. **`flightPlanning/MapView.tsx ↔ MiniMap.tsx`** import each other (`MiniMap` imports the *named* `UpdateMapCenter` helper from `MapView`; `MapView` imports `MiniMap` as a JSX child). Module-level execution is non-circular because each side only uses the type/handle exposed at call time. Ported to `src/features/flights/FlightMap.tsx + MiniMap.tsx` without the cycle. 4. **MP uses raw translation tables** keyed by ISO code, not i18next. The SPA correctly migrated to `react-i18next`; the legacy Russian-language references (if any in `translations.ts`) are out of scope. 5. **`mission-planner/.env.example`** declares `VITE_SATELLITE_TILE_URL` — same env-driven pattern that the workspace `src/` should adopt for the Esri tile URL (currently hardcoded). Carry idea to Step 4. 6. **`mission-planner/package.json`** lockfile is uncommitted (`bun.lock` is workspace-only; MP uses npm without a committed lock). Reproducibility risk if anyone runs MP. Step 8 — when MP is deleted this becomes moot. 7. **Dependency divergence**: MP uses `react-leaflet` 4.2 vs workspace 5.x; `@hello-pangea/dnd` 16 vs 18; `chart.js` shared. None of this affects the deployed bundle. Step 8 — delete MP. ## Tests The single `jsonImport.test.ts` cannot run. None of the other 36 modules have tests. ## Cross-doc references - `_docs/02_document/00_discovery.md §1, §2b, §7b, §10, §11` — discovery-level facts about MP. - Workspace `README.md` — declares MP as not-deployed. - `mission-planner/README.md` — stale CRA boilerplate, do not trust. - The 14 `src/features/flights/` modules — see consolidated `src__features__flights.md`.