Skip to content

Align Geodata plugin with Redis UI design system#5982

Open
valkirilov wants to merge 8 commits into
feature/workbench-geo-pluginfrom
fe/feature/5921/geodata-redis-ui
Open

Align Geodata plugin with Redis UI design system#5982
valkirilov wants to merge 8 commits into
feature/workbench-geo-pluginfrom
fe/feature/5921/geodata-redis-ui

Conversation

@valkirilov
Copy link
Copy Markdown
Member

@valkirilov valkirilov commented May 28, 2026

What

Migrate the new Geodata Workbench plugin to the Redis UI design system instead of hand-rolling its own primitives.

Each Redis UI replacement landed as its own commit so the diff can be reviewed component-by-component:

  • refactor(ui): use Redis UI banner for geodata Message
  • refactor(ui): use Redis UI layout primitives in GeoHeader
  • refactor(ui): use Redis UI Table for GeoTable
  • refactor(ui): use Redis UI cards and Col gap in geodata layout
  • refactor(ui): use Redis UI TextButton and Slider for distance thresholds
  • chore(ui): drop unused geodata styles after Redis UI migration

All theme-token spacing, typography sizes, and color tokens live in per-component *.styles.ts and *.types.ts files per the frontend styleguide.

Screenshots

Message error

Before After
Screenshot 2026-05-28 at 10 29 39 Screenshot 2026-05-28 at 10 40 40
Screenshot 2026-05-28 at 10 29 32 Screenshot 2026-05-28 at 10 40 46

GEOPOS / GEOADD

Before After
Screenshot 2026-05-28 at 11 49 18 Screenshot 2026-05-28 at 14 43 11
Screenshot 2026-05-28 at 11 49 12 Screenshot 2026-05-28 at 14 43 17
Screenshot 2026-05-28 at 13 48 59 Screenshot 2026-05-28 at 14 15 36
Screenshot 2026-05-28 at 13 49 04 Screenshot 2026-05-28 at 14 15 42

GEOHASH

Before After
Screenshot 2026-05-28 at 13 14 43 Screenshot 2026-05-28 at 13 45 31
Screenshot 2026-05-28 at 13 14 48 Screenshot 2026-05-28 at 13 45 22

Map

Before After
Screenshot 2026-05-28 at 16 11 42 Screenshot 2026-05-28 at 15 13 32
Screenshot 2026-05-28 at 16 11 48 Screenshot 2026-05-28 at 15 13 35

Testing

The geodata plugin has its own dev server / mock fixtures:

cd redisinsight/ui/src/packages/geodata
yarn dev          # http://localhost:8081
yarn test         # 99 tests, all pass
yarn typecheck    # geodata-only tsc, clean

Switch themes via ?theme=light / ?theme=dark query string. Edit the dev block in src/main.tsx to swap fixtures (GEOPOS, GEOHASH, GEODIST, GEOADD, PING, GEOSEARCH ... WITHCOORD for markers).

For the threshold-overlay leaflet view, run the markers fixture and confirm the toggle expands into two Redis UI Sliders and a Reset TextButton.


Note

Low Risk
Presentation-layer refactor in an isolated Workbench plugin; map parsing and Leaflet behavior are largely unchanged aside from threshold control UX (sliders).

Overview
The geodata Workbench plugin is refactored from custom CSS and HTML primitives to Redis UI components (Banner, Table, Card, Title/Text, Row/Col, TextButton, Slider) with theme tokens in per-component *.styles.ts files.

New layout pieces include Shell, GeoSummary, GeoMetric, and an extracted DistanceThresholdControls (replacing native range inputs on the map). Errors use variant="danger" on messages. GeoTable now builds on the shared TanStack Table. Plugin imports go through uiSrc re-exports for Slider and TextButton.

styles.scss shrinks to Leaflet-only selectors; tests wrap renders in a ThemeProvider, and the plugin dev server adds React dedupe plus ?theme=light|dark for screenshots.

Reviewed by Cursor Bugbot for commit c0264f9. Bugbot is set up for automated code reviews on this repo. Configure here.

valkirilov and others added 8 commits May 28, 2026 10:28
The geodata plugin's local node_modules pulled in react@18.3.1 while the
workspace root is on 18.2.0. When the plugin's main.tsx imports anything
from uiSrc/components/base (e.g. ThemeProvider), vite resolved two React
copies and the playground crashed with
"Cannot read properties of null (reading 'useContext')".

Dedupe react/react-dom in the shared plugin vite config so every plugin
playground binds to a single React instance. Also accept ?theme=light /
?theme=dark in the geodata dev block so the plugin can be screenshotted
in both themes without editing index.html.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Replace the hand-rolled <section className="geodata-message"> with a
Banner.Compose-based shell so the geodata plugin's status/error panels
match the rest of the app's design system.

- Message wraps Banner.Compose and a Col flex layout (gap="s") around
  the title + children, with theme-token spacing in Message.styles.ts.
- Banner.Compose lets us put a real <div> (Col) inside without the auto
  <p> wrap that Banner's message slot would otherwise enforce, so the
  layout stays valid HTML.
- MessageVariant is inferred from Banner.Compose's own variant prop
  rather than redeclared; MessageProps lives in Message.types.ts per
  the frontend styleguide.
- All eight error-titled call sites (App, GeoInspector x6,
  GeoSearchVisualization x2, RqeGeoVisualization x2) opt into
  variant="danger" so the banner colour matches the message intent.
- jest.setup.ts now wraps every testing-library render with a
  styled-components ThemeProvider so the new theme-token styles
  resolve in unit tests.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Replace the raw <header>/<h2>/<dl> markup with a Row that holds the
heading and the result-summary block, using Title/Text from the design
system and theme-token spacing/border so the geodata plugin header
matches the rest of the app.

The inner result-summary Row uses grow={false} so the outer
justify="between" can push it to the right edge; each metric Col uses
align="end" to right-align its label and value. The header lives in a
styled(Row) with width: 100%, padding-bottom and border-bottom pulled
from theme.core.space and theme.semantic.color.border.

Styles and types live in GeoHeader.styles.ts and GeoHeader.types.ts
per the frontend styleguide.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Replace the hand-rolled <table className="geodata-table"> with the
Redis UI Table from uiSrc/components/base/layout/table (TanStack-based)
so the geodata plugin's inspector tables match the shared table chrome.

The component keeps its existing (columns: string[], rows: ReactNode[][])
contract by adapting internally into ColumnDef<RowData>[] + data[]:
each row is materialised as an object keyed by column name and each
column gets an accessorKey + cell renderer. All four call sites in
GeoInspector and RqeGeoVisualization stay unchanged.

A small styled wrapper holds the top margin via theme.core.space.space150.
A future cycle will convert the surrounding geodata-shell into a Col
with gap so this margin can drop.

jest.setup.ts: tighten the render-override option type so the spread no
longer trips noUnusedLocals/Parameters when typecheck runs against
@tanstack/table-core via the new Table import.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Introduce three shared geodata components built on the Redis UI design
system primitives and rewire the inspector / visualization shells to
use them:

- Shell: a Col-based wrapper that keeps the existing .geodata-shell
  className for leaflet/plot CSS variables while providing a uniform
  gap="m" between header / summary / body sections. Replaces the four
  remaining <div className="geodata-shell"> blocks in App, GeoInspector,
  GeoSearchVisualization, and RqeGeoVisualization.
- GeoSummary: a Card-backed panel that takes a labelled item list and
  lays it out in a Row of label/value Cols. Replaces the two
  <dl className="geodata-summary-grid"> grids in GeoInspector and
  RqeGeoVisualization.
- GeoMetric: a Card-backed metric tile with a small subdued label and
  a large Title value. Replaces the
  <section className="geodata-metric"> blocks for Distance, addSummary
  and storeSummary.

Both Card panels override the default Card border with a
box-shadow: 0 0 0 1px neutral600 ring so they match the Redis UI Table
chrome the GeoTable already renders.

Because Shell now adds gap="m" between siblings, the per-component
margin-top in GeoTable.styles.ts and Message.styles.ts becomes dead
weight: GeoTable.styles.ts is deleted and Message's StyledBanner only
keeps width: 100%.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Move the inline DistanceThresholdControls out of GeoPlot.tsx and into
its own component folder so it follows the per-folder style guide, then
rewire the chrome and inputs to the design system:

- TextButton from @redis-ui/components replaces the two raw <button>
  elements (toggle + Reset). Aria-expanded and disabled props carry
  over, so the existing GeoPlot specs still locate them by role.
- Slider from @redis-ui/components replaces the two <input type="range">
  controls. Slider is Radix-backed and exposes role="slider" thumbs
  that the tests now drive with fireEvent.keyDown on ArrowLeft /
  ArrowRight - no mock needed.
- The overlay panel uses styled(Card) with the same neutral600
  box-shadow ring already used by GeoSummary/GeoMetric, plus position:
  absolute, width: fit-content, and theme-token spacing.
- .geodata-threshold-panel was sitting at z-index: 2, below leaflet's
  marker (600) and control (1000) panes - bump to 1100 so the overlay
  is visible above the map.
- DistanceThresholds and ThresholdControlsProps move to the new
  DistanceThresholdControls.types.ts; GeoPlot.types.ts and
  GeoPlot.constants.ts import from the new location.
- GeoHeader value Text is now size="XS" so the label and value match
  visually (label was already XS).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Now that Message, GeoHeader, GeoTable, GeoSummary, GeoMetric and
DistanceThresholdControls all render via styled-components on top of
Redis UI primitives, the old hand-rolled rules in styles.scss are dead.

Keep only the styles still consumed by leaflet-managed nodes that React
cannot reach directly:
- .geodata-shell + body.theme_LIGHT override (host element on which
  cluster markers / plot panel inherit their CSS variables)
- .geodata-plot-panel / .geodata-plot (positioning and sizing for the
  leaflet container created imperatively)
- .geodata-cluster / .geodata-cluster-icon (DivIcon class names used by
  marker-cluster groups)
- .geodata-offline-note (the "Map tiles unavailable" overlay)

The orphan CSS variables (--geodata-distance-*, --geodata-message-*,
--geodata-marker-background, --geodata-muted-text, --geodata-panel-*,
--geodata-subtle-text, --geodata-table-header-*) are also removed, both
in the dark base block and the light-theme override.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The plugin had two leftover direct imports from @redis-ui/components.
Route them through the project's uiSrc aliases per the styleguide:

- Add `export { Slider } from '@redis-ui/components'` to
  uiSrc/components/base/inputs/index.ts (same pattern the buttons
  barrel uses for TextButton). The geodata plugin now imports Slider
  from uiSrc/components/base/inputs.
- Add a per-file uiSrc/components/base/forms/buttons/TextButton.ts
  re-export so TextButton matches the per-file pattern used by every
  other button in that folder (ActionIconButton, BaseButton,
  DestructiveButton, EmptyButton, IconButton, PrimaryButton,
  SecondaryButton, ToggleButton). Importing TextButton from the
  forms/buttons barrel would also drag in BaseButton -> icons ->
  iconRegistry -> themeContext -> services -> utils -> rawproto, which
  jest's babel pipeline cannot parse; importing from the per-file
  module sidesteps that chain.

The geodata plugin source now has zero direct @redis-ui/components
imports. The only remaining @redis-ui/* reference is themesDefault in
geodata's jest.setup.ts, which mirrors pluginsThemeContext.tsx in the
host app and is test-setup-only.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@valkirilov valkirilov requested a review from a team as a code owner May 28, 2026 13:02
@jit-ci
Copy link
Copy Markdown

jit-ci Bot commented May 28, 2026

🛡️ Jit Security Scan Results

CRITICAL HIGH MEDIUM

✅ No security findings were detected in this PR


Security scan by Jit

@github-actions
Copy link
Copy Markdown
Contributor

Code Coverage - Backend unit tests

St.
Category Percentage Covered / Total
🟢 Statements 92.68% 15641/16877
🟡 Branches 74.81% 4928/6587
🟢 Functions 86.75% 2436/2808
🟢 Lines 92.51% 14949/16159

Test suite run success

3439 tests passing in 307 suites.

Report generated by 🧪jest coverage report action from c0264f9

@valkirilov valkirilov changed the title RI-5921 Align geodata plugin with Redis UI design system Align Geodata plugin with Redis UI design system May 28, 2026
@valkirilov valkirilov self-assigned this May 28, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 28, 2026

Code Coverage - Frontend unit tests

St.
Category Percentage Covered / Total
🟢 Statements 82.87% 24722/29834
🟡 Branches 68.1% 10387/15252
🟡 Functions 78.06% 6677/8554
🟢 Lines 83.33% 24144/28974

Test suite run success

6986 tests passing in 803 suites.

Report generated by 🧪jest coverage report action from c0264f9

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant