Skip to content

GeneGrid: replace hand-rolled table JS with Tabulator #1811

Description

@davmlaw

🤖 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 (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.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions