Skip to content

feat(RHINENG-25194): CVE Table migration to new library#2587

Closed
Siasurai wants to merge 7 commits into
RedHatInsights:masterfrom
Siasurai:RHINENG-25194
Closed

feat(RHINENG-25194): CVE Table migration to new library#2587
Siasurai wants to merge 7 commits into
RedHatInsights:masterfrom
Siasurai:RHINENG-25194

Conversation

@Siasurai
Copy link
Copy Markdown
Contributor

@Siasurai Siasurai commented Apr 29, 2026

What

  • New CVEs table (using bastilian-tabletools): moving to a new table library, but we keep the old table working.
  • Feature flag vulnerability.table-tools: switch between the old and the new table safely.
  • New hook useCvesPage: puts all CVEs page logic (data load, URL params, columns, modals, context) in one place, so CVEs.js is mostly UI.
  • React Query update: moved from cacheTime to gcTime (React Query v5 change).
  • Redux + React Query sync: added SYNC_CVE_LIST_FROM_QUERY so data from React Query is saved in the store and table actions still work.
  • Row expand fix: expand/collapse now uses the CVE id, not the row index, so it works the same in both tables.
  • Better URL params handling: useUrlParams is memoized and CVEs page has a clear allowed params list, to avoid extra updates.
  • Tests/Cypress updates: added mocks and new tests for the new table, and added QueryClientProvider in Cypress.
  • Less network calls: added paramsInitialized so we don’t send an extra “first” request before default/URL params are applied.

How to test

  1. Open the CVEs page in the app
  2. Enable the new table by turning on the feature flag vulnerability.table-tools Reload the page and check:
  3. Sorting works (click a column header, check the request sort= changes).
  4. Pagination works (go to next page, check page/page_size or offset/limit changes depending on table mode).
  5. Expand a row (Details caret) and collapse it.
  6. Select a row checkbox (if selection is enabled for your user/env).
  7. Apply a filter in the toolbar and confirm the table updates and the URL query params update.
  8. Compare with old table: turn off vulnerability.table-tools, reload, and confirm the same actions still work.
  9. Only 1 CVEs list request: in DevTools → Network, you should see only 1 .../vulnerabilities/cves request after load.
Screenshot 2026-04-30 at 10 52 52

Summary by Sourcery

Introduce a new feature-flagged CVE table implementation using bastilian-tabletools while centralizing CVEs page logic into a dedicated hook and updating data-fetching and state sync behavior.

New Features:

  • Add a new CVEs table implementation built on bastilian-tabletools and a shared VulnerabilityTable wrapper component, gated by the vulnerability.table-tools feature flag.
  • Introduce the useCvesPage hook to encapsulate CVEs page data loading, URL parameter handling, column management, and modal/state management.
  • Add React Query–based integration for fetching the CVE list via table tools and syncing results into the existing Redux store, including a new useCveTableToolsQuery hook and SYNC_CVE_LIST_FROM_QUERY action.
  • Support JSONQuery-based serialization for filters, sorting, and pagination in the new table implementation.

Bug Fixes:

  • Ensure CVE row expand/collapse is driven by CVE IDs instead of row indexes and behaves correctly even when Redux list data is absent.
  • Stabilize URL parameter handling by memoizing useUrlParams and clearly constraining allowed CVEs page query params.
  • Make createCveListByAccount resilient to null/partial payloads to avoid crashes on missing data.
  • Align filter chips and export behavior in Cypress tests with the current toolbar markup and labels.
  • Normalize legacy affecting=true parameters to the correct active filter chip representation.

Enhancements:

  • Refactor CVEs.js to be primarily presentational by moving business logic into reusable hooks and context, while retaining the legacy table path.
  • Update React Query client configuration to use gcTime instead of cacheTime in line with React Query v5.
  • Improve handling of operating systems and column visibility (including Applies to OS) via centralized column management.
  • Add helpers for CVE table empty-state messaging and sortable/expandable header construction shared between legacy and new tables.

Build:

  • Add bastilian-tabletools, React Query v5, supporting libraries (e.g., use-deep-compare, @tanstack/react-pacer, @jsonquerylang/jsonquery, p-all), and related configuration updates to package.json.

Tests:

  • Extend Jest and Cypress tests to cover the new tabletools-based CVEs table, React Query wiring, URL param behavior, reducer sync action, and row expansion by CVE ID.
  • Update test utilities to mock bastilian-tabletools, wire QueryClientProvider into Cypress mountWithContext, and relax some strict action count assertions.

@Siasurai Siasurai self-assigned this Apr 29, 2026
@RedHatInsights RedHatInsights deleted a comment from sourcery-ai Bot Apr 29, 2026
@Siasurai Siasurai marked this pull request as ready for review April 30, 2026 08:54
@Siasurai Siasurai requested a review from a team as a code owner April 30, 2026 08:54
Copy link
Copy Markdown

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 2 issues, and left some high level feedback:

  • In useCvesPage, there is a console.log in a useEffect that will fire in production; consider removing it or routing through whatever logging/telemetry mechanism you normally use to avoid noisy console output.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `useCvesPage`, there is a `console.log` in a `useEffect` that will fire in production; consider removing it or routing through whatever logging/telemetry mechanism you normally use to avoid noisy console output.

## Individual Comments

### Comment 1
<location path="src/Helpers/tableToolsSerialisers.js" line_range="9-10" />
<code_context>
+  }
+};
+
+const textFilterSerialiser = (filterConfigItem, value) =>
+  ƒ`regex(.${filterConfigItem.filterAttribute}, "${value}", "i")`;
+const checkboxFilterSerialiser = (filterConfigItem, values) =>
+  `.${filterConfigItem.filterAttribute} in [${values
</code_context>
<issue_to_address>
**issue (bug_risk):** The text filter serialiser contains an invalid character and will not compile.

Please replace the `ƒ` usage with a valid function or template-literal syntax. For example:

```js
const textFilterSerialiser = (filterConfigItem, value) =>
  `regex(.${filterConfigItem.filterAttribute}, "${value}", "i")`;
```

or adjust the string format to whatever the table tools query engine expects.
</issue_to_address>

### Comment 2
<location path="src/Components/SmartComponents/CVEs/useCveTableTableToolsState.js" line_range="29-44" />
<code_context>
+
+  const isEmpty = cves.data.length === 0;
+
+  const emptyRows = useMemo(
+    () => [
+      {
+        heightAuto: true,
+        cells: [
+          {
+            props: { colSpan: header?.length },
+            title: <EmptyStateNoCVEs secondParagraph={emptyMessage} />,
+          },
</code_context>
<issue_to_address>
**suggestion (bug_risk):** Empty-state row colSpan may not cover the selection/expand columns.

`emptyRows` uses `colSpan: header?.length`, but the table can render extra columns for expand/selection (`isExpandable`, `canCollapseAll`, `canSelectAll`). This can leave the empty-state cell too narrow. Please derive `colSpan` from the full rendered column count (including expand/selection), e.g. by computing it from the same header structure as `buildCveExpandableSortHeader` rather than `header.length` alone.

```suggestion
  const isEmpty = cves.data.length === 0;

  const emptyRows = useMemo(
    () => [
      {
        heightAuto: true,
        cells: [
          {
            props: { colSpan: sortHeaderWithCollapse?.length },
            title: <EmptyStateNoCVEs secondParagraph={emptyMessage} />,
          },
        ],
      },
    ],
    [emptyMessage, sortHeaderWithCollapse?.length],
  );
```
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

import { SkeletonTable } from '@patternfly/react-component-groups';
import { useCveTableTableToolsState } from './useCveTableTableToolsState';

const CVEsTableTableToolsInner = ({ header }) => {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What was the reason for building a custom table? As far as i can see this seems to only replicate https://github.com/bastilian/tabletools/blob/main/src/components/TableToolsTable/TableToolsTable.js#L20

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😶‍🌫️ To be honest, there wasn’t a deeper reason. I ran into issues while wiring everything up, so I debugged it step by step and then I forgot to switch the manual Table over to TableToolsTable. Sorry, that’s on me (and my short memory)

I’ll take this back as a follow-up refactor to use the proper component.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cleaned it up, it should be better overall now

@RedHatInsights RedHatInsights deleted a comment from sourcery-ai Bot Apr 30, 2026
@Siasurai Siasurai marked this pull request as draft April 30, 2026 11:54
@RedHatInsights RedHatInsights deleted a comment from sourcery-ai Bot Apr 30, 2026
@RedHatInsights RedHatInsights deleted a comment from sourcery-ai Bot Apr 30, 2026
@Siasurai Siasurai marked this pull request as ready for review April 30, 2026 13:02
Copy link
Copy Markdown

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 1 issue, and left some high level feedback:

  • The useCveTableToolsQuery hook uses a fixed queryKey: ['cveListByAccount', 'tableTools'] while passing params separately; if useQueryWithUtilities keys only by queryKey this will cause different parameter combinations to share cache, so consider incorporating params (or a stable hash of them) into the query key to avoid stale or mixed results.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The `useCveTableToolsQuery` hook uses a fixed `queryKey: ['cveListByAccount', 'tableTools']` while passing `params` separately; if `useQueryWithUtilities` keys only by `queryKey` this will cause different parameter combinations to share cache, so consider incorporating `params` (or a stable hash of them) into the query key to avoid stale or mixed results.

## Individual Comments

### Comment 1
<location path="src/Helpers/tableToolsSerialisers.js" line_range="9-10" />
<code_context>
+  }
+};
+
+const textFilterSerialiser = (filterConfigItem, value) =>
+  ƒ`regex(.${filterConfigItem.filterAttribute}, "${value}", "i")`;
+const checkboxFilterSerialiser = (filterConfigItem, values) =>
+  `.${filterConfigItem.filterAttribute} in [${values
</code_context>
<issue_to_address>
**issue (bug_risk):** The text filter serialiser uses an undefined template tag `ƒ`, which will cause a runtime error.

In `textFilterSerialiser`, ``ƒ`regex(...)` `` is parsed as a tagged template using an identifier `ƒ` that is never defined, so this will throw at runtime when invoked. If this should just be a normal template string, remove the tag:

```js
const textFilterSerialiser = (filterConfigItem, value) =>
  `regex(.${filterConfigItem.filterAttribute}, "${value}", "i")`;
```

If a tagged template was intended, please add and import the `ƒ` tag implementation.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines +9 to +10
const textFilterSerialiser = (filterConfigItem, value) =>
ƒ`regex(.${filterConfigItem.filterAttribute}, "${value}", "i")`;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): The text filter serialiser uses an undefined template tag ƒ, which will cause a runtime error.

In textFilterSerialiser, ƒ`regex(...)` is parsed as a tagged template using an identifier ƒ that is never defined, so this will throw at runtime when invoked. If this should just be a normal template string, remove the tag:

const textFilterSerialiser = (filterConfigItem, value) =>
  `regex(.${filterConfigItem.filterAttribute}, "${value}", "i")`;

If a tagged template was intended, please add and import the ƒ tag implementation.

@RedHatInsights RedHatInsights deleted a comment from sourcery-ai Bot May 4, 2026
@Siasurai Siasurai marked this pull request as draft May 4, 2026 11:19
@Siasurai Siasurai closed this May 19, 2026
@Siasurai
Copy link
Copy Markdown
Contributor Author

#2642 WIP

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.

2 participants