Skip to content

feat(cms): sortable table (for TACC project pages redesign)#1167

Merged
wesleyboar merged 13 commits into
mainfrom
feat/research-software-cms-phase-b
Jun 2, 2026
Merged

feat(cms): sortable table (for TACC project pages redesign)#1167
wesleyboar merged 13 commits into
mainfrom
feat/research-software-cms-phase-b

Conversation

@wesleyboar

@wesleyboar wesleyboar commented Jun 1, 2026

Copy link
Copy Markdown
Member

Overview

Sort tables on CMS pages.

Important

Reconsider implementation. See:

Sorting moved to List.js in follow-up PR.

Related

Changes

  • added sortable table script
  • updated delayed page assets to run it on main content

Testing

  1. Listing table: Name column A→Z by default; Description does not sort.
  2. Other columns sort on header click.

UI

using.the.feature.mov
markup

Vanilla sort for table.o-sortable-table (not tablesort: APG button headers).
Init from assets_core_delayed on #cms-content.

Co-authored-by: Cursor <cursoragent@cursor.com>
@qodo-code-review

qodo-code-review Bot commented Jun 1, 2026

Copy link
Copy Markdown

Review Summary by Qodo

(Agentic_describe updated until commit 044a1b5)

Add sortable table module for CMS project pages

✨ Enhancement

Grey Divider

Walkthroughs

Description
• Add client-side sortable table functionality for CMS pages
• Implement accessible sort buttons with ARIA attributes
• Include CSS styling for sort indicators and button states
• Initialize sortable tables on delayed page assets load
Diagram
flowchart LR
  A["assets_core_delayed.html"] -->|imports| B["sortableTable.css"]
  A -->|imports| C["sortableTable.js"]
  C -->|initializes| D["table.is-sortable"]
  D -->|renders| E["Sort Buttons"]
  E -->|updates| F["aria-sort Attributes"]
  F -->|triggers| G["Client-side Sort"]

Loading

Grey Divider

File Changes

1. taccsite_cms/templates/assets_core_delayed.html ✨ Enhancement +4/-0

Wire sortable table module into delayed assets

• Import sortableTable CSS stylesheet for styling
• Import sortableTable JS module as ES6 module
• Initialize sortableTable on cms-content scope element

taccsite_cms/templates/assets_core_delayed.html


2. taccsite_cms/static/site_cms/css/modules/sortableTable.css ✨ Enhancement +45/-0

Add sortable table styling and indicators

• Style sortable table headers with button-specific rules
• Add sort indicator symbols (▲/▼) via CSS content
• Support Bootstrap btn-link and Core-Components c-button--as-link styles
• Ensure proper focus visibility and layout for header buttons

taccsite_cms/static/site_cms/css/modules/sortableTable.css


3. taccsite_cms/static/site_cms/js/modules/sortableTable.js ✨ Enhancement +187/-0

Implement accessible client-side table sorting

• Implement vanilla JavaScript sort for tables with is-sortable class
• Create accessible sort buttons with aria-sort and aria-label attributes
• Handle edge cases like missing cells and irregular row structures
• Support configurable scope, selectors, and button styling
• Sort first column ascending by default on initialization
• Use locale-aware string comparison for sorting

taccsite_cms/static/site_cms/js/modules/sortableTable.js


Grey Divider

Qodo Logo

@qodo-code-review

qodo-code-review Bot commented Jun 1, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0)

Grey Divider


Action required

1. Missing cell sort crash ✓ Resolved 🐞 Bug ☼ Reliability
Description
sortTable() passes row.cells[columnIndex] into getSortValue(), but getSortValue()
immediately calls cell.querySelector(...) with no null/undefined guard. Any table row with fewer
cells than the header (e.g., due to colspan/rowspan or malformed CMS output) will throw a TypeError
on sort and can break the page’s module script execution.
Code

taccsite_cms/static/site_cms/js/modules/sortableTable.js[R40-43]

Evidence
getSortValue dereferences cell via querySelector, while sortTable calls it with
row.cells[columnIndex] without validating the index exists on every row; when the cell is missing,
sorting throws at runtime.

taccsite_cms/static/site_cms/js/modules/sortableTable.js[20-24]
taccsite_cms/static/site_cms/js/modules/sortableTable.js[40-43]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`getSortValue` assumes it always receives an `HTMLTableCellElement`, but `sortTable` can pass `undefined` when `row.cells[columnIndex]` is out of bounds. This causes a `TypeError` during sorting.
## Issue Context
Tables coming from CMS/editorial content can have irregular row structures (e.g., colspan/rowspan, missing cells). The sorting logic should be defensive and treat missing cells as an empty sort key (or some deterministic fallback) rather than crashing.
## Fix Focus Areas
- taccsite_cms/static/site_cms/js/modules/sortableTable.js[20-24]
- taccsite_cms/static/site_cms/js/modules/sortableTable.js[31-44]
## Implementation notes
- Add a guard in `getSortValue` (preferred) to handle falsy/undefined `cell` and return `''`.
- Optionally, add a secondary guard in `sortTable`’s comparator to avoid calling `getSortValue` when the cell is missing.
- Consider also guarding against `rowA.cells[columnIndex]` returning `null/undefined` when tables contain colspan/rowspan.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

2. Unbuilt nested CSS module 🐞 Bug ≡ Correctness
Description
The template links site_cms/css/modules/sortableTable.css directly, but the file uses nested
selectors (&, &::after, &:focus-visible) and lh units that are normally handled via the
repo’s PostCSS build. Because the CSS build only processes css/src/**/*.css, this module bypasses
that pipeline and may ship unsupported syntax to some browsers, causing the sort buttons/indicators
to render incorrectly.
Code

taccsite_cms/static/site_cms/css/modules/sortableTable.css[R7-44]

Evidence
The stylesheet is served directly from css/modules/, but the build script only compiles
css/src/**/*.css into css/build, so this file will not be transformed by PostCSS even though it
uses nested selector syntax.

taccsite_cms/templates/assets_core_delayed.html[10-27]
taccsite_cms/static/site_cms/css/modules/sortableTable.css[7-44]
bin/build-css.js[14-31]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`taccsite_cms/static/site_cms/css/modules/sortableTable.css` is linked directly from the template but is authored using nested CSS (`&` selectors) and modern units (`1lh`). This file is outside the CSS build input glob, so it will not receive the same PostCSS transforms as the rest of the project’s CSS.
## Issue Context
The repo’s CSS build step (`bin/build-css.js`) only builds `taccsite_cms/static/site_cms/css/src/**/*.css` into `.../css/build`. The new stylesheet is placed under `.../css/modules/` and linked directly in `assets_core_delayed.html`.
## Fix Focus Areas
- taccsite_cms/static/site_cms/css/modules/sortableTable.css[7-44]
- taccsite_cms/templates/assets_core_delayed.html[10-27]
- bin/build-css.js[14-31]
## Suggested fix approaches (pick one)
1. **Move into build pipeline**: relocate the stylesheet into `taccsite_cms/static/site_cms/css/src/_imports/components/` (or similar), import it from `css/src/core-cms.css`, rebuild, and remove the direct `<link>`.
2. **Keep as standalone but make it plain CSS**: rewrite the file to fully-expanded selectors (no nesting) and replace/avoid `1lh` (use a compatible fallback, e.g. `1em` or omit the height rule).
3. **Expand build inputs**: adjust the CSS build script to also process `css/modules/**/*.css` into `css/build` and update the template to load the built artifact instead of the raw module.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

Comment thread taccsite_cms/static/site_cms/js/modules/sortableTable.js
wesleyboar and others added 2 commits June 1, 2026 17:21
Return empty sort keys and warn in the console so CMS editors can fix markup.

Co-authored-by: Cursor <cursoragent@cursor.com>
Pair sortableTable.css with JS; use table.is-sortable and c-button--as-link.
Note Core-Components as future home.

Co-authored-by: Cursor <cursoragent@cursor.com>
@wesleyboar wesleyboar changed the title feat(cms): sortable table for Research/Software project listings feat(cms): sortable table Jun 2, 2026
@wesleyboar wesleyboar changed the title feat(cms): sortable table feat(cms): sortable table (for TACC project pages redesign) Jun 2, 2026
wesleyboar added a commit to TACC/Core-Styles that referenced this pull request Jun 2, 2026
## Overview

Skins Django CMS Bootstrap 4 Alert plugin output using `x-message`.

## Related

- [RT
#42216](https://tickets.tacc.utexas.edu/Ticket/Display.html?id=42216)
- required by TACC/tup-ui#558
- pairs with TACC/Core-CMS#1167

## Changes

- **added** Bootstrap 4 `alert` component

## Testing

1. `npm run build:css`
2. `npm start`
3. Open the [Bootstrap 4 Alerts
demo](http://localhost:3000/components/detail/alert).
4. Review styles.
5. Compare to [C Message
demo](http://localhost:3000/components/detail/c-message--type).

## UI

| Alerts | Primary Alert = Global Message |
| - | - |
| <img width="1066" height="1581" alt="Alerts"
src="https://github.com/user-attachments/assets/9567db25-6ec6-4ad1-af7c-a3684a23187a"
/> | <img width="900" height="470" alt="Primary Alert : Global Message"
src="https://github.com/user-attachments/assets/a78f31a7-76a1-4ae6-8f01-027e0259af84"
/> |


https://github.com/user-attachments/assets/87f3f3f7-f642-41de-a0f7-8ceca25fcba3

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
@wesleyboar wesleyboar marked this pull request as ready for review June 2, 2026 23:22
@qodo-code-review

qodo-code-review Bot commented Jun 2, 2026

Copy link
Copy Markdown

Code review by qodo was updated up to the latest commit 044a1b5

@wesleyboar

Copy link
Copy Markdown
Member Author

Approving, so —

  1. solution is saved in working state
  2. I can demo

— but I really should replace with tristen/tablesort.

@wesleyboar wesleyboar merged commit 22f6eb2 into main Jun 2, 2026
@wesleyboar wesleyboar deleted the feat/research-software-cms-phase-b branch June 2, 2026 23:31
wesleyboar added a commit that referenced this pull request Jun 8, 2026
## Overview

Sortable CMS tables use List.js 2.3.1 instead of custom sort logic.
Editors use `js-sortable` on the table and `not-sortable` on non-sort
columns; row order stays as authored until a header is clicked.

## Related

- [RT
#42216](https://tickets.tacc.utexas.edu/Ticket/Display.html?id=42216)
- closes #1168
- supersedes #1167
- required by TACC/tup-ui#558

## Changes

- **added** List.js 2.3.1 from jsDelivr in delayed assets (SRI)
- **refactored** `sortableTable.js` for List prep, row `data-*`,
aria-sort sync
- **updated** `sortableTable.css` for `js-sortable` and `.sort` controls

## Testing

1. Deploy or load delayed assets with List.js + `sortableTable` on
`#cms-content`.
2. Use a table with `o-fixed-header-table js-sortable` and
`th.not-sortable` on Description.
3. On load: CMS row order, all `aria-sort="none"`.
    <sup>⚠️ CMS strips `data-attribute`.</sup>
4. Click headers: sort toggles; other columns reset to `none`.
5. Column with link in cell sorts on link text.
6. Add `<fieldset>` with filter UI (see `tmp/pr-1169.html`).
7. Verify filtering works.

## UI


https://github.com/user-attachments/assets/52ab6aed-2e43-47f1-be46-6df493128f86

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
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