Actions: Add expandLevel parameter to configure tree depth#33977
Actions: Add expandLevel parameter to configure tree depth#33977valentinpalkovic merged 3 commits intostorybookjs:nextfrom
Conversation
Fixes storybookjs#22390 The react-inspector's `Inspector` component supports an `expandLevel` prop that controls how deep the action tree is initially expanded. This makes it configurable via story parameters. Example usage: ```ts const meta = { parameters: { actions: { expandLevel: 2 }, }, }; ```
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughAdds an optional Changes
Sequence Diagram(s)sequenceDiagram
participant API as Storybook API
participant Container as ActionLogger Container
participant Component as ActionLogger Component
participant Inspector as ThemedInspector
API->>Container: mount / provide params
Container->>API: useParameter(PARAM_KEY) => expandLevel
Container->>API: register EVENT_ID listener
Container->>API: register STORY_CHANGED listener
API->>Container: EVENT_ID (new action)
Container->>Container: addAction (dedupe/count/limit)
Container->>Component: props{ actions, expandLevel, onClear }
Component->>Inspector: render with expandLevel
Component->>Container: onClear()
Container->>API: emit CLEAR_ID
Container->>Container: reset actions
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes 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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@code/core/src/actions/containers/ActionLogger/index.tsx`:
- Around line 49-51: Create a single normalized resolver for the expandLevel
parameter so invalid values can't reach state: add a helper function (e.g.,
normalizeExpandLevel) that reads the raw value via
api.getCurrentParameter<ActionsParameters['actions']>(PARAM_KEY), coerces it to
a safe integer >= 1 (handle NaN, floats, negatives by using Number conversion
and Math.floor or default to 1), and then use that helper wherever expandLevel
is set (replace the inline reads before this.setState and at the other
occurrence around the lines using expandLevel); ensure calls reference the
PARAM_KEY and update setState({ expandLevel }) with the sanitized value.
ℹ️ Review info
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
code/core/src/actions/components/ActionLogger/index.tsxcode/core/src/actions/containers/ActionLogger/index.tsxcode/core/src/actions/types.ts
valentinpalkovic
left a comment
There was a problem hiding this comment.
LGTM! Thanks for your contribution :)
|
Hi @mixelburg Thank you for your contribution! When trying it out, the solution unfortunately didn't work. I think it had something to do with |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
code/core/src/actions/containers/ActionLogger/index.tsx (1)
51-65: Frequent re-subscription due tohandleStoryChangedepending onactions.Since
handleStoryChangeincludesactionsin its dependency array, it recreates on every action addition. This triggers theuseEffectto unsubscribe and resubscribe toSTORY_CHANGED, which is inefficient and could miss events during the transition window.Use a ref to access the latest actions without triggering callback recreation:
Proposed fix using ref pattern
+import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'; -import React, { useCallback, useEffect, useMemo, useState } from 'react';export default function ActionLogger({ active, api }: ActionLoggerProps) { const [actions, setActions] = useState<ActionDisplay[]>([]); + const actionsRef = useRef<ActionDisplay[]>(actions); const parameter = useParameter<ActionsParameters['actions']>(PARAM_KEY); const expandLevel = parameter?.expandLevel ?? 1; + useEffect(() => { + actionsRef.current = actions; + }, [actions]); + // ... clearActions and addAction unchanged ... const handleStoryChange = useCallback(() => { - if (actions.length > 0 && actions[0].options.clearOnStoryChange) { + if (actionsRef.current.length > 0 && actionsRef.current[0].options.clearOnStoryChange) { clearActions(); } - }, [actions, clearActions]); + }, [clearActions]); useEffect(() => { api.on(EVENT_ID, addAction); api.on(STORY_CHANGED, handleStoryChange); return () => { api.off(EVENT_ID, addAction); api.off(STORY_CHANGED, handleStoryChange); }; }, [api, addAction, handleStoryChange]);🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@code/core/src/actions/containers/ActionLogger/index.tsx` around lines 51 - 65, handleStoryChange currently depends on actions so it is recreated on every action add causing frequent api (STORY_CHANGED) unsubscribe/resubscribe; fix by storing the latest actions in a ref (e.g., actionsRef) and update that ref whenever actions change, then rewrite handleStoryChange to read actionsRef.current and call clearActions if needed (remove actions from handleStoryChange deps), keep clearActions, addAction and api in the outer useEffect deps so the effect no longer resubscribes on every action addition.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@code/core/src/actions/containers/ActionLogger/index.tsx`:
- Around line 37-49: The updater in addAction mutates objects: newActions uses a
shallow copy so modifying previous.count and action.count mutates prior state
and the incoming object; fix by creating new objects instead of mutating—when
merging with the previous entry construct a new object (e.g., copy previous and
increment its count) and when pushing the incoming action create a newAction
copy with count = 1 rather than assigning to action.count; also change the final
slice to slice(-action.options.limit) (or handle undefined safely) so the most
recent actions are retained; reference addAction, setActions, previous,
safeDeepEqual, and action.options.limit when applying these changes.
---
Nitpick comments:
In `@code/core/src/actions/containers/ActionLogger/index.tsx`:
- Around line 51-65: handleStoryChange currently depends on actions so it is
recreated on every action add causing frequent api (STORY_CHANGED)
unsubscribe/resubscribe; fix by storing the latest actions in a ref (e.g.,
actionsRef) and update that ref whenever actions change, then rewrite
handleStoryChange to read actionsRef.current and call clearActions if needed
(remove actions from handleStoryChange deps), keep clearActions, addAction and
api in the outer useEffect deps so the effect no longer resubscribes on every
action addition.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: e446d712-c23d-46a5-9eee-e7cdb2c63acf
📒 Files selected for processing (1)
code/core/src/actions/containers/ActionLogger/index.tsx
Package BenchmarksCommit: No significant changes detected, all good. 👏 |
What this PR does
Adds an
expandLevelparameter to the actions addon configuration, allowing users to control how deep the action object tree is initially expanded in the panel.The addon uses react-inspector's
Inspectorcomponent which already supports anexpandLevelprop — this PR exposes it as a configurable story parameter.How to use
The default value is
1(same as before — no visible change for existing users).Closes
Closes #22390
Summary by CodeRabbit
New Features
Refactor
Documentation