refactor: Fix ui flashes from on prop changes#1812
Conversation
|
Important Review skippedAuto incremental reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
WalkthroughFive frontend components refactor state management from useEffect-based initialization and effects to render-time conditionals and local state tracking. AnimatedProviderSteps detects completion transitions to set elapsed time, OnboardingStep synchronizes text/visibility/completion state during render, UnifiedCloudPicker inlines OneDrive URL detection, and TaskDialogFileList and useTaskDialog hook consolidate state resets into conditional blocks instead of effect watchers. ChangesRender-time state synchronization refactor
Possibly related PRs
Suggested labels
Suggested reviewers
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
frontend/components/cloud-picker/unified-cloud-picker.tsx (1)
31-31:⚠️ Potential issue | 🟠 MajorFix stale
effectiveBaseUrlcaused by persistedautoBaseUrlwhen switching providers
unified-cloud-picker.tsxstores OneDrive’s fallback in component state (autoBaseUrl) and deriveseffectiveBaseUrlasbaseUrl || autoBaseUrl. Since there’s no reset whenproviderchanges away from"onedrive",createProviderHandler(provider, ..., effectiveBaseUrl)can receive the OneDrive picker URL for subsequent providers whilebaseUrlis still unset.Suggested fix
- const [autoBaseUrl, setAutoBaseUrl] = useState<string | undefined>(undefined); - - const effectiveBaseUrl = baseUrl || autoBaseUrl; - - if (provider === "onedrive" && !baseUrl && accessToken && !autoBaseUrl) { - setAutoBaseUrl("https://onedrive.live.com/picker"); - } + const effectiveBaseUrl = + baseUrl ?? + (provider === "onedrive" && accessToken + ? "https://onedrive.live.com/picker" + : undefined);🤖 Prompt for 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. In `@frontend/components/cloud-picker/unified-cloud-picker.tsx` at line 31, The stale OneDrive URL comes from storing OneDrive’s fallback in state (autoBaseUrl) and using effectiveBaseUrl = baseUrl || autoBaseUrl even after provider changes; update the component so autoBaseUrl is cleared or ignored when provider !== "onedrive" — e.g., add a useEffect that watches provider and sets setAutoBaseUrl(undefined) whenever provider changes away from "onedrive", or only pass a OneDrive-specific effectiveBaseUrl into createProviderHandler(provider, ..., effectiveBaseUrl) by computing effectiveBaseUrl conditionally (use baseUrl || autoBaseUrl only if provider === "onedrive"); ensure references to autoBaseUrl, effectiveBaseUrl and createProviderHandler are updated accordingly.
🤖 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 `@frontend/app/onboarding/_components/animated-provider-steps.tsx`:
- Around line 30-38: The component seeds prevIsCompleted incorrectly and never
handles the true->false transition; change initialization of prevIsCompleted so
it does not start from the incoming isCompleted prop (initialize false) and
replace the inline if-block with a useEffect that watches isCompleted and
processingStartTime: when isCompleted becomes true && prevIsCompleted is false,
setElapsedTime(Date.now() - processingStartTime) (guarding for undefined
processingStartTime) and setPrevIsCompleted(true); when isCompleted becomes
false, setPrevIsCompleted(false) so subsequent completions recompute
elapsedTime; update references to setPrevIsCompleted and setElapsedTime inside
that effect.
In `@frontend/app/onboarding/_components/onboarding-step.tsx`:
- Around line 38-40: On mount OnboardingStep currently initializes displayedText
and showChildren to empty/false which causes blank render when isVisible &&
isCompleted && !isMarkdown; change the initial state setup so displayedText
initializes to text and showChildren to true when props.isVisible &&
props.isCompleted && !props.isMarkdown (keep prev as before), and ensure the
typing useEffect still early-returns for completed cases—this guarantees
immediate full text and children on first render for the non-markdown completed
case.
---
Outside diff comments:
In `@frontend/components/cloud-picker/unified-cloud-picker.tsx`:
- Line 31: The stale OneDrive URL comes from storing OneDrive’s fallback in
state (autoBaseUrl) and using effectiveBaseUrl = baseUrl || autoBaseUrl even
after provider changes; update the component so autoBaseUrl is cleared or
ignored when provider !== "onedrive" — e.g., add a useEffect that watches
provider and sets setAutoBaseUrl(undefined) whenever provider changes away from
"onedrive", or only pass a OneDrive-specific effectiveBaseUrl into
createProviderHandler(provider, ..., effectiveBaseUrl) by computing
effectiveBaseUrl conditionally (use baseUrl || autoBaseUrl only if provider ===
"onedrive"); ensure references to autoBaseUrl, effectiveBaseUrl and
createProviderHandler are updated accordingly.
🪄 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: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: dc95ce7a-6ed6-40c3-8cad-df6606d2a5ee
📒 Files selected for processing (5)
frontend/app/onboarding/_components/animated-provider-steps.tsxfrontend/app/onboarding/_components/onboarding-step.tsxfrontend/components/cloud-picker/unified-cloud-picker.tsxfrontend/components/task-dialog/file-list.tsxfrontend/components/task-dialog/use-task-dialog.ts
| const [prevIsCompleted, setPrevIsCompleted] = useState(isCompleted); | ||
| const [elapsedTime, setElapsedTime] = useState<number>(0); | ||
|
|
||
| // Initialize start time from prop | ||
| useEffect(() => { | ||
| if (isCompleted && !prevIsCompleted) { | ||
| setPrevIsCompleted(true); | ||
| if (processingStartTime) { | ||
| // Use the start time passed from parent (when user clicked Complete) | ||
| setStartTime(processingStartTime); | ||
| setElapsedTime(Date.now() - processingStartTime); | ||
| } | ||
| }, [processingStartTime]); | ||
| } |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Locate and print the relevant portion of the file
FILE="frontend/app/onboarding/_components/animated-provider-steps.tsx"
echo "== File: $FILE =="
nl -ba "$FILE" | sed -n '1,200p'
# Focus on the specific lines mentioned (30-120 in case numbering differs)
echo
echo "== Focus: lines 20-90 =="
nl -ba "$FILE" | sed -n '20,90p'
# Extract any usage of isCompleted / processingStartTime within this component
echo
echo "== Search within file for isCompleted / processingStartTime =="
rg -n "isCompleted|processingStartTime|prevIsCompleted|elapsedTime|setElapsedTime" "$FILE" || trueRepository: langflow-ai/openrag
Length of output: 200
🏁 Script executed:
#!/bin/bash
set -euo pipefail
FILE="frontend/app/onboarding/_components/animated-provider-steps.tsx"
echo "== File exists? =="
if [[ -f "$FILE" ]]; then
echo "yes: $FILE"
else
echo "no: $FILE"
exit 0
fi
echo
echo "== Focus: lines 1-200 (with line numbers via awk) =="
awk '{printf "%6d %s\n", NR, $0}' "$FILE" | sed -n '1,200p'
echo
echo "== Search within file for relevant identifiers =="
rg -n "isCompleted|processingStartTime|prevIsCompleted|elapsedTime|setPrevIsCompleted|setElapsedTime" "$FILE" || true
echo
echo "== Show around prevIsCompleted initialization and completion logic =="
rg -n "prevIsCompleted|setPrevIsCompleted|setElapsedTime|processingStartTime" "$FILE" | head -n 50Repository: langflow-ai/openrag
Length of output: 10233
🏁 Script executed:
#!/bin/bash
set -euo pipefail
rg -n "AnimatedProviderSteps" -S frontend || true
# If we found usages, show surrounding code for the first few matches
# (Limit output to avoid noise)
matches=$(rg -n "AnimatedProviderSteps" -S frontend || true)
echo
echo "== Matched lines =="
echo "$matches" | head -n 50
# For each match file, print a small window around it
echo
echo "== Context around matches (first 50 lines) =="
echo "$matches" | head -n 10 | while read -r line; do
file=$(echo "$line" | cut -d: -f1)
lineno=$(echo "$line" | cut -d: -f2)
echo "-- $file:$lineno --"
# print 40 lines around the match
start=$((lineno-20)); end=$((lineno+20))
awk -v s=$start -v e=$end 'NR>=s && NR<=e {print NR ":" $0}' "$file" | sed -n '1,80p'
doneRepository: langflow-ai/openrag
Length of output: 8140
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Show relevant portions of onboarding-card.tsx around the AnimatedProviderSteps usage
FILE1="frontend/app/onboarding/_components/onboarding-card.tsx"
echo "== onboarding-card: AnimatedProviderSteps call context =="
awk 'NR>=700 && NR<=820 {print NR ":" $0}' "$FILE1"
# Search within onboarding-card for isCompleted / processingStartTime declarations and update sites
echo
echo "== onboarding-card: search for isCompleted / processingStartTime =="
rg -n "processingStartTime|isCompleted" "$FILE1" || true
# Show around the first few matches for each
echo
echo "== onboarding-card: show processingStartTime related blocks (first 80 matches neighborhood) =="
rg -n "processingStartTime" "$FILE1" | head -n 20 | while read -r line; do
lineno=$(echo "$line" | cut -d: -f1)
start=$((lineno-25)); end=$((lineno+25))
echo "-- $FILE1:$lineno --"
awk -v s=$start -v e=$end 'NR>=s && NR<=e {print NR ":" $0}' "$FILE1" | sed -n '1,120p'
done
echo
echo "== onboarding-card: show isCompleted related blocks (first 20 matches neighborhood) =="
rg -n "isCompleted" "$FILE1" | head -n 20 | while read -r line; do
lineno=$(echo "$line" | cut -d: -f1)
start=$((lineno-25)); end=$((lineno+25))
echo "-- $FILE1:$lineno --"
awk -v s=$start -v e=$end 'NR>=s && NR<=e {print NR ":" $0}' "$FILE1" | sed -n '1,120p'
done
# Show relevant portions of onboarding-upload.tsx around the AnimatedProviderSteps usage
FILE2="frontend/app/onboarding/_components/onboarding-upload.tsx"
echo
echo "== onboarding-upload: AnimatedProviderSteps call context =="
awk 'NR>=250 && NR<=420 {print NR ":" $0}' "$FILE2"
# Search within onboarding-upload for isCompleted / processingStartTime
echo
echo "== onboarding-upload: search for isCompleted / processingStartTime =="
rg -n "processingStartTime|isCompleted" "$FILE2" || trueRepository: langflow-ai/openrag
Length of output: 24623
🏁 Script executed:
#!/bin/bash
set -euo pipefail
FILE="frontend/app/onboarding/_components/onboarding-card.tsx"
echo "== Search for setProcessingStartTime =="
rg -n "setProcessingStartTime" "$FILE" || true
echo
echo "== Search for isCompleted state/derivation in this file =="
rg -n "isCompleted" "$FILE" | head -n 200
echo
echo "== Search for onComplete call sites in this file =="
rg -n "onComplete\(" "$FILE" || true
echo
echo "== Show around handleComplete definition area =="
# handleComplete likely contains setProcessingStartTime / onComplete.
handle_line=$(rg -n "const handleComplete" "$FILE" | head -n 1 | cut -d: -f1 || true)
if [[ -n "${handle_line:-}" ]]; then
start=$((handle_line-80)); end=$((handle_line+160))
awk -v s=$start -v e=$end 'NR>=s && NR<=e {print NR ":" $0}' "$FILE" | sed -n '1,200p'
else
echo "No handleComplete found"
fiRepository: langflow-ai/openrag
Length of output: 8353
🏁 Script executed:
#!/bin/bash
set -euo pipefail
rg -n "OnboardingCard" frontend/app/onboarding -S || true
rg -n "<OnboardingCard|OnboardingCard\s" frontend -S || trueRepository: langflow-ai/openrag
Length of output: 1141
🏁 Script executed:
#!/bin/bash
set -euo pipefail
FILE="frontend/app/onboarding/_components/onboarding-content.tsx"
echo "== File context (imports + around OnboardingCard usages) =="
awk 'NR>=180 && NR<=280 {print NR ":" $0}' "$FILE"
echo
echo "== Search within file for isCompleted props =="
rg -n "isCompleted" "$FILE" || true
echo
echo "== Search for key= on OnboardingCard elements =="
rg -n "<OnboardingCard[^>]*key=" "$FILE" || trueRepository: langflow-ai/openrag
Length of output: 4186
🏁 Script executed:
#!/bin/bash
set -euo pipefail
FILE="frontend/app/onboarding/_components/onboarding-content.tsx"
# Show file header + where currentStep is initialized
echo "== onboarding-content: search for currentStep state initialization =="
rg -n "currentStep" "$FILE" || true
echo
echo "== onboarding-content: show around currentStep useState/initialization =="
rg -n "useState<.*currentStep|useState\(.*currentStep|const \[currentStep" "$FILE" -S || true
echo
# Show near where handleStepComplete is defined
echo "== onboarding-content: search for handleStepComplete =="
rg -n "handleStepComplete" "$FILE" -S || true
echo
echo "== onboarding-content: show around handleStepComplete definition =="
line=$(rg -n "const handleStepComplete|function handleStepComplete|handleStepComplete\s*=" "$FILE" -S | head -n 1 | cut -d: -f1 || true)
if [[ -n "${line}" ]]; then
start=$((line-80)); end=$((line+140))
awk -v s=$start -v e=$end 'NR>=s && NR<=e {print NR ":" $0}' "$FILE" | sed -n '1,220p'
else
echo "No handleStepComplete definition found"
fi
echo
echo "== onboarding-content: show around any persistence/initial completion logic =="
# Look for localStorage/session or query params / hydration / initial state indicators
rg -n "localStorage|sessionStorage|searchParams|query|persist|initial|default.*currentStep|hydr" "$FILE" -S || trueRepository: langflow-ai/openrag
Length of output: 2059
🏁 Script executed:
#!/bin/bash
set -euo pipefail
FILE="frontend/app/onboarding/_components/onboarding-content.tsx"
echo "== File length =="
wc -l "$FILE" || true
echo
echo "== onboarding-content: top 220 lines =="
awk 'NR>=1 && NR<=220 {print NR ":" $0}' "$FILE" | sed -n '1,220p'
echo
echo
echo "== Search for currentStep source (useState / params / context) =="
rg -n "useState\(|useSearchParams|searchParams|params|router|currentStep\s*[,=]" "$FILE" -S || true
echo
echo
echo "== Search for handleStepComplete definition (non-type) =="
rg -n "handleStepComplete" "$FILE" -S || trueRepository: langflow-ai/openrag
Length of output: 9000
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# 1) Inspect onboarding-card.tsx around where AnimatedProviderSteps is rendered and what condition/keys control it
FILE1="frontend/app/onboarding/_components/onboarding-card.tsx"
echo "== onboarding-card: show around AnimatedProviderSteps render and its surrounding ternary/AnimatePresence =="
rg -n "AnimatedProviderSteps" "$FILE1" | head -n 5 | while read -r line; do
lineno=$(echo "$line" | cut -d: -f1)
start=$((lineno-120)); end=$((lineno+120))
echo
echo "-- $FILE1:$start..$end --"
awk -v s=$start -v e=$end 'NR>=s && NR<=e {print NR ":" $0}' "$FILE1" | sed -n '1,260p'
done
# 2) Locate OnboardingStep component and inspect whether it unmounts/mounts children based on isVisible/isCompleted
FILE2="frontend/app/onboarding/_components/onboarding-step.tsx"
echo
echo "== OnboardingStep file exists? =="
if [[ -f "$FILE2" ]]; then echo "yes: $FILE2"; else echo "no: $FILE2"; fi
# Search for actual definition if path differs
echo
echo "== Search for 'function OnboardingStep' or 'const OnboardingStep' =="
rg -n "OnboardingStep\s*=" frontend/app/onboarding/_components -S || true
rg -n "function\s+OnboardingStep|const\s+OnboardingStep" frontend/app/onboarding/_components -S || true
# If found, print around first match
match=$(rg -n "function\s+OnboardingStep|const\s+OnboardingStep" frontend/app/onboarding/_components -S | head -n 1 || true)
if [[ -n "$match" ]]; then
file=$(echo "$match" | cut -d: -f1)
lineno=$(echo "$match" | cut -d: -f2)
echo
echo "== OnboardingStep definition: $file:$lineno =="
start=$((lineno-80)); end=$((lineno+160))
awk -v s=$start -v e=$end 'NR>=s && NR<=e {print NR ":" $0}' "$file" | sed -n '1,260p'
fiRepository: langflow-ai/openrag
Length of output: 16862
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Find where OnboardingContent is used (likely defines currentStep + handlers)
rg -n "OnboardingContent" frontend/app/onboarding -S
# Find handleStepBack implementation by searching for the identifier in the onboarding flow
rg -n "handleStepBack" frontend/app/onboarding -S
# Also search globally for "currentStep" in onboarding context to locate the state owner
rg -n "const \[currentStep" frontend/app/onboarding -S || true
rg -n "currentStep\W*>\W*0" frontend/app/onboarding -S || trueRepository: langflow-ai/openrag
Length of output: 1091
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Find where OnboardingContent is rendered (parent that owns currentStep)
rg -n "<OnboardingContent\b|OnboardingContent\s*\(" frontend/app/onboarding -S || true
rg -n "<OnboardingContent\b|OnboardingContent\s*\(" frontend/app -S || true
# Also look for handleStepBack definition (likely in same parent)
rg -n "handleStepBack\s*=\s*\(" frontend/app/onboarding -S || true
rg -n "handleStepBack\s*=\s*\(" frontend/app -S || true
# Search for currentStep state owner near that parent by looking for `const [currentStep` outside onboarding-content
rg -n "const \[currentStep" frontend/app -S || trueRepository: langflow-ai/openrag
Length of output: 516
🏁 Script executed:
#!/bin/bash
set -euo pipefail
rg -n "OnboardingContent" frontend -S || true
rg -n "<OnboardingContent\b|OnboardingContent\s*\(" frontend -S || trueRepository: langflow-ai/openrag
Length of output: 543
🏁 Script executed:
#!/bin/bash
set -euo pipefail
FILE="frontend/components/chat-renderer.tsx"
# Show around where OnboardingContent is rendered
echo "== Context around OnboardingContent usage =="
awk 'NR>=320 && NR<=430 {print NR ":" $0}' "$FILE" | sed -n '1,200p'
echo
echo "== Search within chat-renderer for currentStep state owner =="
rg -n "currentStep" "$FILE" || true
echo
echo "== Search within chat-renderer for handleStepComplete/Back =="
rg -n "handleStepComplete|handleStepBack" "$FILE" || trueRepository: langflow-ai/openrag
Length of output: 3616
🏁 Script executed:
#!/bin/bash
set -euo pipefail
FILE="frontend/components/chat-renderer.tsx"
echo "== currentStep initialization and persistence in chat-renderer =="
awk 'NR>=1 && NR<=120 {print NR ":" $0}' "$FILE" | sed -n '1,140p'
echo
echo "== handleStepComplete logic =="
line=$(rg -n "const handleStepComplete" "$FILE" | head -n 1 | cut -d: -f1)
start=$((line-30)); end=$((line+140))
awk -v s=$start -v e=$end 'NR>=s && NR<=e {print NR ":" $0}' "$FILE" | sed -n '1,220p'
echo
echo "== handleStepBack logic =="
line2=$(rg -n "const handleStepBack" "$FILE" | head -n 1 | cut -d: -f1)
start2=$((line2-30)); end2=$((line2+160))
awk -v s=$start2 -v e=$end2 'NR>=s && NR<=e {print NR ":" $0}' "$FILE" | sed -n '1,260p'
echo
echo "== showLayout condition around OnboardingContent mount =="
awk 'NR>=300 && NR<=390 {print NR ":" $0}' "$FILE" | sed -n '1,140p'Repository: langflow-ai/openrag
Length of output: 23618
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Look for isCompleted usage in effects in onboarding-card.tsx
rg -n "useEffect\\(|isCompleted" frontend/app/onboarding/_components/onboarding-card.tsx -S
# Specifically find effects that list isCompleted in deps
rg -n "useEffect\\([^\\)]*\\n[^\\)]*isCompleted|useEffect\\(.*isCompleted" frontend/app/onboarding/_components/onboarding-card.tsx -S || true
# Find whether onboarding-card uses a key on AnimatedProviderSteps or remount boundary tied to isCompleted/currentStep
rg -n "key=\"provider-steps\"|key=\\\"provider-|key=\\\"" frontend/app/onboarding/_components/onboarding-card.tsx -S
# Check onboarding-step: children mount/unmount logic based on isCompleted
rg -n "showChildren|isCompleted" frontend/app/onboarding/_components/onboarding-step.tsx -SRepository: langflow-ai/openrag
Length of output: 792
Fix elapsed-time transition handling in AnimatedProviderSteps
In frontend/app/onboarding/_components/animated-provider-steps.tsx (lines 30-38), seeding prevIsCompleted from the isCompleted prop suppresses the isCompleted && !prevIsCompleted block on an initial mount where the wizard is restored to a completed step (ChatRenderer initializes currentStep from backend settings?.onboarding?.current_step, and OnboardingContent passes isCompleted={currentStep > 0}), so the UI shows Initialized in 0.0 seconds.
Also, prevIsCompleted is never updated on the true -> false edge, so if the component instance remains mounted across subsequent completions, elapsedTime won’t be recomputed.
Suggested fix
- const [prevIsCompleted, setPrevIsCompleted] = useState(isCompleted);
- const [elapsedTime, setElapsedTime] = useState<number>(0);
+ const [prevIsCompleted, setPrevIsCompleted] = useState(false);
+ const [elapsedTime, setElapsedTime] = useState<number>(() =>
+ isCompleted && processingStartTime != null
+ ? Date.now() - processingStartTime
+ : 0,
+ );
- if (isCompleted && !prevIsCompleted) {
- setPrevIsCompleted(true);
- if (processingStartTime) {
- setElapsedTime(Date.now() - processingStartTime);
- }
- }
+ if (isCompleted !== prevIsCompleted) {
+ setPrevIsCompleted(isCompleted);
+ setElapsedTime(
+ isCompleted && processingStartTime != null
+ ? Date.now() - processingStartTime
+ : 0,
+ );
+ }📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const [prevIsCompleted, setPrevIsCompleted] = useState(isCompleted); | |
| const [elapsedTime, setElapsedTime] = useState<number>(0); | |
| // Initialize start time from prop | |
| useEffect(() => { | |
| if (isCompleted && !prevIsCompleted) { | |
| setPrevIsCompleted(true); | |
| if (processingStartTime) { | |
| // Use the start time passed from parent (when user clicked Complete) | |
| setStartTime(processingStartTime); | |
| setElapsedTime(Date.now() - processingStartTime); | |
| } | |
| }, [processingStartTime]); | |
| } | |
| const [prevIsCompleted, setPrevIsCompleted] = useState(false); | |
| const [elapsedTime, setElapsedTime] = useState<number>(() => | |
| isCompleted && processingStartTime != null | |
| ? Date.now() - processingStartTime | |
| : 0, | |
| ); | |
| if (isCompleted !== prevIsCompleted) { | |
| setPrevIsCompleted(isCompleted); | |
| setElapsedTime( | |
| isCompleted && processingStartTime != null | |
| ? Date.now() - processingStartTime | |
| : 0, | |
| ); | |
| } |
🤖 Prompt for 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.
In `@frontend/app/onboarding/_components/animated-provider-steps.tsx` around lines
30 - 38, The component seeds prevIsCompleted incorrectly and never handles the
true->false transition; change initialization of prevIsCompleted so it does not
start from the incoming isCompleted prop (initialize false) and replace the
inline if-block with a useEffect that watches isCompleted and
processingStartTime: when isCompleted becomes true && prevIsCompleted is false,
setElapsedTime(Date.now() - processingStartTime) (guarding for undefined
processingStartTime) and setPrevIsCompleted(true); when isCompleted becomes
false, setPrevIsCompleted(false) so subsequent completions recompute
elapsedTime; update references to setPrevIsCompleted and setElapsedTime inside
that effect.
Eliminate stale UI flashes from state-on-prop-change effects
Fixes 10 instances of no-adjust-state-on-prop-change across 5 files. These useEffect calls synced state to prop changes, causing React to render once with stale values before the effect corrected them — users
briefly saw wrong data.
Changes:
file-list.tsx— Tab reset on retry tab disappearing moved to render-time checkuse-task-dialog.ts— Selection clear on dialog close and status category fallback moved to prev-prop patternanimated-provider-steps.tsx— Removed redundant startTime state (was just a copy of processingStartTime prop); elapsed time now captured during render on completion transitiononboarding-step.tsx— Split monolithic effect into render-time prop adjustments + a slimmer effect for the typewriter animation interval onlyunified-cloud-picker.tsx— Replaced fake-async effect with render-time check (the "async" function was synchronous); removed dead isLoadingBaseUrl state and unreachable loading UISummary by CodeRabbit