Skip to content

BDMS-1133: Projects as a top-level resource, boundary preview, denser table - #344

Draft
jirhiker wants to merge 5 commits into
stagingfrom
BDMS-1133
Draft

BDMS-1133: Projects as a top-level resource, boundary preview, denser table#344
jirhiker wants to merge 5 commits into
stagingfrom
BDMS-1133

Conversation

@jirhiker

Copy link
Copy Markdown
Member

What

Three commits on top of staging:

  1. 23db2ee — Projects promoted to a top-level resource with editing.
  2. f672775 — Boundary preview dialog + denser table. Rows with geometry get a map action that opens the project boundary in a dialog. MapComponent gains an onLoad callback so the dialog can fit bounds once the map is ready instead of guessing at mount.
  3. bee0abd — Dev server port made configurable. Reads PORT, falls back to 5173.

On the table density

Cell padding drops to py-0.5 and the header to h-7, but padding was not the binding constraint. Row height was floored by the action buttons: at size-7 they were 28px, taller than both the status badge (20px) and the text line box (20px), so trimming padding alone would have changed nothing. They now use the existing icon-xs variant at 24px, and the icons inherit their size from the variant instead of an ad-hoc size-3.5 override.

Measured in the browser rather than estimated:

Before After
Body row 37px 29px
Header 32px 28px
Action button 28px 24px
Table, 20 rows 772px 608px

24px is now the floor — badge and text sit at 20px, so going tighter means sub-24px hit targets. Left that call open.

Why PORT

vite.config.ts hardcoded 5173, so a second dev server on the same checkout could not start. 5173 stays the default because the Authentik redirect URI is registered against it; launch.json opts into autoPort.

Verification

  • tsc --noEmit clean
  • vitest run — 47 files, 398 passed, 1 skipped
  • biome lint clean on all changed files (17 pre-existing warnings, 0 errors)
  • Projects page exercised in the browser: 83 projects render, no console errors, geometry measured from the live DOM

Note: npm run lint currently fails repo-wide with "nested root configuration" — caused by biome.json files inside pre-existing .claude/worktrees/ checkouts. Unrelated to this branch and present before it.

🤖 Generated with Claude Code

@github-actions

Copy link
Copy Markdown

Preview Deployment

Preview URL: https://preview-bdms-1133-auejgdbofq-uc.a.run.app

Note: This preview uses the staging API endpoints.

@github-actions

Copy link
Copy Markdown

Preview Deployment

Preview URL: https://preview-bdms-1133-auejgdbofq-uc.a.run.app

Note: This preview uses the staging API endpoints.

@github-actions

Copy link
Copy Markdown

Preview Deployment

Preview URL: https://preview-bdms-1133-auejgdbofq-uc.a.run.app

Note: This preview uses the staging API endpoints.

@github-actions

Copy link
Copy Markdown

Preview Deployment

Preview URL: https://preview-bdms-1133-auejgdbofq-uc.a.run.app

Note: This preview uses the staging API endpoints.

@jirhiker
jirhiker marked this pull request as draft August 14, 2026 16:20
@jirhiker

Copy link
Copy Markdown
Member Author

@TylerAdamMartinez FYSA

jirhiker and others added 5 commits August 17, 2026 13:56
Projects were introduced as a sub-feature of Wells and later moved to
top-level navigation, but the URL, resource name, route nesting, access
key and source directory still described them as a wells sub-feature.
Finish that move and build out editing on the list page.

Routing:
- /ocotillo/well/projects -> /ocotillo/projects, resource `projects`,
  access key `ocotillo.projects`, route lifted out of the `well` block
- pages moved to src/pages/ocotillo/projects/, components renamed to
  ProjectList / ProjectShow

List:
- replace the MUI DataGrid with the shadcn table. The group endpoint
  ignores sort params and returns a few hundred rows, so the page loads
  the full set and sorts, filters and pages locally; filtering a single
  server page would only ever describe part of the data
- sortable columns with aria-sort and blanks-last ordering, search over
  name/description/type/status, Type and Release status facets with a
  "none" option for untyped records, 20 rows per page

Editing:
- ProjectEditPanel opens from a row edit action or double click: name
  (admin only), description, release status, type, and boundary upload
- GeoJSON upload accepts a single polygon and emits MULTIPOLYGON WKT,
  the only geometry type group.project_area accepts
- 409 on the unique (name, group_type) constraint gets its own message

Also drops the client-side quick filter from ListPage. It filtered only
the current server page while sitting next to the Filters toolbar
button, with no way to tell the two apart. Server-search lists (Wells)
keep their search input.

Project type editing requires the matching OcotilloAPI change adding
group_type to UpdateGroup; without it PATCH returns 200 and silently
discards the value.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Adds a map action to each project row that has geometry, opening the
boundary in a dialog. MapComponent grows an onLoad callback so the dialog
can fit bounds once the map is ready rather than guessing at mount time.

Also tightens the table vertically. Cell padding drops to py-0.5 and the
header to h-7, but the row height was actually floored by the action
buttons: at size-7 they were 28px, taller than both the status badge
(20px) and the text line box (20px), so trimming padding alone would not
have moved anything. Switching them to the existing icon-xs variant puts
them at 24px and lets the icons inherit their size from the variant
instead of an ad-hoc override. Measured in the browser, rows go from 37px
to 29px — a 20-row page is 608px tall instead of 772px.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The port was hardcoded, so a second dev server on the same checkout could
not start at all. It now reads PORT and falls back to 5173, which stays
the default because the Authentik redirect URI is registered against it.
launch.json opts into autoPort so the harness can pick a free port.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
23db2ee moved Projects to the shadcn table and dropped the client-side
quick filter from ListPage, but the e2e spec was only updated for the new
URL. Two assertions still described the old DataGrid.

The projects test now looks for the table's own search input and uses
native th/tr selectors, since the shadcn table has no explicit
role="columnheader"/role="row" attributes. The contacts test drops its
quick-filter assertion outright — that page has no search config, so the
input is simply gone rather than renamed. Its DataGrid assertions stay,
because contacts still renders a DataGrid.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The MapLibre merge made maplibre-gl reachable from ProjectListPanel's
render tree, and it calls URL.createObjectURL at module load to start its
worker. jsdom does not implement that, so the import threw and vitest
failed the run on an unhandled rejection even though all 398 tests passed.

Stubbed in the shared setup rather than per-test, since any future test
that reaches MapComponent would hit the same wall. Guarded on window
because the API contract tests run in the node environment.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
jirhiker added a commit that referenced this pull request Aug 17, 2026
Replaces the MUI DataGrid on the Wells and Contacts lists with a shared
shadcn table built on TanStack Table, following the denser table style
introduced by the Projects work in #344.

- Adds src/components/DataTable: table renderer, sortable/filterable
  column headers, column visibility menu, filter chips, pager, and a
  useRefineDataTable hook bridging Refine's useTable server state
  (paging, sorting, filtering) to TanStack's manual mode.
- Column filters cover text, single-select, and numeric/date comparison
  operators; PostHog events keep the names the DataGrid pages emitted
  (<prefix>_sorted, _filter_applied, _column_visibility_changed).
- Wells: same columns, tooltips, project filter chip, server search,
  batch field sheets and CSV export; now defaults to newest first
  (created_at desc, the closest field the API exposes to "last updated").
- Contacts: rows now select instead of navigating, so the email, phone
  and address cards open below the table; the name cell links to the
  contact page.
- Adds ListPageShell for the page chrome the DataTable pages share, and
  moves the row navigation helpers next to the DataTable (re-exported
  from ListPage).

Density toggle is not carried over; the shadcn table is already compact.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

Preview Deployment

Preview URL: https://preview-bdms-1133-auejgdbofq-uc.a.run.app

Note: This preview uses the staging API endpoints.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant