Skip to content

CONSOLE-5028: Refactor dev-console and knative-plugin Packages to useK8sWatchResource(s)#16011

Open
krishagarwal278 wants to merge 3 commits intoopenshift:mainfrom
krishagarwal278:CONSOLE-5028
Open

CONSOLE-5028: Refactor dev-console and knative-plugin Packages to useK8sWatchResource(s)#16011
krishagarwal278 wants to merge 3 commits intoopenshift:mainfrom
krishagarwal278:CONSOLE-5028

Conversation

@krishagarwal278
Copy link
Member

@krishagarwal278 krishagarwal278 commented Feb 9, 2026

Tested locally to check refactored components in Dev-Console and knative-plugin packages are working as expected:

Screenshot 2026-02-13 at 3 48 19 PM

Summary by CodeRabbit

Release Notes

  • Refactor
    • Updated and enhanced resource loading mechanisms across development console and knative plugin components for improved data consistency and error state handling.
    • Standardized internal data synchronization patterns in project access, resource import, monitoring, and traffic management features to improve overall system reliability and performance consistency.
    • Improved loading state indicators and error information clarity across affected console components.

@openshift-ci-robot
Copy link
Contributor

openshift-ci-robot commented Feb 9, 2026

@krishagarwal278: This pull request references CONSOLE-5028 which is a valid jira issue.

Details

In 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.

@openshift-ci-robot openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label Feb 9, 2026
@openshift-ci openshift-ci bot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Feb 9, 2026
@openshift-ci openshift-ci bot requested review from cajieh and rhamilto February 9, 2026 20:59
@openshift-ci openshift-ci bot added the component/dev-console Related to dev-console label Feb 9, 2026
@openshift-ci
Copy link
Contributor

openshift-ci bot commented Feb 9, 2026

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: krishagarwal278
Once this PR has been reviewed and has the lgtm label, please assign rhamilto for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-ci openshift-ci bot added the component/knative Related to knative-plugin label Feb 9, 2026
@cajieh
Copy link
Contributor

cajieh commented Feb 11, 2026

/retest

@krishagarwal278 krishagarwal278 changed the title [WIP] CONSOLE-5028: Refactor dev-console and knative-plugin Packages to useK8sWatchResource(s) CONSOLE-5028: Refactor dev-console and knative-plugin Packages to useK8sWatchResource(s) Feb 11, 2026
@openshift-ci openshift-ci bot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Feb 11, 2026
@krishagarwal278
Copy link
Member Author

/retest

@openshift-ci-robot
Copy link
Contributor

openshift-ci-robot commented Feb 12, 2026

@krishagarwal278: This pull request references CONSOLE-5028 which is a valid jira issue.

Details

In response to this:

Summary by CodeRabbit

Release Notes

  • Refactor
  • Updated and enhanced resource loading mechanisms across development console and knative plugin components for improved data consistency and error state handling.
  • Standardized internal data synchronization patterns in project access, resource import, monitoring, and traffic management features to improve overall system reliability and performance consistency.
  • Improved loading state indicators and error information clarity across affected console components.

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.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 12, 2026

📝 Walkthrough

Walkthrough

This pull request systematically replaces Firehose-based resource provisioning throughout the dev-console and knative-plugin packages with direct Kubernetes watch hooks (useK8sWatchResource and useK8sWatchResources). Affected areas include health checks, deploy image, import forms, monitoring overview, project access, and knative features. Type definitions are standardized to { data: T; loaded: boolean; loadError?: Error } structures. The FirehoseList interface is removed. Test utilities are updated to mock the new watch hooks instead of Firehose. Runtime behavior is preserved while internal data wiring is refactored to use watch hooks directly.

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main refactoring objective: migrating from Firehose-based data provisioning to useK8sWatchResource(s) hooks across dev-console and knative-plugin packages.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Tip

Issue Planner is now in beta. Read the docs and try it out! Share your feedback on Discord.


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

Copy link
Contributor

@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: 5

Caution

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

⚠️ Outside diff range comments (4)
frontend/packages/dev-console/src/components/import/ImportSamplePage.tsx (1)

44-46: ⚠️ Potential issue | 🟡 Minor

Handle loadError to prevent silent failures and improve UX.

The hook returns [data, loaded, loadError], but loadError isn't captured. If the ImageStream fails to load (e.g., RBAC denial, resource not found), imageStreamloaded will be true while imageStream is null/undefined. This will cause a runtime error on line 52 when accessing builderImage.name.

Consider destructuring loadError and rendering an appropriate error state:

🛡️ Proposed fix
-  const [imageStream, imageStreamloaded] = useK8sWatchResource(imageStreamResource);
+  const [imageStream, imageStreamLoaded, loadError] = useK8sWatchResource(imageStreamResource);

-  if (!imageStreamloaded) return <LoadingBox />;
+  if (!imageStreamLoaded) return <LoadingBox />;
+  if (loadError) {
+    return (
+      <div className="co-m-pane__body">
+        <div className="pf-v6-u-text-align-center">
+          {t('devconsole~Error loading ImageStream: {{error}}', { error: loadError.message })}
+        </div>
+      </div>
+    );
+  }

Also consider using a shared error component pattern if one exists in the codebase (e.g., StatusBox with loadError).

frontend/packages/knative-plugin/src/components/revisions/DeleteRevisionModalController.tsx (1)

175-183: ⚠️ Potential issue | 🟠 Major

Missing return for promise chain - errors from delete won't propagate.

On line 177, deleteRevisionAction(action) returns a Promise, but it's not being returned from the .then() callback. If k8sPatch succeeds but k8sKill fails, the error won't propagate to the .catch() block, leaving the user unaware of the failure and potentially in an inconsistent state (traffic redistributed, but revision not deleted).

🐛 Fix: return the promise to maintain the chain
    return k8sPatch(ServiceModel, service, ksvcPatch)
      .then(() => {
-       deleteRevisionAction(action);
+       return deleteRevisionAction(action);
      })
      .catch((err) => {
frontend/packages/dev-console/src/components/import/ImportForm.tsx (1)

168-168: ⚠️ Potential issue | 🟡 Minor

Potential undefined access on projects.

The projects prop is typed as optional (projects? at line 62), but line 168 accesses projects.loaded without a guard. If ImportForm is ever rendered without the projects prop, this will throw a runtime error.

Consider adding a defensive check:

🛡️ Proposed fix
-    const createNewProject = projects.loaded && _.isEmpty(projects.data);
+    const createNewProject = projects?.loaded && _.isEmpty(projects.data);
frontend/packages/dev-console/src/components/project-access/ProjectAccess.tsx (1)

33-53: ⚠️ Potential issue | 🟠 Major

Guard optional roleBindings and use explicit error detection.

roleBindings is optional in the interface but dereferenced immediately on line 47 without null checks, causing a crash if the prop is omitted. Additionally, _.isEmpty(new Error()) returns true (Error objects have no enumerable keys), so the current guard masks error states and incorrectly shows LoadingBox when an error exists. Update the destructuring to provide a default value and replace _.isEmpty() with an explicit instanceof Error check.

🛠️ Proposed fix
 const ProjectAccess: FC<ProjectAccessProps> = ({
   namespace,
-  roleBindings,
+  roleBindings = { data: [], loaded: false, loadError: undefined },
   roles,
   fullFormView,
 }) => {
   const { t } = useTranslation();
-  if ((!roleBindings.loaded && _.isEmpty(roleBindings.loadError)) || !roles.loaded) {
+  const hasLoadError =
+    roleBindings.loadError instanceof Error || !_.isEmpty(roleBindings.loadError);
+  if ((!roleBindings.loaded && !hasLoadError) || !roles.loaded) {
     return <LoadingBox />;
   }
🤖 Fix all issues with AI agents
In
`@frontend/packages/dev-console/src/components/health-checks/HealthChecksPage.tsx`:
- Around line 10-15: The route params (kind, ns, name) from useParams may be
undefined, so change HealthChecksPage.tsx to avoid calling useK8sWatchResource
with undefined values: either add an early guard in the component that returns a
loading/error UI when any of kind/ns/name is missing, or switch to a conditional
watch by only invoking useK8sWatchResource (or passing null as the resource
argument) when all three params are defined; reference the existing
useK8sWatchResource call and the kind/ns/name variables to implement the guard
or conditional call.

In
`@frontend/packages/knative-plugin/src/components/knatify/CreateKnatifyPage.tsx`:
- Around line 140-143: The form is being rendered with
projects={resources?.projects as WatchK8sResultsObject<...>} which can be
undefined; update the rendering guard in CreateKnatifyPage to ensure
resources.projects exists and is loaded before rendering KnatifyForm (or pass a
safe default typed WatchK8sResultsObject) — e.g., check resources?.projects &&
isResourceLoaded(resources.projects) (or similar) using the existing
isResourceLoaded helper and only pass formikProps to KnatifyForm when that
condition is true so KnatifyForm never receives an undefined projects prop.

In
`@frontend/packages/knative-plugin/src/components/revisions/DeleteRevisionModalController.tsx`:
- Around line 75-81: The current loaded check in
DeleteRevisionModalController.tsx only ensures resources[key].loaded but ignores
resources[key].loadError; update the readiness gating to also detect loadError
(e.g., treat a resource as not-ok if resources[key].loadError is truthy) and
specifically guard the non-optional services resource: if services.loadError (or
any resource.loadError) is present, return or render an error state/modal
instead of proceeding with deletion logic; ensure any early-return that
currently uses the loaded variable is updated to incorporate the new error
condition so stale/failed watches don’t allow the component to continue.

In
`@frontend/packages/knative-plugin/src/components/test-function/TestFunctionController.tsx`:
- Around line 19-26: Update TestFunctionController to destructure the third
return value from useK8sWatchResource (loadError) and handle three states: show
a brief loading indicator while not loaded, show an inline error (or call
props.closeOverlay with a notification) when loadError is present, and guard
against service being undefined before rendering <TestFunction {...props}
service={service} />; reference the useK8sWatchResource call in
TestFunctionController and the TestFunction component to add the error check and
the fallback UI for loading and missing service.

In
`@frontend/packages/knative-plugin/src/components/traffic-splitting/TrafficSplittingController.tsx`:
- Around line 48-50: The controller currently returns null when resources are
still loading; update TrafficSplittingController so that when loaded is false it
renders the project's LoadingBox component instead of null (i.e., return
<LoadingBox />), keeping the existing return when loaded is true:
<TrafficSplitting {...props} service={props.obj} revisions={revisions} />; also
add an import for LoadingBox if not already present and ensure
getKnativeRevisionsData and TrafficSplitting usage remain unchanged.
🧹 Nitpick comments (8)
frontend/packages/dev-console/src/components/import/ImportSamplePage.tsx (1)

33-42: Remove Firehose-specific prop field from resource definition.

The prop: 'imageStreams' field is a Firehose artifact used to name the injected prop. useK8sWatchResource doesn't utilize this field — it simply returns the resource data directly. Leaving it in creates confusion about what's actually used.

🧹 Proposed cleanup
   const imageStreamResource = useMemo(
     () => ({
       kind: ImageStreamModel.kind,
-      prop: 'imageStreams',
       isList: false,
       name: imageStreamName,
       namespace: imageStreamNamespace,
     }),
     [imageStreamName, imageStreamNamespace],
   );
frontend/packages/knative-plugin/src/components/test-function/TestFunctionController.tsx (1)

39-42: Stable reference for props in useCallback dependency.

If props is a new object reference on each render (common pattern when spreading inline), the memoized callback will be recreated every time, defeating the purpose of useCallback. Verify that the caller passes a stable props object or consider destructuring only the required properties into the dependency array.

frontend/packages/dev-console/src/components/health-checks/HealthChecksPage.tsx (1)

17-21: Consider memoizing the resource object.

This object is recreated on every render. If AddHealthChecksForm or its descendants perform reference equality checks (e.g., in useEffect dependencies or React.memo), this could trigger unnecessary re-renders.

♻️ Proposed refactor using useMemo
+import { useMemo } from 'react';
-  const resource = {
-    data: resourceData,
-    loaded,
-    loadError,
-  };
+  const resource = useMemo(
+    () => ({ data: resourceData, loaded, loadError }),
+    [resourceData, loaded, loadError],
+  );
frontend/packages/knative-plugin/src/components/revisions/DeleteRevisionModalController.tsx (1)

153-167: Consider useCallback for deleteRevisionAction (optional).

The function is recreated on every render. For a modal component with user-triggered actions, this is acceptable, but wrapping in useCallback with [revision, close, t] dependencies would be a minor optimization if this pattern is used elsewhere.

The redirect logic using regex to check if we're on the deleted revision's page is a solid pattern for avoiding broken views post-deletion.

frontend/packages/knative-plugin/src/components/traffic-splitting/TrafficSplittingController.tsx (1)

44-46: Consider simplifying loaded check and handling loadError.

The Object.keys(resources).length > 0 guard is redundant since watchResources always defines both revisions and configurations keys—the object will never be empty. More importantly, when loadError is present on either resource, the user currently sees nothing (null render) with no feedback.

Since resources are optional: true, errors may be expected, but for a traffic splitting modal, consider surfacing errors or at least logging them for debuggability.

♻️ Suggested simplification with error awareness
-  const loaded =
-    Object.keys(resources).length > 0 &&
-    Object.keys(resources).every((key) => resources[key].loaded);
+  const loaded = resources.revisions.loaded && resources.configurations.loaded;
+  const loadError = resources.revisions.loadError || resources.configurations.loadError;
+
+  if (loadError) {
+    // eslint-disable-next-line no-console
+    console.warn('TrafficSplittingController: Failed to load resources', loadError);
+  }
frontend/packages/dev-console/src/components/import/DeployImagePage.tsx (1)

19-22: Consider using ProjectModel.kind instead of string literal.

For consistency with ImportPage.tsx (which uses ProjectModel.kind at line 67), consider importing and using ProjectModel here. This ensures the kind string stays in sync if the model definition ever changes.

♻️ Suggested refactor
+import { ProjectModel } from '@console/internal/models';
 import { useK8sWatchResource } from '@console/internal/components/utils/k8s-watch-hook';
 import { K8sResourceKind } from '@console/internal/module/k8s';
   const [projectsData, loaded, loadError] = useK8sWatchResource<K8sResourceKind[]>({
-    kind: 'Project',
+    kind: ProjectModel.kind,
     isList: true,
   });
frontend/packages/dev-console/src/components/import/ImportPage.tsx (1)

49-50: Edge case handling is graceful but lacks test coverage.

The code correctly guards against partial imagestream parameters by requiring both imageStreamName AND imageStreamNamespace—if either is missing, it silently falls back to git import mode. Analysis of the codebase shows the only identified URL construction path in useBuilderImages.tsx always provides both parameters together, so this edge case shouldn't occur in normal operation. However, this fallback behavior is neither documented nor tested, and users navigating with malformed URLs would silently get git import rather than an error. Consider adding a test case covering incomplete URL parameters to prevent future regressions.

frontend/packages/dev-console/src/components/monitoring/overview/MonitoringTab.tsx (1)

48-69: Preserve pod event loadError for parity.
Right now per-pod watch errors are dropped; carrying loadError keeps the shape consistent and makes future error handling easier.

🔧 Suggested update
-  const podEventProps: Record<string, { data: EventKind[]; loaded: boolean }> = {};
+  const podEventProps: Record<string, { data: EventKind[]; loaded: boolean; loadError?: Error }> = {};
   if (podData?.pods) {
     podData.pods.forEach((pod) => {
       const podEvents = resources[pod.metadata.uid];
       if (podEvents) {
         podEventProps[pod.metadata.uid] = {
           data: podEvents.data || [],
           loaded: podEvents.loaded,
+          loadError: podEvents.loadError,
         };
       }
     });
   }

Comment on lines +10 to +15
const [resourceData, loaded, loadError] = useK8sWatchResource<K8sResourceKind>({
kind,
namespace: ns,
isList: false,
name,
});
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Route params may be undefined — consider guard or conditional watch.

The kind, ns, and name values from useParams() are typed as string | undefined. If any of these are missing (e.g., malformed URL or route mismatch), useK8sWatchResource will attempt to watch with undefined values, which could lead to unexpected API calls or silent failures.

Consider either:

  1. Adding a guard clause that returns early (e.g., a loading state or error) when required params are missing, or
  2. Using a conditional resource watch pattern (passing null to skip the watch when params are invalid).
🛡️ Proposed fix using conditional watch
-  const [resourceData, loaded, loadError] = useK8sWatchResource<K8sResourceKind>({
-    kind,
-    namespace: ns,
-    isList: false,
-    name,
-  });
+  const watchResource = kind && ns && name
+    ? { kind, namespace: ns, isList: false, name }
+    : null;
+
+  const [resourceData, loaded, loadError] = useK8sWatchResource<K8sResourceKind>(watchResource);
🤖 Prompt for AI Agents
In
`@frontend/packages/dev-console/src/components/health-checks/HealthChecksPage.tsx`
around lines 10 - 15, The route params (kind, ns, name) from useParams may be
undefined, so change HealthChecksPage.tsx to avoid calling useK8sWatchResource
with undefined values: either add an early guard in the component that returns a
loading/error UI when any of kind/ns/name is missing, or switch to a conditional
watch by only invoking useK8sWatchResource (or passing null as the resource
argument) when all three params are defined; reference the existing
useK8sWatchResource call and the kind/ns/name variables to implement the guard
or conditional call.

Comment on lines 140 to 143
<KnatifyForm
{...formikProps}
projects={(resources?.projects as WatchK8sResultsObject<K8sResourceKind[]>) ?? {}}
projects={resources?.projects as WatchK8sResultsObject<K8sResourceKind[]>}
/>
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Guard against undefined projects before rendering the form.

projects={resources?.projects as ...} can still be undefined while isResourceLoaded is true (since the current check doesn’t require the key). That’s a latent runtime risk if KnatifyForm dereferences projects.loaded/data. Consider tightening the loaded check to require resources.projects (or providing a typed default) before rendering.

✅ Tighten the loaded gate to require projects
-  const isResourceLoaded =
-    Object.keys(resources).length > 0 &&
-    Object.values(resources).every((value) => value.loaded || !!value.loadError) &&
-    (hpaLoaded || !!hpaError);
+  const isResourceLoaded =
+    !!resources.projects &&
+    Object.values(resources).every((value) => value.loaded || !!value.loadError) &&
+    (hpaLoaded || !!hpaError);
🤖 Prompt for AI Agents
In
`@frontend/packages/knative-plugin/src/components/knatify/CreateKnatifyPage.tsx`
around lines 140 - 143, The form is being rendered with
projects={resources?.projects as WatchK8sResultsObject<...>} which can be
undefined; update the rendering guard in CreateKnatifyPage to ensure
resources.projects exists and is loaded before rendering KnatifyForm (or pass a
safe default typed WatchK8sResultsObject) — e.g., check resources?.projects &&
isResourceLoaded(resources.projects) (or similar) using the existing
isResourceLoaded helper and only pass formikProps to KnatifyForm when that
condition is true so KnatifyForm never receives an undefined projects prop.

Comment on lines +75 to 81
const loaded =
Object.keys(resources).length > 0 &&
Object.keys(resources).every((key) => resources[key].loaded);

if (!loaded) {
return null;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Missing loadError handling for watched resources.

The loaded check only verifies that resources have finished loading but doesn't account for loadError. If the services watch fails (e.g., RBAC denial), the component will proceed with potentially empty or stale data, leading to confusing UX.

Consider checking for errors, especially on the non-optional services resource:

🛡️ Suggested defensive error handling
  const loaded =
    Object.keys(resources).length > 0 &&
    Object.keys(resources).every((key) => resources[key].loaded);

+ const loadError = resources.services?.loadError;
+
+ if (loadError) {
+   // Consider rendering an error state or logging
+   console.error('Failed to load services:', loadError);
+ }
+
  if (!loaded) {
    return null;
  }

Alternatively, you could display a user-facing error modal if the required service data can't be loaded.

📝 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.

Suggested change
const loaded =
Object.keys(resources).length > 0 &&
Object.keys(resources).every((key) => resources[key].loaded);
if (!loaded) {
return null;
}
const loaded =
Object.keys(resources).length > 0 &&
Object.keys(resources).every((key) => resources[key].loaded);
const loadError = resources.services?.loadError;
if (loadError) {
// Consider rendering an error state or logging
console.error('Failed to load services:', loadError);
}
if (!loaded) {
return null;
}
🤖 Prompt for AI Agents
In
`@frontend/packages/knative-plugin/src/components/revisions/DeleteRevisionModalController.tsx`
around lines 75 - 81, The current loaded check in
DeleteRevisionModalController.tsx only ensures resources[key].loaded but ignores
resources[key].loadError; update the readiness gating to also detect loadError
(e.g., treat a resource as not-ok if resources[key].loadError is truthy) and
specifically guard the non-optional services resource: if services.loadError (or
any resource.loadError) is present, return or render an error state/modal
instead of proceeding with deletion logic; ensure any early-return that
currently uses the loaded variable is updated to incorporate the new error
condition so stale/failed watches don’t allow the component to continue.

Comment on lines 19 to 26
const [service, loaded] = useK8sWatchResource<ServiceKind>({
kind: referenceForModel(ServiceModel),
isList: false,
namespace: obj.metadata.namespace,
name: obj.metadata.name,
});

return (
<Firehose resources={serverlessResources}>
<Controller {...props} />
</Firehose>
);
return loaded ? <TestFunction {...props} service={service} /> : null;
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Handle loadError and guard against undefined service.

The useK8sWatchResource hook returns a tuple of [data, loaded, loadError]. Currently, loadError is not destructured, so users receive no feedback if the resource fetch fails—the component just renders null indefinitely once loaded becomes true with an error state. Additionally, service may be undefined even when loaded is true (e.g., resource not found), which could cause issues downstream in TestFunction.

Consider also providing a brief loading indicator rather than null to avoid a flash of empty content in the modal.

🛡️ Proposed fix to handle error state and guard service
-  const [service, loaded] = useK8sWatchResource<ServiceKind>({
+  const [service, loaded, loadError] = useK8sWatchResource<ServiceKind>({
     kind: referenceForModel(ServiceModel),
     isList: false,
     namespace: obj.metadata.namespace,
     name: obj.metadata.name,
   });
 
-  return loaded ? <TestFunction {...props} service={service} /> : null;
+  if (!loaded) {
+    return null; // Consider a <LoadingBox /> here for better UX
+  }
+
+  if (loadError || !service) {
+    // Optionally render an error state or close the modal
+    return null;
+  }
+
+  return <TestFunction {...props} service={service} />;

For a production-quality modal, you may want to show an inline error message (e.g., using PatternFly's Alert component) or call props.closeOverlay with an appropriate notification when the resource cannot be loaded.

📝 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.

Suggested change
const [service, loaded] = useK8sWatchResource<ServiceKind>({
kind: referenceForModel(ServiceModel),
isList: false,
namespace: obj.metadata.namespace,
name: obj.metadata.name,
});
return (
<Firehose resources={serverlessResources}>
<Controller {...props} />
</Firehose>
);
return loaded ? <TestFunction {...props} service={service} /> : null;
const [service, loaded, loadError] = useK8sWatchResource<ServiceKind>({
kind: referenceForModel(ServiceModel),
isList: false,
namespace: obj.metadata.namespace,
name: obj.metadata.name,
});
if (!loaded) {
return null; // Consider a <LoadingBox /> here for better UX
}
if (loadError || !service) {
// Optionally render an error state or close the modal
return null;
}
return <TestFunction {...props} service={service} />;
🤖 Prompt for AI Agents
In
`@frontend/packages/knative-plugin/src/components/test-function/TestFunctionController.tsx`
around lines 19 - 26, Update TestFunctionController to destructure the third
return value from useK8sWatchResource (loadError) and handle three states: show
a brief loading indicator while not loaded, show an inline error (or call
props.closeOverlay with a notification) when loadError is present, and guard
against service being undefined before rendering <TestFunction {...props}
service={service} />; reference the useK8sWatchResource call in
TestFunctionController and the TestFunction component to add the error check and
the fallback UI for loading and missing service.

Comment on lines +48 to +50
const revisions = getKnativeRevisionsData(props.obj, resources);

return loaded ? <TrafficSplitting {...props} service={props.obj} revisions={revisions} /> : null;
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Find the knative-topology-utils file
find frontend -name "*knative*topology*utils*" -type f

Repository: openshift/console

Length of output: 219


🏁 Script executed:

#!/bin/bash
# Search for getKnativeRevisionsData definition
rg -n 'getKnativeRevisionsData' frontend --type=ts -A 5 -B 2

Repository: openshift/console

Length of output: 6348


🏁 Script executed:

#!/bin/bash
# Find useK8sWatchResources to understand the structure it returns
rg -n 'useK8sWatchResources' frontend/packages/knative-plugin --type=ts -A 3 -B 2

Repository: openshift/console

Length of output: 30355


🏁 Script executed:

#!/bin/bash
# Check for LoadingBox usage patterns in the knative-plugin
rg -n 'LoadingBox' frontend/packages/knative-plugin --type=ts

Repository: openshift/console

Length of output: 1961


🏁 Script executed:

#!/bin/bash
# Get the full getKnativeRevisionsData function implementation
sed -n '495,520p' frontend/packages/knative-plugin/src/topology/knative-topology-utils.ts

Repository: openshift/console

Length of output: 1014


🏁 Script executed:

#!/bin/bash
# Check TopologyDataResources type definition
rg -n 'type TopologyDataResources' frontend/packages/knative-plugin --type=ts -A 5

Repository: openshift/console

Length of output: 43


🏁 Script executed:

#!/bin/bash
# Verify the exact structure returned by useK8sWatchResources in the controller
sed -n '35,52p' frontend/packages/knative-plugin/src/components/traffic-splitting/TrafficSplittingController.tsx

Repository: openshift/console

Length of output: 527


🏁 Script executed:

#!/bin/bash
# Find TopologyDataResources type definition in the utils file
rg -n 'TopologyDataResources' frontend/packages/knative-plugin/src/topology/knative-topology-utils.ts -B 2 -A 8 | head -30

Repository: openshift/console

Length of output: 1165


🏁 Script executed:

#!/bin/bash
# Look for TopologyDataResources definition in the imported console topology package
# First, check if it's documented in any local type files or interfaces
rg -n 'interface TopologyDataResources\|type TopologyDataResources' frontend --type=ts

Repository: openshift/console

Length of output: 43


🏁 Script executed:

#!/bin/bash
# Verify the pattern across other usages in DeleteRevisionModalController to confirm consistency
sed -n '65,95p' frontend/packages/knative-plugin/src/components/revisions/DeleteRevisionModalController.tsx

Repository: openshift/console

Length of output: 907


Use LoadingBox for visual feedback during resource loading.

The resources structure from useK8sWatchResources correctly resolves via optional chaining—resources.configurations?.data and resources.revisions?.data align properly with the hook's return shape. However, returning null during the loading state leaves the modal with no visual feedback. The codebase consistently uses <LoadingBox /> for this pattern (e.g., CreateKnatifyPage, EventSourcePage, Subscribe). Replace the null return with a loading spinner for better perceived responsiveness.

🤖 Prompt for AI Agents
In
`@frontend/packages/knative-plugin/src/components/traffic-splitting/TrafficSplittingController.tsx`
around lines 48 - 50, The controller currently returns null when resources are
still loading; update TrafficSplittingController so that when loaded is false it
renders the project's LoadingBox component instead of null (i.e., return
<LoadingBox />), keeping the existing return when loaded is true:
<TrafficSplitting {...props} service={props.obj} revisions={revisions} />; also
add an import for LoadingBox if not already present and ensure
getKnativeRevisionsData and TrafficSplitting usage remain unchanged.

@krishagarwal278
Copy link
Member Author

/retest

@openshift-ci-robot
Copy link
Contributor

openshift-ci-robot commented Feb 13, 2026

@krishagarwal278: This pull request references CONSOLE-5028 which is a valid jira issue.

Details

In response to this:

Tested locally to check refactored components in Dev-Console and knative-plugin packages are working as expected:

Screenshot 2026-02-13 at 3 48 19 PM

Summary by CodeRabbit

Release Notes

  • Refactor
  • Updated and enhanced resource loading mechanisms across development console and knative plugin components for improved data consistency and error state handling.
  • Standardized internal data synchronization patterns in project access, resource import, monitoring, and traffic management features to improve overall system reliability and performance consistency.
  • Improved loading state indicators and error information clarity across affected console components.

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.

@openshift-ci
Copy link
Contributor

openshift-ci bot commented Feb 14, 2026

@krishagarwal278: all tests passed!

Full PR test history. Your PR dashboard.

Details

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. I understand the commands that are listed here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

component/dev-console Related to dev-console component/knative Related to knative-plugin jira/valid-reference Indicates that this PR references a valid Jira ticket of any type.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants