Skip to content

Improve network modifications table rendering performance#3931

Merged
flomillot merged 10 commits into
mainfrom
perf/network-modifications-table-rendering
May 19, 2026
Merged

Improve network modifications table rendering performance#3931
flomillot merged 10 commits into
mainfrom
perf/network-modifications-table-rendering

Conversation

@flomillot
Copy link
Copy Markdown
Contributor

@flomillot flomillot commented May 4, 2026

Summary

Stop unmounting cells (and resetting their local state like SwitchCell's modificationActivated) on every columns rebuild by hoisting all cell/header renderers to module scope and routing dynamic values through react-table meta instead of closure capture.

  • Hoist renderers to a new cell-renderers.tsx (DragHandle, Select, Name, Description, Switch, RootNetwork).
    - Replace createBaseColumns factory with a static BASE_COLUMNS constant. POSTPONED due to merge conflicts
  • Build the columns array directly in the editor and pass it as a columns prop instead of a createAllColumns callback (depends on commons-ui PR).
  • Augment react-table TableMeta/ColumnMeta to type the meta channel.
  • Drop the optimistic global update from SwitchCell; the row state is refreshed by the server notification, and a local useState handles the immediate checkbox feedback with rollback on error.
  • Replace useState/useEffect in useIsAnyNodeBuilding with a direct selector.
  • Remove the now-broken inline debounce around handleCellClick.

Depends on gridsuite/commons-ui#perf/network-modifications-table-meta.

Stop unmounting cells (and resetting their local state like SwitchCell's
modificationActivated) on every columns rebuild by hoisting all cell/header
renderers to module scope and routing dynamic values through react-table
meta instead of closure capture.

- Hoist renderers to a new cell-renderers.tsx (DragHandle, Select, Name,
  Description, Switch, RootNetwork)
- Replace createBaseColumns factory with a static BASE_COLUMNS constant
- Build the columns array directly in the editor and pass it as a `columns`
  prop instead of a createAllColumns callback
- Augment react-table TableMeta/ColumnMeta to type the meta channel
- Drop the optimistic global update from SwitchCell; the row state is
  refreshed by the server notification, and a local useState handles the
  immediate checkbox feedback with rollback on error
- Replace useState/useEffect in useIsAnyNodeBuilding with a direct selector
- Remove the now-broken inline debounce around handleCellClick

Signed-off-by: Florent MILLOT <florent.millot_externe@rte-france.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 4, 2026

Review Change Stack

Warning

Rate limit exceeded

@flomillot has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 41 minutes and 52 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 5cba47dd-6da0-4dc9-ae0d-eb007e9d7d5e

📥 Commits

Reviewing files that changed from the base of the PR and between 0406c96 and 8de1f23.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (5)
  • package.json
  • src/components/graph/menus/network-modifications/network-modification-node-editor.tsx
  • src/components/graph/menus/network-modifications/network-modification-table/createColumns.tsx
  • src/components/graph/menus/network-modifications/network-modification-table/renderers/cell-renderers.tsx
  • src/module-tanstack.d.ts
📝 Walkthrough

Walkthrough

The PR extracts table cell/header renderers, exports a constant BASE_COLUMNS, updates root-network column creation to pass per-column meta, expands react-table metadata types, moves switch activation handling to local state with API calls, simplifies a hook to use a selector, and wires computed columns into the node editor without debouncing.

Changes

Network Modification Table Rendering & State Refactor

Layer / File(s) Summary
Type Augmentations
src/module-tanstack.d.ts
TableMeta<TData> extended with isRowDragDisabled, modificationsCount, and nameHeaderProps. New ColumnMeta<TData, TValue> interface added for per-column styling (cellStyle), root network metadata (rootNetwork, isCurrentRootNetwork, currentRootNetworkTag), and modification exclusion state/actions (modificationsToExclude, setModificationsToExclude).
Column Definitions
src/components/graph/menus/network-modifications/network-modification-table/createColumns.tsx
createBaseColumns factory replaced with exported constant BASE_COLUMNS using renderer-based cell/header entries and meta.cellStyle values. createRootNetworksColumns signature updated to accept modification exclusion props instead of modificationsCount, and delegates header/cell rendering to dedicated renderer components via meta.
Renderer Components
src/components/graph/menus/network-modifications/network-modification-table/renderers/cell-renderers.tsx
New file exports renderer functions (DragHandleRenderer, SelectHeaderRenderer, SelectCellRenderer, NameHeaderRenderer, NameCellRenderer, DescriptionCellRenderer, SwitchCellRenderer, RootNetworkHeaderRenderer, RootNetworkCellRenderer) that conditionally render UI based on CellContext/HeaderContext and column/table metadata.
Node Editor Wiring
src/components/graph/menus/network-modifications/network-modification-node-editor.tsx
Columns are now built via useMemo from BASE_COLUMNS and conditional createRootNetworksColumns (instead of createAllColumns callback). NetworkModificationsTable receives computed columns prop; handleCellClick passed directly without debounce wrapping. Removed imports: debounce from @mui/material, SetStateAction from React.
Cell Toggle Logic
src/components/graph/menus/network-modifications/network-modification-table/renderers/switch-cell.tsx
SwitchCellRendererProps narrowed to data only. Switch toggle now maintains local state (modificationActivated) synced via useEffect, calls setModificationMetadata with activation change, rolls back on error, and uses onChange instead of onClick. Removed tree manipulation logic (setModifications, tree-update helpers).
Hook Simplification
src/components/utils/is-any-node-building-hook.ts
useIsAnyNodeBuilding refactored from local useState/useEffect to direct Redux useSelector, returning state.networkModificationTreeModel?.isAnyNodeBuilding ?? false.

Suggested reviewers

  • Mathieu-Deharbe
  • souissimai
  • Meklo
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main objective of the changeset: improving rendering performance of the network modifications table by hoisting renderers and refactoring the columns mechanism.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description check ✅ Passed The pull request description accurately describes the changeset, detailing renderer hoisting, meta channel augmentation, and refactoring work that aligns with the actual file modifications.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/components/graph/menus/network-modifications/network-modification-node-editor.tsx (1)

1082-1095: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Non-null assertion on currentRootNetworkUuid could mask a runtime null.

currentRootNetworkUuid! is only evaluated when isMonoRootStudy is false, but there's a potential initial-state window where isMonoRootStudy is already false while currentRootNetworkUuid hasn't been populated yet. If that occurs, createRootNetworksColumns receives null cast as string, and the rootNetworkUuid === currentRootNetworkUuid comparison inside the function would silently fail (all isCurrentRootNetwork values would be false).

Consider guarding the call:

🔧 Proposed guard
-            : createRootNetworksColumns(
-                  rootNetworks,
-                  currentRootNetworkUuid!,
-                  modificationsToExclude,
-                  setModificationsToExclude
-              )),
+            : currentRootNetworkUuid
+              ? createRootNetworksColumns(
+                    rootNetworks,
+                    currentRootNetworkUuid,
+                    modificationsToExclude,
+                    setModificationsToExclude
+                )
+              : []),
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@src/components/graph/menus/network-modifications/network-modification-node-editor.tsx`
around lines 1082 - 1095, The code currently passes currentRootNetworkUuid with
a non-null assertion into createRootNetworksColumns inside the columns useMemo;
instead, guard the call so createRootNetworksColumns is only invoked when
isMonoRootStudy is false AND currentRootNetworkUuid is defined (truthy), e.g.
branch so that when currentRootNetworkUuid is null/undefined the spread is an
empty array; reference the constants/identifiers columns, useMemo,
isMonoRootStudy, currentRootNetworkUuid and createRootNetworksColumns when
applying this check.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@src/components/graph/menus/network-modifications/network-modification-table/renderers/switch-cell.tsx`:
- Around line 52-58: The Promise chain uses optional chaining (?.catch) which
can short-circuit and cause a TypeError that prevents the finally block from
running; change the call to invoke the Promise directly (remove the ? operator)
so that setModificationMetadata(...) returns a Promise and you call .catch(...)
and .finally(...) on it; keep the existing rollback via
setModificationActivated(data?.activated), the error reporting via
snackWithFallback(snackError, error, { headerId:
'networkModificationActivationError' }), and the setIsLoading(false) in finally
to guarantee isLoading is always cleared.

---

Outside diff comments:
In
`@src/components/graph/menus/network-modifications/network-modification-node-editor.tsx`:
- Around line 1082-1095: The code currently passes currentRootNetworkUuid with a
non-null assertion into createRootNetworksColumns inside the columns useMemo;
instead, guard the call so createRootNetworksColumns is only invoked when
isMonoRootStudy is false AND currentRootNetworkUuid is defined (truthy), e.g.
branch so that when currentRootNetworkUuid is null/undefined the spread is an
empty array; reference the constants/identifiers columns, useMemo,
isMonoRootStudy, currentRootNetworkUuid and createRootNetworksColumns when
applying this check.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: ee78b7ad-c00f-46cf-ac9f-34d80fabc9f7

📥 Commits

Reviewing files that changed from the base of the PR and between 2cadf5f and 7dc74d2.

📒 Files selected for processing (7)
  • src/components/graph/menus/network-modifications/PERF-ANALYSIS.md
  • src/components/graph/menus/network-modifications/network-modification-node-editor.tsx
  • src/components/graph/menus/network-modifications/network-modification-table/createColumns.tsx
  • src/components/graph/menus/network-modifications/network-modification-table/renderers/cell-renderers.tsx
  • src/components/graph/menus/network-modifications/network-modification-table/renderers/switch-cell.tsx
  • src/components/utils/is-any-node-building-hook.ts
  • src/module-tanstack.d.ts

flomillot added 2 commits May 5, 2026 10:31
Signed-off-by: Florent MILLOT <florent.millot_externe@rte-france.com>
- Clarify the importance of stable references for cell/header renderers.
- Update explanatory comments about renderers' scope and usage in react-table.

Signed-off-by: Florent MILLOT <florent.millot_externe@rte-france.com>
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@src/components/graph/menus/network-modifications/network-modification-table/renderers/switch-cell.tsx`:
- Around line 32-37: The local state modificationActivated and its updater
setModificationActivated are initialized and synced from data?.activated which
may be undefined and cause a controlled/uncontrolled Switch; coerce values to a
strict boolean when setting state and in the useEffect (e.g. wrap
data?.activated with !!) and also update the other occurrence at the second
state sync (around line referenced 53) so the Switch always receives true/false.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: e029946e-ff44-4265-a792-b73be09bcb75

📥 Commits

Reviewing files that changed from the base of the PR and between 7dc74d2 and a5e6c00.

📒 Files selected for processing (2)
  • src/components/graph/menus/network-modifications/network-modification-table/renderers/cell-renderers.tsx
  • src/components/graph/menus/network-modifications/network-modification-table/renderers/switch-cell.tsx
✅ Files skipped from review due to trivial changes (1)
  • src/components/graph/menus/network-modifications/network-modification-table/renderers/cell-renderers.tsx


const toggleModificationActive = useCallback(() => {
setIsLoading(true);
setModifications((oldModifications) => {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

No risk of stale data if we remove the dataset update ? Although that may have been part of the perf issues I guess

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.

What do you mean exactly ? Do you have an example ? If you're talking about this set modification, it was useless because it was already updated right after by server notification.

Copy link
Copy Markdown
Contributor

@Meklo Meklo May 19, 2026

Choose a reason for hiding this comment

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

I mean up until now the state of the component was directly derived from the value contained in the dataset and with this change it is now driven by a state which replicates the dataset value. That said maybe it was part of the issue

Comment thread src/module-tanstack.d.ts
// Read at runtime via `column.columnDef.meta` (per-column).
// TData / TValue must match the original generic signature of ColumnMeta for the
// module-augmentation merge to apply. They aren't referenced in this body, hence the disable.
// eslint-disable-next-line @typescript-eslint/no-unused-vars
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

It may be relevant to ignore d.ts files for no-unused-vars rule in eslint config

@flomillot flomillot requested a review from Meklo May 13, 2026 13:01
flomillot added 2 commits May 13, 2026 17:10
The per-row cells, the cell-renderers adapter, the two services
(setModificationMetadata, updateModificationStatusByRootNetwork) and the
@tanstack/react-table module augmentation that they relied on have moved
to commons-ui. Local files are deleted and createColumns now imports the
renderers from commons-ui. createRootNetworksColumns is simplified: it
only needs the root-networks list since the rest of the per-column meta
(rootNetwork, modificationsToExclude, isCurrentRootNetwork,
currentRootNetworkTag) is now derived from TableMeta. The node editor
passes studyUuid, currentNodeId, currentRootNetworkUuid, rootNetworks,
modificationsToExclude, setModificationsToExclude and a combined
isDisabled (isAnyNodeBuilding || mapDataLoading) to NetworkModificationsTable.

Signed-off-by: Florent MILLOT <75525996+flomillot@users.noreply.github.com>
flomillot and others added 5 commits May 19, 2026 17:14
…rendering

# Conflicts:
#	src/components/graph/menus/network-modifications/network-modification-node-editor.tsx
#	src/components/graph/menus/network-modifications/network-modification-table/createColumns.tsx
Thread the optimistic name edit handler through the NAME column's
ColumnMeta (same pattern as createRootNetworksColumns) instead of the
previously removed createBaseColumns parameter.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: Florent MILLOT <75525996+flomillot@users.noreply.github.com>
Signed-off-by: Florent MILLOT <75525996+flomillot@users.noreply.github.com>
Signed-off-by: Florent MILLOT <75525996+flomillot@users.noreply.github.com>
@sonarqubecloud
Copy link
Copy Markdown

@flomillot flomillot merged commit 0612baa into main May 19, 2026
5 checks passed
@flomillot flomillot deleted the perf/network-modifications-table-rendering branch May 19, 2026 16:44
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