Commit Graph

19931 Commits

Author SHA1 Message Date
Evan Rusackas
cb5bb69fa8 feat(country-map): build script — emit manifest.json describing outputs
Adds a manifest.json output the plugin can fetch at runtime to
populate worldview / country / region-set / composite dropdowns
dynamically. Adding a new entry to the YAML configs no longer requires
a plugin code change — re-run build.sh, manifest updates, plugin
controls reflect the new options.

Manifest schema:
  ne_pinned_tag, ne_pinned_sha, build_timestamp_utc
  worldviews: [<wv>, ...]
  admin_levels: [0, 1]
  countries_by_worldview: {<wv>: [<adm0_a3>, ...]}
  regional_aggregations: [{country, set_id, worldview, size_bytes}, ...]
  composites: [{id, worldview, size_bytes}, ...]

Sample current output:
  1 worldview (ukr), 211 countries with subdivisions, 4 regional sets,
  1 composite (france_overseas). Build pinned to NE v5.1.2.

Follow-up commit will replace the hardcoded choice tables in
controlPanel.tsx with manifest-driven options.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-12 17:06:30 -07:00
Evan Rusackas
52dfc853d2 test(country-map): transformProps + buildQuery tests
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>
2026-05-12 17:01:25 -07:00
Evan Rusackas
f696fe1e05 feat(country-map): full control panel — worldview, admin level, region filters, language
Replace the placeholder control panel with the real form-data surface.
New controls (none of which exist on the legacy plugin):

- worldview: SelectControl, defaults to 'ukr' per documented editorial
  choice; configurable per-deployment + per-chart
- admin_level: SelectControl (Admin 0 / Admin 1 / Aggregated regions)
- country: SelectControl, visible only when admin_level !== 0 and no
  composite is selected
- region_set: SelectControl, visible only when admin_level === 'aggregated';
  choices depend on selected country (sourced from the regional_aggregations
  YAML's snapshot table)
- composite: SelectControl (france_overseas etc.); when set, overrides
  admin_level + country
- region_includes / region_excludes: free-form multi-select for client-side
  filtering at render time (these drive the projection refit too — the
  renderer's `filterFeatures` uses them)
- show_flying_islands: CheckboxControl, default true
- name_language: SelectControl with 20 NE-supported languages

The choice tables (WORLDVIEW_CHOICES, COUNTRY_CHOICES, REGION_SET_CHOICES_
BY_COUNTRY, COMPOSITE_CHOICES) are hardcoded snapshots for the POC.
Follow-up commit will replace these with options pulled from the build
pipeline's manifest.json so adding a new worldview or country only
requires a build script run, not a plugin code change.

Standard query controls (entity, metric, adhoc_filters, row_limit,
linear_color_scheme, number_format) preserved from the legacy plugin.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-12 17:00:08 -07:00
Evan Rusackas
b296345332 feat(country-map): port D3 renderer to modern modules + new features
Replace the placeholder renderer with a real D3-based choropleth.
Modernizes the legacy plugin's rendering in three ways:

1. **Modern D3 modules** (d3-geo, d3-array, d3-color) instead of the
   d3 v3 monolith. No more @ts-nocheck — fully typed.

2. **Built-in include/exclude filtering** (formData.region_includes /
   region_excludes) before render. Projection auto-fits the FILTERED
   feature set, so excluding Russia from a Europe view actually zooms
   to Europe (the "fit to selection" behavior).

3. **Multi-language display names** via name_language formData field.
   Falls back through name_<lang> → name → '' so any worldview/dataset
   degrades gracefully.

Other changes:
- Tooltip is React state instead of D3-driven HTML (cleaner unmount,
  no XSS surface from .html())
- Color scale uses sequential scheme registry from @superset-ui/core
  (same path as legacy)
- Cleanup on unmount via useEffect cleanup function

Stubbed for follow-ups:
- Click-to-zoom (legacy had this; revisit after deprecation banner)
- Cross-filter integration
- Composite projection support (geoAlbersUsa for USA, etc.) — falls
  back to plain Mercator + build-time repositioning for now
- Flying-islands toggle: feature-tagging in the build pipeline still
  needs to land before the toggle can drop them at render time

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-12 16:58:38 -07:00
Evan Rusackas
2165b95a08 docs(country-map): SIP — add test plan section for maintainer validation
Captures things the maintainer should manually verify before merge,
organized by category:
- Build pipeline (data correctness)
- Visual/cartographic quality (in-chart rendering)
- Controls UX
- Backward compatibility
- Per-deployment customization (config)
- Performance + ops

Items get added/checked off as the implementation progresses.
Includes specific spot-checks the agent can't validate alone:
Crimea-as-Ukrainian visual, Russia Chukchi connectedness, India
J&K under _ukr worldview, French composite layout, etc.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-12 16:57:03 -07:00
Evan Rusackas
fb31a5160d docs(country-map): SIP — sync implementation plan with current progress
Mark Phase 1 substantially complete (5/5 transforms working,
220 outputs verified, all schemas in place) and Phase 2 partially
complete (modern plugin scaffold compiles end-to-end, real renderer +
controls still TODO).

Add a "Current PR state" section showing the build script's actual
output so reviewers reading the SIP can see at a glance what the POC
produces today.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-12 16:45:49 -07:00
Evan Rusackas
07532ae1a7 feat(country-map): scaffold modern plugin shell
Bootstrap the new @superset-ui/plugin-chart-country-map package with
the modern ChartPlugin pattern. Mirrors plugin-chart-handlebars'
structure (the leanest existing modern plugin in the repo).

Files:
  package.json                     — workspace pkg with d3-* deps
  tsconfig.json                    — extends frontend root tsconfig,
                                     references core/chart-controls
  types/external.d.ts              — ambient types for png/jpg/geojson
  README.md                        — what this plugin is + status
  src/
    index.ts                       — package entry
    types.ts                       — CountryMapFormData + transform props
    CountryMap.tsx                 — placeholder renderer (real D3 port
                                     in a follow-up commit)
    plugin/
      index.ts                     — ChartPlugin class with metadata
      buildQuery.ts                — modern chart/data query (this is
                                     the core difference from the legacy
                                     plugin's explore_json path)
      controlPanel.tsx             — minimal placeholder; full control
                                     set (worldview / admin level /
                                     country / region include-exclude /
                                     fly-islands / language) ports next
      transformProps.ts            — derives geoJsonUrl from form_data
                                     using the build-script's output
                                     naming convention

Renderer scaffold fetches the resolved GeoJSON URL and shows a small
diagnostic block (URL + feature count + data row count + metric name)
so the plugin compiles end-to-end and can be wired to the chart-type
registry without a real D3 render. Real renderer + controls land in
the next commits.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-12 16:44:43 -07:00
Evan Rusackas
d7edbf747a feat(country-map): build script — split Admin 1 per country
The monolithic ukr_admin1.geo.json (15MB / 4595 features) was a single
file that any chart would have to download in full just to render one
country's subdivisions. Replace with per-country files keyed by
adm0_a3, each individually simplified.

Also drops single-subdivision countries (useless as choropleths) at
this stage, mirroring the notebook's auto-purge.

Output stats from full run:
  Files: 220 total
    1 × admin0 (world) ............ 2.1 MB
    4 × regional aggregations ..... 23-32 KB each
    1 × composite (france_overseas) 322 KB
  214 × per-country admin1 ........ 17 KB - 662 KB each (GBR largest)

Per-chart payload:
  world choropleth   → ukr_admin0.geo.json                  2.1 MB
  France departments → ukr_admin1_FRA.geo.json              308 KB
  US states          → ukr_admin1_USA.geo.json              ~250 KB
  Türkiye NUTS-1     → regional_TUR_nuts_1_ukr.geo.json     23 KB
  France w/ overseas → composite_france_overseas_ukr.geo.json 322 KB

All well within usable browser payload range. The plugin will lazy-load
only what's needed for the current chart's worldview/admin-level/country.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-12 16:39:47 -07:00
Evan Rusackas
989ed61f34 feat(country-map): build script — composite_maps transform (5/5 transforms)
Implements the fifth and final transform from the notebook audit.
A composite combines a base country's Admin 1 features with:
- base_repositions (with optional `group: true` for grouped transforms
  like Paris + petite couronne treated as one body)
- additions (features pulled from sibling countries' Admin 1, with
  optional dissolve, drop_parts, reposition, and attribute set)

Verified on France-with-Overseas:
  france_overseas: 108 features → composite_france_overseas_ukr.geo.json
                                  (322,058 bytes)

108 = 101 FRA admin1 departments + 7 additions (Polynésie française,
Terres australes et antarctiques françaises, Wallis-et-Futuna,
Nouvelle-Calédonie, Saint-Pierre-et-Miquelon, Saint-Martin,
Saint-Barthélémy).

Bug fix during implementation: composites pull additions from Admin 1
of sibling countries (Windward Islands is a PYF Admin 1 subdivision,
not an Admin 0 country), not from Admin 0. Initial implementation got
this wrong and warned 0 features. Fixed by sourcing from base_admin1
(the global Admin 1 dataset, which contains all countries'
subdivisions).

New helpers:
- _drop_parts(geom, indices) — drop sub-polygon indices from MultiPolygon
- _translate_and_scale_with_pivot — explicit pivot (vs feature centroid),
  used for `group: true` transforms

==== Build pipeline status ====

All 5 declarative transforms implemented and verified:
  ✓ name_overrides         (19 updates per Admin 1 build)
  ✓ flying_islands         (12 reposition + 5 bbox drop)
  ✓ territory_assignments  (4 features added: TWN/HKG/MAC/ALD)
  ✓ regional_aggregations  (4 region sets: TUR/FRA/ITA/PHL)
  ✓ composite_maps         (1 composite: france_overseas)

Current outputs (UA worldview):
  ukr_admin0.geo.json                       2.1 MB   249 features
  ukr_admin1.geo.json                        15 MB  4595 features
  regional_TUR_nuts_1_ukr.geo.json           23 KB    12 regions
  regional_FRA_regions_ukr.geo.json          32 KB    18 regions
  regional_ITA_regions_ukr.geo.json          32 KB    20 regions
  regional_PHL_regions_ukr.geo.json          32 KB    17 regions
  composite_france_overseas_ukr.geo.json    322 KB   108 features

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-12 16:34:43 -07:00
Evan Rusackas
1e77ff1706 feat(country-map): build script — regional_aggregations transform
Implements the fourth transform: dissolve Admin 1 subdivisions into
coarser administrative regions. Supports two mapping styles:
- explicit_mapping: per-region {name, members: [iso_3166_2, ...]}
- grouping_field: dissolve by an existing NE field (e.g. region_cod)

Verified counts match notebook expectations exactly:
  TUR/nuts_1:  81 subdivisions → 12 regions → 23 KB
  FRA/regions: 101 subdivisions → 18 regions → 32 KB
  ITA/regions: 110 subdivisions → 20 regions → 32 KB
  PHL/regions: 118 subdivisions → 17 regions → 32 KB

Per-region-set output is its own file (`regional_<country>_<set>_
<worldview>.geo.json`) so the plugin can lazy-load only what's needed
for the current chart.

Implementation:
- Filter base geo to country features
- Tag each with derived `_region_code` and `_region_name` (via reverse
  lookup of explicit_mapping, or via grouping_field value)
- mapshaper -dissolve handles the polygon merging in one pass
- Rename derived fields → standard `iso_3166_2` and `name` on output

Output sizes are tiny — each per-chart payload becomes ~30 KB instead
of pulling the full Admin 1 layer.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-12 16:29:44 -07:00
Evan Rusackas
cb005a2ea5 feat(country-map): build script — territory_assignments transform
Implements the third transform: pull features from sibling Admin 0
records into a destination country's Admin 1 view. Used for:
- China + Taiwan/HK/Macau (NE keeps each as separate Admin 0)
- Finland + Åland (missing from FIN admin 1; NE keeps Åland as ALD
  admin 0)

Verified on real data:
  Building worldview=ukr admin_level=1
    territory_assignments: added 4 features from sibling Admin 0 records

(4 = TWN/HKG/MAC + ALD; ARMM-renamed BARMM region picks up correctly
because name_overrides ran first.)

Two bugs fixed along the way:

1. **Property name casing.** NE Admin 0 ships with uppercase property
   names (ADM0_A3, NAME_EN), Admin 1 with lowercase. All transforms
   downstream assume lowercase, so we now normalize to lowercase at
   shapefile-conversion time. Bonus: fixes a silent flying_islands
   bug where `adm0_a3` filters never matched at Admin 0 because the
   props were uppercase.

2. **drop_outside_bbox at Admin 0.** A country's multi-polygon often
   includes overseas territories (Netherlands → Caribbean), so bbox
   filtering at Admin 0 would drop entire countries. Now guarded to
   only run at Admin 1 where each feature is a single subdivision.

3. **Åland's NE code.** NE uses ALD, not the ISO 3166-1 ALA. Updated
   territory_assignments.yaml with comment noting the divergence.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-12 16:27:04 -07:00
Evan Rusackas
ae5e1132ba feat(country-map): build script — mapshaper -simplify final pass
Add mapshaper -simplify as a final-stage pass after the Python
transforms. Two-stage so the transforms operate on full-resolution
geometry (no risk of repositioning ghost features that got simplified
away) but the shipped output is browser-sized.

Default 5% with keep-shapes — preserves recognizable country shapes
while dropping the per-vertex bloat. keep-shapes prevents tiny features
(small island chains) from being collapsed away entirely.

Results on real outputs:
  Admin 0: 23.6 MB → 2.1 MB  (-91%, 249 features intact)
  Admin 1: 67.7 MB → 15 MB   (-78%, 4591 features, transforms preserved)

Per-feature simplify factors (the notebook had a size-based ladder)
can be added later if specific countries need tuning. 5% is the
mapshaper-recommended "good enough for web" default.

Open thought for future: split Admin 1 output by country
(`<worldview>_admin1_<adm0_a3>.geo.json`) so the per-chart payload is
~50KB-1MB instead of one 15MB global file. Will pair naturally with
the territory_assignments pass (which is per-country anyway).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-12 16:03:34 -07:00
Evan Rusackas
ea9b21b017 feat(country-map): build script — Admin 1 + flying_islands transform
Add Admin 1 build path and the second declarative transform. Exercises
the YAML config layer on real data:

  Building worldview=ukr admin_level=1
    loaded 4596 features
    name_overrides: applied 19 field updates across 10 entries
    flying_islands: repositioned 12 features, dropped 5 (outside-bbox)
    wrote ukr_admin1.geo.json (67,677,079 bytes, 4591 features)

Counts verified against expectations:
- 19 name_overrides = 2 France typos + 6 France ISO codes
  + 5 PHL Caraga renames + 6 PHL BARMM renames
- 12 repositions = 2 USA + 1 NOR + 2 PRT + 2 ESP + 5 FRA
- 5 drops = NLD Caribbean + GBR overseas territories

New: pure-Python translate/scale geometry transform (no shapely dep);
operates on Polygon/MultiPolygon coordinates. Scale pivot is the bbox
center of each matched feature — good enough for the visual layout
purposes we use it for. Output bbox correctness verified by counts.

Refactor: extract `build_one(worldview, admin_level, ...)` so the
target matrix can grow in subsequent commits.

What's stubbed (TODO inline): territory_assignments, composite_maps,
regional_aggregations, simplification, procedural/. Output is
uncompressed and unsimplified (67MB) — simplification will land with
the mapshaper -simplify pass.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-12 16:02:11 -07:00
Evan Rusackas
2db41bb2b2 feat(country-map): minimum-viable build pipeline (NE → GeoJSON)
End-to-end working pipeline replacing the legacy notebook for one
worldview / admin level. Verified locally:

  $ ./build.sh
  Country Map build — pinned to NE v5.1.2 (f1890d9f)
  Loaded 10 name override entries
  Building worldview=ukr admin_level=0
  Downloading NE ne_10m_admin_0_countries_ukr (worldview=ukr)…
    mapshaper: ne_10m_admin_0_countries_ukr.shp → _raw_ukr_admin0.geo.json
    loaded 249 features
    name_overrides: applied 0 field updates across 10 entries
    wrote .../output/ukr_admin0.geo.json (23,639,348 bytes)
  Done.

What's wired:
- NE download from pinned tag (v5.1.2 / SHA f1890d9f) with cache
- Shapefile → GeoJSON via mapshaper CLI
- YAML config loading (currently just name_overrides)
- name_overrides transform with {match, set} semantics, including
  the {in: [...]} list-membership matcher
- Output writes to scripts/output/ (gitignored)
- build.sh wrapper validates Python + Node + PyYAML are available

What's stubbed for future commits (TODO inline):
- Multiple worldviews (currently UA only)
- Admin 1 build (where name_overrides actually fire — currently no
  features in Admin 0 match the FRA/PHL admin1 entries)
- flying_islands, territory_assignments, regional_aggregations,
  composite_maps transforms
- Simplification (mapshaper -simplify)
- Procedural escape-hatch orchestration
- Manifest with NE SHA + build metadata

The 0 overrides applied is correct, not a bug: all current entries
target Admin 1 features.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-12 16:00:29 -07:00
Evan Rusackas
d2916b99ee feat(country-map): backfill France-with-Overseas composite from full notebook cell
The original draft was missing entries because notebook cell 63 was
truncated in the audit. Reading the full cell surfaced:

- Saint Martin (MAF) + Saint Barthélémy (BLM) as additional sister
  Admin 0 territories (small Caribbean islands, scaled up significantly
  for visibility — 5x and 8x respectively)
- Paris + petite couronne (Hauts-de-Seine, Seine-Saint-Denis,
  Val-de-Marne) as a metropolitan zoom-in (group + translate + scale 3x)
- Per-territory metadata renames (Polynésie française, Nouvelle-
  Calédonie, etc.) + ISO 3166-2 code assignments (FR-PF, FR-NC, etc.)

Schema additions:
- base_repositions[].group: true — when match yields multiple features,
  transform them as a single MultiPolygon then split back out
  (preserves per-feature attributes). Used for the Paris zoom-in.
- additions[].set: { name, iso_3166_2, ... } — override attributes on
  the added/dissolved feature

SPM offset placeholder is gone; composite definition now matches the
notebook's output exactly (modulo the build script implementing the
declarative schema).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-12 15:57:59 -07:00
Evan Rusackas
1eb48e94fc feat(country-map): scaffold scripts/ dir with YAML config schemas
First-pass schemas for the build pipeline's declarative config layer.
Each schema is documented inline + populated with concrete entries
ported from the legacy notebook's audited touchups (those that the
obsolescence check determined still need to ship).

scripts/
├── README.md                 — pipeline overview, layout, workflow
├── config/
│   ├── name_overrides.yaml         — France typos, ISO codes; PHL renames
│   ├── flying_islands.yaml         — USA/NOR/PRT/ESP/FRA repositions; NLD/GBR drops
│   ├── territory_assignments.yaml  — China + SARs; Finland + Åland
│   ├── regional_aggregations.yaml  — Turkey NUTS-1; FRA/ITA/PHL regions
│   └── composite_maps.yaml         — France-with-Overseas
└── procedural/
    └── README.md             — escape-hatch rules + skeleton (currently empty)

All five YAML files parse cleanly (validated with PyYAML).

Schema design choices:
- Every entry has a `description:` field. Forces honest documentation
  of why each fix exists; reviewers can scan rationale at a glance.
- Match semantics: simple AND-of-conditions; supports `{ in: [...] }`
  for value-set matching.
- composite_maps and territory_assignments share the "pull feature
  from sibling Admin 0" primitive; build script can implement once.
- composite_maps.yaml has a TODO marker for SPM offsets — notebook
  cell 63 was truncated in the audit; will backfill during build
  script implementation.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-12 15:56:04 -07:00
Evan Rusackas
1fffd9d832 docs(country-map): SIP — add procedural/ escape hatch for edge cases
Most touchups fit declarative YAML cleanly (typos, ISO codes,
repositions, dissolves, composites). A few don't — e.g., the
France-with-Overseas notebook drops a specific sub-polygon by index
to avoid visual conflict with Corsica.

Add a `procedural/` directory of small, named, single-purpose Python
scripts as an escape hatch. Build orchestrator runs YAML transforms
first, then iterates procedural/*.py in numeric order.

Why this is much better than the notebook for the same content:
- Each fix is a separate file → conflicts localize to one fix at a
  time, not "the whole notebook touched the same cell"
- No kernel state, no output churn, pure functions on data
- Naming forces documentation; reviewers see add/remove at a glance
- Bounded growth: a 50-file procedural/ dir is annoying enough to
  signal "push back into YAML or upstream"; the notebook had no
  such signal and just bloated

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-12 15:50:05 -07:00
Evan Rusackas
1e349d26a4 docs(country-map): SIP — obsolescence check vs current NE 5.x
Verified each notebook touchup against current Natural Earth Admin 1
data. Headline wins:

OBSOLETE (NE caught up or worldview handles it):
- Vietnam diacritics: NE has correct values in name_vi field; manual
  rewrites collapse to zero by exposing name_language=vi
- Crimea/Sevastopol: handled by _ukr worldview (already confirmed)
- India Kashmir/Ladakh geometry: NE has UTs with correct ISO codes;
  worldview selection adjusts northern boundary
- Russia Chukchi antimeridian: NE has split geometry into properly-
  bounded polygons (x range [-180, 180]); D3 projection should handle
- Latvia third-party file: NE has 119 fine-grained admin1 features
- Philippines third-party file: NE has 118 admin1 features
- external_overrides.yaml DROPPED from the design

STILL NEEDED (NE still wrong / no upstream support):
- France typos (Seien-et-Marne, Haute-Rhin still in NE)
- France ISO codes (FR-75 → FR-75C, FR-GP → FR-971, etc. — 6 features)
- Philippines admin renames (Dinagat→Caraga, ARMM→BARMM, 11 features)
- China + SARs (Taiwan/HK/Macau still separate Admin 0 in NE)
- Finland + Åland (missing from FIN admin 1 in NE)
- Regional aggregations (Turkey NUTS-1, France/Italy/PHL regions)
- France-with-Overseas composite
- Flying-island repositions (USA, Norway, Portugal, Spain, France DOM)

Net: design surface shrinks, no third-party data dependencies in-tree,
config files stable enough that ongoing maintenance is small.

Two follow-up verifications still pending: Russia Chukchi renders
correctly under D3, India J&K geometry matches current Indian
boundary expectations under _ukr worldview.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-12 15:43:36 -07:00
Evan Rusackas
b12044cec7 docs(country-map): SIP — audit notebook touchups, enumerate config surface
Read all 96 cells of the legacy notebook; categorized every kind of
work it does into 14 buckets and mapped each to either:
-  already covered by the proposed design
- 🟡 covered but requires a YAML config we'll need to port
- 🟠 needs a NEW config file or pipeline feature beyond what was sketched
-  might be obsolete in current NE — verify per case

Surfaced four NEW config-driven build features beyond the original
sketch:
- territory_assignments.yaml (China + SARs, Finland + Åland)
- regional_aggregations.yaml (Turkey NUTS-1, France/Italy/Philippines
  regions; new "Aggregated regions" admin level)
- composite_maps.yaml (France-with-Overseas multi-country composite)
- external_overrides.yaml (India/Latvia/Philippines third-party
  GeoJSON; verify whether still needed against current NE)

Plus extended flying_islands.yaml with drop|reposition action modes
to subsume the bounds-clipping pattern (Netherlands, UK).

Updated open questions, smoke-test fixtures (now 5 cases that
exercise the full surface), and Phase 1 of the implementation plan
with the obsolescence check + external-GeoJSON check as concrete
follow-ups.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-12 15:33:54 -07:00
Evan Rusackas
a4b1ecafd1 docs(country-map): SIP draft for Country Map plugin redesign
Living document tracking the design for the Country Map rework. Will
be filed as a proper SIP issue when the POC matures; this file is
working scratch in the meantime.

Captured so far:
- Motivation: disputed-borders flashpoints, Jupyter notebook pain,
  legacy explore_json endpoint
- Goals: configurable worldview, Admin 0 + Admin 1, per-deployment
  + per-chart customization, mapshaper-based reproducible build
  pipeline, modern chart/data endpoint
- Spike findings: NE UA worldview vs Default — confirms Crimea-as-
  Ukrainian + several other commonly-expected positions (Kosovo,
  Western Sahara, Palestine, Cyprus, Kashmir)
- Deprecation plan: in-UI "switch to new Country Map" button + banner
  on legacy, modeled on existing deprecated-chart pattern

Open questions tracked inline; implementation phases sketched.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-12 15:16:03 -07:00
Varun Chawla
a77fec68d4 fix(drill-detail): make page-size selector functionally adjustable (#37975)
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Co-authored-by: Evan Rusackas <evan@preset.io>
2026-05-12 13:39:41 -07:00
Abdul Rehman
e94465208f fix(bar-chart): cap bar width so a single data point doesn't stretch across the chart (#39588)
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-12 13:24:46 -07:00
Abdul Rehman
f2eee4ef46 fix(frontend): prevent LanguagePicker crash when locale is missing from LANGUAGES config (#39585)
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-12 13:22:36 -07:00
yeaight
7445105735 fix(explore): explain disabled chart overwrite option (#39796) 2026-05-12 12:53:59 -07:00
innovark
2392c8e624 fix(Select): fix Russian translations for Select (#35751)
Co-authored-by: Evan Rusackas <evan@preset.io>
Co-authored-by: Sam Firke <sfirke@users.noreply.github.com>
2026-05-12 13:48:42 -04:00
Arpit Jain
39ad6b200f docs(update): fix typos in UPDATING.md (#40068) 2026-05-12 23:40:22 +07:00
Igor Khrol
3363b48180 fix(spark): register Spark SQLAlchemy dialect so spark:// URIs resolve to SparkEngineSpec (#38299)
Co-authored-by: Joe Li <joe@preset.io>
2026-05-12 12:33:17 -04:00
dependabot[bot]
c9fb1bc10f chore(deps-dev): bump @typescript-eslint/parser from 8.59.2 to 8.59.3 in /superset-frontend (#40057)
Signed-off-by: dependabot[bot] <support@github.com>
Signed-off-by: hainenber <dotronghai96@gmail.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: hainenber <dotronghai96@gmail.com>
2026-05-12 22:27:58 +07:00
Evan Rusackas
658907a0a6 fix(gha): use sound condition gating for latest-tag step (#40035)
Co-authored-by: Superset Dev <dev@superset.apache.org>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-12 22:27:26 +07:00
Đỗ Trọng Hải
4a79896bb2 chore(build): replace replaceable jest-mock-console with native Jest spies (#38643)
Signed-off-by: hainenber <dotronghai96@gmail.com>
2026-05-12 21:32:08 +07:00
Đỗ Trọng Hải
b0c5b061c5 fix(sqllab): display horizontal scrollbar in data preview modal (#39799)
Signed-off-by: hainenber <dotronghai96@gmail.com>
2026-05-12 21:30:54 +07:00
Kasia
c394405fc1 fix(explore): restore spacing between tabs and content in control popovers (#40023) 2026-05-12 14:30:41 +02:00
Kasia
d2ae5fb275 fix(ux): remove CSS-forced uppercase from button labels (#40049) 2026-05-12 14:28:39 +02:00
Amin Ghadersohi
460992d89b fix(mcp): improve not-found errors to suggest corresponding list_* tools (#39919)
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-05-12 02:38:10 -04:00
Amin Ghadersohi
85935b0b88 fix(mcp): handle SSL connection drop during pre-call session teardown (#39917) 2026-05-12 02:32:14 -04:00
innovark
fa168fcc8a fix(Label): use correct color for label component (#38707) 2026-05-11 21:40:31 -07:00
Andy
a6ad0bf169 fix(re-encrypt-secrets): use db.Model.metadata to discover encrypted … (#39390)
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-11 21:16:41 -07:00
Abdul Rehman
fed29b3017 fix(deploy): prevent double-prefix of logo URL in subdirectory deployments (#39472)
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-11 21:13:26 -07:00
Nitish Agarwal
24d76b4249 fix(sunburst): remove label text outline in dark theme (#39774) 2026-05-11 20:24:25 -07:00
Evan Rusackas
5ab8583cd0 chore(gha): pin github/codeql-action to a SHA (#40043)
Co-authored-by: Superset Dev <dev@superset.apache.org>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-11 20:18:55 -07:00
Evan Rusackas
e66fbc91c2 chore(gha): pass commenter login through env in claude.yml (#40042)
Co-authored-by: Superset Dev <dev@superset.apache.org>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-11 20:00:27 -07:00
Mafi
187bb416e7 fix(plugin-chart-ag-grid-table): use display text for filter and sort on HTML cells (#39885)
Co-authored-by: Richard Fogaca Nienkotter <63572350+richardfogaca@users.noreply.github.com>
2026-05-11 20:29:16 -03:00
Evan Rusackas
cfb704dbeb test(sqllab): stabilize SaveDatasetModal overwrite-flow test helper (#40036)
Co-authored-by: Superset Dev <dev@superset.apache.org>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-11 15:48:10 -07:00
Evan Rusackas
e77f6ece92 fix(ci): serialize Docs Deployment runs to avoid push races (#40030)
Co-authored-by: Claude Code <noreply@anthropic.com>
2026-05-11 11:25:31 -07:00
Evan Rusackas
785a08c7d5 chore(frontend): export typed useAppDispatch / useAppSelector hooks (#40027)
Co-authored-by: Claude Code <noreply@anthropic.com>
2026-05-11 11:01:57 -07:00
Maxime Beauchemin
d90d3a2dea fix(importexport): honor overwrite flag on /api/v1/assets/import (#39502)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-11 10:24:42 -07:00
Maxime Beauchemin
6ee4d694bc fix(sqllab): include template_params when overwriting a dataset (#39501)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-11 10:24:15 -07:00
Evan Rusackas
006a1800be chore(lint): convert react-pivottable components to function components (#39453)
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 10:19:05 -07:00
Evan Rusackas
2fe6269c22 chore(lint): convert ChartDataProvider and StatefulChart to function components (#39456)
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 09:55:27 -07:00
Evan Rusackas
26ef4b7ed3 fix(sqla): pass catalog and schema to get_sqla_engine in values_for_column (#38681)
Co-authored-by: Superset Dev <dev@superset.apache.org>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Claude <claude@anthropic.com>
2026-05-11 09:54:48 -07:00