SACGF / SACGF/variantgrid

GeneGrid: replace hand-rolled table JS with Tabulator

Open
#1,811 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Python
Stars
30
Forks
3
Avg merge
9h 28m
Merged PRs (30d)
42

Description

🤖 Written by Claude

## Problem

`genes/templates/genes/tags/gene_grid_tag.html` contains ~2,170 lines of JS. Roughly a third of it is a hand-rolled reactive table: global arrays (`enrichmentKits`, `geneLists`, `pathologyTestVersions`, `evidenceColumns`, …) hold the state, the DOM is a second copy, and `createRowColumns` / `createRowColumnsFromData` / `addGeneDataRows` / `setCell` / `gcEmptyRows` / `removeColumn` reconcile the two by hand — dynamic columns keyed by CSS class, sorted row insertion, colspan bookkeeping, enrichment-kit sub-columns. Another ~150 lines is a hand-rolled table→CSV exporter. That plumbing is the hardest part to change safely and none of it is specific to genes.

## Proposal

Port the grid to [Tabulator](https://tabulator.info) (MIT, 6.x, no build step, coexists with jQuery). It is column-oriented with dynamic columns as a first-class API, which is exactly the shape of this feature:

- `table.addColumn()` / `column.delete()` replaces all column reconciliation and colspan handling
- Column groups replace `addSubColumns` and the `headerRow` special-casing for enrichment kits
- `index: "gene"` + `updateOrAddData()` replaces the sorted merge-insert in `addGeneDataRows`; sorting is free
- Per-column `formatter` — each column type (gene list, enrichment kit, gene annotation release, PanelApp, GenCC, lab classification counts, pathology test version) becomes a self-contained module: fetch → column def + formatter. Lazy cells render a spinner and `row.update()` when the existing batch fetch resolves (keep the ~100 lines of debounced batching)
- `titleFormatter` for header icons / close / copy buttons; `cellMouseEnter`/`cellMouseLeave` for hover-to-add
- `table.download("csv")` deletes the CSV exporter
- Frozen gene column + virtual DOM rendering — large PanelApp panels × many columns will render noticeably faster than the current full-DOM approach
- `rowFormatter` for alias / unmatched row styling

Expected outcome: ~2,170 → ~800–1,000 lines, mostly domain logic organised per column type.

## Considered and passed on

- **DataTables** (already in the project) — row-oriented; adding/removing columns needs destroy/re-init. Poor fit for this grid specifically.
- **AG Grid Community** — would work but heavier than needed.
- **Alpine / petite-vue** — would remove the reconciliation code but leaves column groups, sorting and CSV to hand-write, and there's no precedent for a reactive framework in the codebase.
- **Server-render via htmx** — the URL is already the column source of truth, but the editable gene-list / pathology-test interactions and batched lazy coverage fetches make this a larger redesign.

## Prerequisite

Extracting the JS from the template into `js/gene_grid.js` (config via `json_script`, callbacks via a `geneGridInit(config, callbacks)` bootstrap) is being done first as a separate, behaviour-preserving change. The port should start from that file.

## Suggested first step

Prototype with two column types — a gene list and an enrichment kit column group with lazy coverage — to confirm the fit before porting the rest.

Contributor guide

No contributing guide indexed for this repository

Research direction

Start from js/gene_grid.js after the behaviour-preserving extraction, then prototype the gene-list column and the enrichment-kit column group with lazy coverage. Compare the prototype with the existing gene grid behaviour, including dynamic columns, sorting, and CSV download. The first step is done when those two column types work without the old table reconciliation plumbing and the Tabulator fit is confirmed.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript
Domain
frontend
Issue type
Refactor
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.