refactor(portal-framework-ui): fix form autocomplete logic#477
refactor(portal-framework-ui): fix form autocomplete logic#477
Conversation
- Extracted autocomplete value calculation into separate utility function - Reordered imports and interface declarations - Simplified autocomplete prop passing in RegisteredComponent - Improved loading state styling with Tailwind classes - Added formConfig to FieldRenderer's context usage
|
WalkthroughAdds a helper to standardize autocomplete value resolution in FieldRenderer, introduces an internal props type, refactors to use useFormContext for form action, memoizes computed autocomplete, updates prop passing accordingly, adjusts import order, and makes a minor spinner container class tweak. No public API changes. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant U as User
participant FR as FieldRenderer
participant FC as useFormContext
participant GV as getAutocompleteValue
participant C as Field Component
U->>FR: Render field
FR->>FC: Obtain formConfig
FC-->>FR: { action, ... }
note over FR: Compute autoCompleteValue
alt field.autocomplete present
FR-->>FR: Use field.autocomplete
else no field.autocomplete
FR->>GV: getAutocompleteValue(field, { formPurpose: action })
GV-->>FR: derived value or undefined
alt undefined
FR-->>FR: Use field.inputProps?.autocomplete
end
end
FR->>C: Render with props (autocomplete=autoCompleteValue)
C-->>U: Field displayed
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Poem
✨ Finishing Touches
🧪 Generate unit tests
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
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)
libs/portal-framework-ui/src/components/form/FormRenderer.tsx (1)
173-197: Loading state bug: stale closure makes spinner stick; cleanup missing.
if (isLoading) setIsLoading(false)checks a stale value and won’t clear loading after an asyncshow(). Also guard against state updates after unmount.- if (shouldShow && field.show) { - try { - const showPromiseOrValue = field.show(currentValues); - if (showPromiseOrValue instanceof Promise) { - setIsLoading(true); - shouldShow = await showPromiseOrValue; - if (isLoading) setIsLoading(false); - } else { - shouldShow = showPromiseOrValue; - if (isLoading) setIsLoading(false); - } - } catch (error) { + if (shouldShow && field.show) { + const result = field.show(currentValues); + const isPromise = + result && typeof (result as any).then === "function"; + try { + if (isPromise) setIsLoading(true); + shouldShow = await Promise.resolve(result); + } catch (error) { console.error( `Error checking show status for field ${String(field.name)}:`, error, ); shouldShow = false; - if (isLoading) setIsLoading(false); - } - } else if (!field.show) { - if (isLoading) setIsLoading(false); - } else { - if (isLoading) setIsLoading(false); + } finally { + if (isPromise) setIsLoading(false); + } }Add cancellation guard in the effect:
- useEffect(() => { + useEffect(() => { + let cancelled = false; // Subscribe to form changes and check visibility when relevant fields change const subscription = watch((values, { name }) => { // Only check visibility if dependencies are empty (watch all) or changed field is in dependencies if (!dependencies.length || (name && dependencies.includes(name))) { checkVisibility(); } }); @@ - return () => subscription.unsubscribe(); + return () => { + cancelled = true; + subscription.unsubscribe(); + }; }, [dependencies, field, getValues, isLoading, watch]);
🧹 Nitpick comments (2)
libs/portal-framework-ui/src/components/form/FormRenderer.tsx (2)
14-16: Keep imports contiguous; move local type below imports.Minor style for consistency/readability.
-interface FieldRendererProps<TFieldValues extends FieldValues> { - field: FormFieldConfig<TFieldValues>; -}Re-add just after the last import:
+interface FieldRendererProps<TFieldValues extends FieldValues> { + field: FormFieldConfig<TFieldValues>; +}
207-207: Effect re-subscribes on every loading toggle.Remove
isLoadingfrom deps to avoid unnecessary subscribe/unsubscribe churn.- }, [dependencies, field, getValues, isLoading, watch]); + }, [dependencies, field, getValues, watch]);
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (1)
libs/portal-framework-ui/src/components/form/FormRenderer.tsx(5 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
libs/portal-framework-ui/src/components/form/FormRenderer.tsx (3)
libs/portal-framework-ui/src/components/form/types.ts (1)
FormFieldConfig(121-175)libs/portal-framework-ui/src/components/form/context.tsx (1)
useFormContext(35-43)libs/portal-framework-ui/src/components/form/autocomplete/rules.ts (1)
getAutocompleteValue(364-378)
🔇 Additional comments (6)
libs/portal-framework-ui/src/components/form/FormRenderer.tsx (6)
25-25: Import location change looks fine.
120-120: Using formConfig from context — OK.
127-130: Good extraction + memoization of autocomplete value.
214-214: Spinner container tweak — OK.
279-288: Helper reads well; precedence is correct (explicit > derived > fallback).
256-258: Leaveautocompleteprop as-is
Field components declare and accept a lowercaseautocompleteprop and correctly map it to the rendered element’sautoCompleteattribute; no change required.
Summary by CodeRabbit