Two small UX wins on top of the previous control-panel fixes:
1. Rename admin_level options to "World" / "Country" / "Aggregated
regions" (from the technical "Countries (Admin 0)" / "Subdivisions
(Admin 1)"). The control's own label becomes "Map view" with an
explanatory description. Underlying form_data values stay 0 / 1 /
aggregated so saved charts don't break.
2. Auto-migrate form_data when a user switches a saved legacy
country_map chart's viz type to country_map_v2:
- select_country: 'france' → admin_level=1, country=FRA
- select_country: 'france_overseas' → composite=france_overseas
- select_country: 'turkey_regions' → admin_level=aggregated,
country=TUR, region_set=nuts_1
- …same pattern for france_regions / italy_regions /
philippines_regions and ~180 other legacy country files.
The mapping lives in src/plugin/migrateFromLegacy.ts (covered by
12 unit tests). Migration only fills fields the user hasn't already
set on the new chart, so explicit edits win over inferred values.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Four UX bugs reported on the new country map chart:
1. **"Country: cannot be empty" stuck on the Data tab even at Admin 0.**
The Country control had a hard `validators: [validateNonEmpty]`, but
it's only rendered (and only meaningful) when admin_level != 0 and no
composite is set. The validator was firing for the hidden empty value
and trapped the user — the Update Chart button was permanently
disabled with no visible control to satisfy. Switched to a dynamic
validator via mapStateToProps so it only fires when the field is
actually needed.
2. **"Aggregated regions" threw TypeError: t.map is not a function.**
The region_set control used `choices: ({ controls }) => ...`, but
SelectControl's `choices` must be a literal array. Moved the
country-dependent choice computation into `mapStateToProps` (same
pattern other plugins use).
3. **Composite map always visible and "sticky" overriding admin_level.**
At Admin 0 (world choropleth) the composite override produced a map
that didn't change when you toggled admin_level. Hidden composite
control at Admin 0 entirely, and hidden it whenever the build
pipeline didn't emit any composites — leaves room for future
per-country scoping (e.g. only show france_overseas when country=FRA).
4. **Show flying islands checkbox was a no-op.** The build pipeline
doesn't currently tag features as flying, so the runtime drop logic
had nothing to act on. Removed from the control set rather than ship
a misleading control; a single line brings it back once the build
tags features.
Tests updated to cover all four behaviors.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Previously the build only emitted the ukr (Ukraine) worldview, so the
worldview dropdown had a single option even though it claimed otherwise.
Build now produces Admin 0 GeoJSON for every NE-published editorial:
default, arg, bdg, bra, chn, deu, egy, esp, fra, gbr, grc, idn, ind, iso,
isr, ita, jpn, kor, mar, nep, nld, pak, pol, prt, pse, rus, sau, swe, tur,
twn, ukr, usa, vnm (33 total).
NE does not publish per-worldview Admin 1 variants, so subdivisions within
a country come from a single shared file. The frontend now always points
Admin 1, regional aggregation, and composite URLs at the ukr-prefixed
shared outputs regardless of the selected worldview — the worldview
control only affects the world (Admin 0) map.
- build.py: expand WORLDVIEWS_ADMIN_0 to 33 worldviews; main() builds
Admin 0 for all of them, Admin 1 only for ukr
- transformProps.ts: introduce SHARED_ADMIN1_WORLDVIEW = 'ukr'; pin all
non-Admin-0 URLs to it
- controlPanel.tsx: WORLDVIEW_LABELS now covers all 33 codes; unrecognized
codes still fall back to raw code for forward-compat
- transformProps.test.ts: cover shared-Admin1 contract (admin1+chn still
resolves to ukr_admin1_*)
- pre-commit: exclude .geo.json from check-added-large-files (existing
rule only excluded .geojson and would block these ~2MB worldview files)
- README + SIP: document the worldview model and check off Phase 1 item
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Completes the test trio (transformProps + buildQuery + controlPanel).
Verifies:
- All 9 new controls (worldview / admin_level / country / region_set /
composite / region_includes / region_excludes / show_flying_islands /
name_language) are present in the panel
- Worldview defaults to 'ukr' (Superset's editorial choice)
- show_flying_islands defaults to true
- name_language defaults to 'en'
- admin_level offers exactly the 3 expected codes
- Country selector visibility hides on Admin 0 OR when composite set
- Region-set selector only visible when admin_level === 'aggregated'
- Region-set choices key off the selected country (TUR → nuts_1,
FRA → regions, USA → empty)
- Composite selector exposes france_overseas
These tests would fail loudly if anyone refactored the visibility
predicates or accidentally removed/renamed a control.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
transformProps tests cover the URL-derivation logic — the core piece
that maps form_data into the right build-pipeline output:
- Admin 0 + worldview → world choropleth URL
- Admin 1 + country → per-country file
- Region set + country → regional aggregation
- Composite overrides admin level + country
- Worldview defaults to 'ukr' when not specified
- Different worldviews reflected in URL
- Admin 1 without country → null URL (chart UI prompts)
- Pass-through of metricName/numberFormat/linearColorScheme
- Pass-through of query data + width/height
buildQuery tests cover that we're producing a valid chart/data
QueryContext with the expected shape (one query, form_data preserved,
orderby normalized as array).
These are the units most likely to break silently if someone refactors
the form_data → URL mapping or the query layer.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>