CONSOLE-5055: AsyncComponent type improvements#16002
CONSOLE-5055: AsyncComponent type improvements#16002openshift-merge-bot[bot] merged 2 commits intoopenshift:mainfrom
Conversation
|
@logonoff: This pull request references CONSOLE-5055 which is a valid jira issue. Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.22.0" version, but no target version was set. DetailsIn response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository. |
|
@logonoff: This pull request references CONSOLE-5055 which is a valid jira issue. Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.22.0" version, but no target version was set. DetailsIn response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository. |
|
@logonoff: This pull request references CONSOLE-5055 which is a valid jira issue. Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.22.0" version, but no target version was set. DetailsIn response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository. |
|
@logonoff: This pull request references CONSOLE-5055 which is a valid jira issue. Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.22.0" version, but no target version was set. DetailsIn response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository. |
|
/label px-approved |
📝 WalkthroughWalkthroughThis pull request refactors the AsyncComponent lazy-loading system from class-based to functional component using hooks and Suspense, introducing exponential backoff retry logic with a configurable retry cap. Type signatures across lazy loaders are updated to expect 🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
frontend/public/components/import-yaml.tsx (1)
16-25:⚠️ Potential issue | 🟡 MinorFix type safety:
initialResource={undefined}violates the required prop definition.
ResourceYAMLEditorPropsdefinesinitialResource: K8sResourceKindas required (not optional). Passingundefinedconflicts with this contract. Increate-yaml.tsx, the pattern correctly uses an empty object{}instead:const initialResource = useMemo(() => { if (!kindObj) { return {}; // Always pass an object } // ... }, []);Either mark
initialResourceas optional inResourceYAMLEditorPropsif undefined should be supported, or pass{}here to align with the type definition and existing usage patterns.
🧹 Nitpick comments (3)
frontend/packages/console-shared/src/components/formik-fields/field-types.ts (1)
166-173: Minor inconsistency between RadioButtonFieldProps and RadioGroupFieldProps value types.
RadioButtonFieldProps.valueacceptsstring | number(line 167), whileRadioGroupOption.valueis constrained tostringonly (line 185). If aRadioButtonFieldis used standalone with a numeric value but the same field is later wrapped in aRadioGroupField, the types won't align.Consider whether both should consistently use
stringorstring | number. If numeric values are genuinely needed for radio buttons,RadioGroupOption.valueshould also supportnumber.frontend/public/components/utils/async.tsx (1)
18-22:sameLoadercomparison is fragile — document limitations and consider alternatives.Comparing functions via
nameandtoString()can produce false positives (different inline functions with identical bodies) or false negatives (minified code where function bodies differ). The current approach handles inline loaders better than referential equality alone, but:
- Arrow functions typically have empty
nameproperties- Minifiers may alter function bodies unpredictably
The comment acknowledges this ("not the best solution"), but consider adding a more robust equality check or documenting that consumers should define loaders outside render cycles when possible.
frontend/public/components/utils/__tests__/async.spec.tsx (1)
98-109: Minor: MissingawaitafteradvanceTimersByTimemay cause timing issues.For consistency with other tests in this file, consider wrapping the timer advancement in
actor awaiting promise resolution:await act(async () => { jest.advanceTimersByTime(1000); });This ensures all pending promise resolutions are flushed before the assertion on line 107.
♻️ Suggested improvement
await waitFor(() => expect(loader).toHaveBeenCalledTimes(1)); - jest.advanceTimersByTime(1000); + await act(async () => { + jest.advanceTimersByTime(1000); + }); expect(loader).toHaveBeenCalledTimes(1);
be35005 to
9cf3f71
Compare
|
/woof |
DetailsIn response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. |
9cf3f71 to
6f03cdd
Compare
TheRealJon
left a comment
There was a problem hiding this comment.
Just a couple of questions about the kind props being removed.
| path="/k8s/ns/:ns/secrets/~new/:type" | ||
| element={ | ||
| <AsyncComponent | ||
| kind="Secret" |
There was a problem hiding this comment.
m.CreateSecret takes no props
export const CreateSecret = () => {
const params = useParams();
const formType = params.type as SecretFormType;
return (
<SecretFormWrapper
fixed={{ metadata: { namespace: params.ns } }}
formType={formType}
isCreate={true}
/>
);
};| loader={() => import('./droppable-edit-yaml').then((c) => c.DroppableEditYAML)} | ||
| initialResource={initialResource} | ||
| create={isCreate} | ||
| kind={kindObj.kind} |
There was a problem hiding this comment.
kind is not a prop in either DroppableEditYAML nor EditYAML. props.kind is not accessed in either component either
| forwardRef={editorRef} | ||
| ref={editorRef} |
There was a problem hiding this comment.
CodeEditor never accepted forwardRef, the way to pass a ref to a component is via the ref prop
| <ErrorBoundaryPage> | ||
| <AsyncComponent | ||
| loader={createResourceExtension.properties.component} | ||
| namespace={params.ns} | ||
| /> | ||
| </ErrorBoundaryPage> | ||
| <AsyncComponent | ||
| loader={createResourceExtension.properties.component} | ||
| namespace={params.ns} | ||
| /> |
There was a problem hiding this comment.
AsyncComponent now wraps an ErrorBoundary
| path="/k8s/ns/:ns/secrets/~new/:type" | ||
| element={ | ||
| <AsyncComponent | ||
| kind="Secret" |
There was a problem hiding this comment.
m.CreateSecret takes no props
export const CreateSecret = () => {
const params = useParams();
const formType = params.type as SecretFormType;
return (
<SecretFormWrapper
fixed={{ metadata: { namespace: params.ns } }}
formType={formType}
isCreate={true}
/>
);
};| path="/k8s/ns/:ns/configmaps/~new/form" | ||
| element={ | ||
| <AsyncComponent | ||
| kind="ConfigMap" |
There was a problem hiding this comment.
ConfigMapPage accepts no props
export const ConfigMapPage: FC = () => {
const { t } = useTranslation();
const { ns: namespace, name } = useParams();
const isCreateFlow: boolean = !name;
const [watchedConf| loader={() => | ||
| import('./RBAC' /* webpackChunkName: "rbac" */).then((m) => m.CreateRoleBinding) | ||
| } | ||
| kind="RoleBinding" |
There was a problem hiding this comment.
CreateRoleBinding accepts no props
export const CreateRoleBinding: FC = () => {
const params = useParams();
const location = useLocation();
const searchParams = new URLSearchParams(location.search);
const roleKind = searchParams.get('rolekind');
const roleName = searchParams.get('rolename');
const subjectName = searchParams.get('subjectName'| path="/k8s/ns/:ns/persistentvolumeclaims/~new/form" | ||
| element={ | ||
| <AsyncComponent | ||
| kind="PersistentVolumeClaim" |
There was a problem hiding this comment.
accepts no props
export const CreatePVC = () => {
const params = useParams();
const namespace = params.ns || 'default';
return <CreatePVC| path="/k8s/ns/:ns/:resourceRef/form" | ||
| element={ | ||
| <AsyncComponent | ||
| kind="PodDisruptionBudgets" |
There was a problem hiding this comment.
accepts no props
export const PDBFormPage: FC = () => {
const { t } = useTranslation();
const params = us| loader={() => import('./droppable-edit-yaml').then((c) => c.DroppableEditYAML)} | ||
| initialResource={initialResource} | ||
| create={isCreate} | ||
| kind={kindObj.kind} |
There was a problem hiding this comment.
kind is not a prop in either DroppableEditYAML nor EditYAML. props.kind is not accessed in either component either
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: logonoff, TheRealJon The full list of commands accepted by this bot can be found here. The pull request process is described here DetailsNeeds approval from an approver in each of these files:
Approvers can indicate their approval by writing |
|
/assign @yapei |
|
performed some regression testing on following
No obvious regression issues found |
|
@yapei: This PR has been marked as verified by DetailsIn response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository. |
|
@logonoff: all tests passed! Full PR test history. Your PR dashboard. DetailsInstructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here. |

AsyncComponentto be a functional component that uses React.lazyAsyncComponentnow have proper type checking based on the props of the loaderSummary by CodeRabbit
Bug Fixes
New Features
Tests