Repository: opendatahub-io/odh-dashboard
Pull request #3882: stashed home hint banner for hardware profiles
Author: login: rsun19
Labels: name: lgtm
name: approved
Created: 2025-03-07T21:35:11Z | Merged: 2025-03-14T16:36:05Z

<!--- If this is a non-code change, this template is not required; reference any issues or top-level descriptions as needed -->
<!--- All code change PRs should relate to an issue, reference it here; see example below -->
https://issues.redhat.com/browse/RHOAIENG-21273

## Description
<!--- Describe your changes in detail; the what, the why, any findings, etc -->
<!--- Include any screenshots of changed UI; Include any gifs if it was a flow / UX change -->

<img width="1546" alt="Screenshot 2025-03-13 at 12 19 21 PM" src="https://github.com/user-attachments/assets/137b44db-6825-4702-afb7-27f3fe54301d" />

Stashed the home hint banner for hardware profiles for future use. It no longer appears.

## How Has This Been Tested?
<!--- Please describe in detail how you tested your changes. -->
<!--- Include details of your testing environment, and the tests you ran to -->
<!--- see how your change affects other areas of the code, etc. -->

set feature flag for hardware profiles and visit the home page. the banner should not appear.

## Test Impact
<!--- What tests have you done to cover the implemented functionality -->
<!--- If tests are not applicable, explain why here -->

I reverted the cypress tests that enforce their disappearance

## Request review criteria:
<!--- This PR will be merged by any repository approver when it meets all the points in the checklist -->
<!--- Go over all the following points, and put an `x` in all the boxes that apply. -->

Self checklist (all need to be checked):
- [x] The developer has manually tested the changes and verified that the changes work
- [x] Testing instructions have been added in the PR body (for PRs involving changes that are not immediately obvious).
- [x] The developer has added tests or explained why testing cannot be added (unit or cypress tests for related changes)

If you have UI changes: 
<!--- You can ignore these if you are doing manifest, backend, internal logic, etc changes; aka non-UI / visual changes -->
- [x] Included any necessary screenshots or gifs if it was a UI change.
- [ ] Included tags to the UX team if it was a UI/UX change.

After the PR is posted & before it merges:
- [ ] The developer has tested their solution on a cluster by using the image produced by the PR to `main`



Diff:
diff --git a/frontend/src/__tests__/cypress/cypress/pages/home/home.ts b/frontend/src/__tests__/cypress/cypress/pages/home/home.ts
index 8eb0c238ae..18a7014b4f 100644
--- a/frontend/src/__tests__/cypress/cypress/pages/home/home.ts
+++ b/frontend/src/__tests__/cypress/cypress/pages/home/home.ts
@@ -17,6 +17,10 @@ class HomePage {
     cy.testA11y();
   }
 
+  findJupyterIcon() {
+    return cy.findByTestId('jupyter-hint-icon');
+  }
+
   findHint() {
     return cy.findByTestId('home-page-hint');
   }
@@ -25,6 +29,10 @@ class HomePage {
     return cy.findByTestId('hint-body-text');
   }
 
+  findHintLink() {
+    return cy.findByTestId('home-page-hint-navigate');
+  }
+
   findHintCloseButton() {
     return cy.findByTestId('home-page-hint-close');
   }
diff --git a/frontend/src/__tests__/cypress/cypress/tests/mocked/home/home.cy.ts b/frontend/src/__tests__/cypress/cypress/tests/mocked/home/home.cy.ts
index fba5c86dfe..122c8b5438 100644
--- a/frontend/src/__tests__/cypress/cypress/tests/mocked/home/home.cy.ts
+++ b/frontend/src/__tests__/cypress/cypress/tests/mocked/home/home.cy.ts
@@ -1,33 +1,47 @@
 import { enabledPage } from '~/__tests__/cypress/cypress/pages/enabled';
 import { mockComponents } from '~/__mocks__/mockComponents';
 import { homePage } from '~/__tests__/cypress/cypress/pages/home/home';
+import { verifyRelativeURL } from '~/__tests__/cypress/cypress/utils/url';
 
 describe('Home page', () => {
   beforeEach(() => {
     cy.interceptOdh('GET /api/components', { query: { installed: 'true' } }, mockComponents());
     homePage.initHomeIntercepts();
   });
-
+  it('should be shown by default', () => {
+    homePage.visit();
+    // enabled applications page is still navigable
+    enabledPage.visit();
+  });
   it('should be not shown when disabled', () => {
-    homePage.initHomeIntercepts({ disableHardwareProfiles: true });
+    homePage.initHomeIntercepts({ disableHome: true });
+    homePage.visit(false);
+    enabledPage.shouldHaveEnabledPageSection();
+  });
+  it('should show the home page hint', () => {
     homePage.visit();
-    homePage.findHint().should('not.exist');
+    homePage.findJupyterIcon().should('be.visible');
+    homePage.findHintText().should('contain', 'Jupyter');
+
+    // // enabled applications page is still navigable
+    homePage.findHintLink().click();
+    verifyRelativeURL('/enabled');
   });
 
-  it('should show the home page hint', () => {
-    homePage.initHomeIntercepts({ disableHardwareProfiles: false });
+  it('should hide the home page hint when the notebook controller is disabled.', () => {
+    homePage.initHomeIntercepts({ disableNotebookController: true });
     homePage.visit();
-    homePage.findHint().should('exist');
-    homePage.findHintText().should('contain', 'Hardware profiles');
+    homePage.findHint().should('not.exist');
   });
 
   it('should hide the home page hint when closed', () => {
-    homePage.initHomeIntercepts({ disableHardwareProfiles: false });
     homePage.visit();
     homePage.findHintCloseButton().click();
     homePage.findHint().should('not.exist');
 
+    // hint should not reappear when home page is navigated to
     enabledPage.visit();
+    enabledPage.shouldHaveEnabledPageSection();
     homePage.returnToHome();
     homePage.findHint().should('not.exist');
   });
diff --git a/frontend/src/pages/home/HardwareProfilesHomeHint.tsx b/frontend/src/pages/home/HardwareProfilesHomeHint.tsx
new file mode 100644
index 0000000000..7fa3ffb210
--- /dev/null
+++ b/frontend/src/pages/home/HardwareProfilesHomeHint.tsx
@@ -0,0 +1,42 @@
+import * as React from 'react';
+import { Content } from '@patternfly/react-core';
+import TitleWithIcon from '~/concepts/design/TitleWithIcon';
+import { ProjectObjectType } from '~/concepts/design/utils';
+import ExternalLink from '~/components/ExternalLink';
+import { SupportedArea, useIsAreaAvailable } from '~/concepts/areas';
+import HomeHint from './HomeHint';
+
+const HardwareProfilesHomeHint: React.FC = () => {
+  const releaseNoteDocumentation =
+    'https://docs.redhat.com/en/documentation/red_hat_openshift_ai/2025';
+
+  return (
+    <HomeHint
+      title={
+        <TitleWithIcon
+          title={
+            <>Hardware profiles, formerly &quot;Accelerator profiles&quot;, have new features</>
+          }
+          objectType={ProjectObjectType.acceleratorProfile}
+        />
+      }
+      body={
+        <>
+          <Content component="p" data-testid="hint-body-text">
+            Hardware profiles offer more flexibility by enabling administrators to create profiles
+            for additional types of identifiers, limit workload resource allocations, and target
+            workloads to specific nodes by including tolerations and nodeSelectors in profiles.
+          </Content>
+          <ExternalLink
+            text="Find the 2.19 release notes in the documentation"
+            to={releaseNoteDocumentation}
+          />
+        </>
+      }
+      homeHintKey="hardware-profiles-intro"
+      isDisplayed={useIsAreaAvailable(SupportedArea.HARDWARE_PROFILES).status}
+    />
+  );
+};
+
+export default HardwareProfilesHomeHint;
diff --git a/frontend/src/pages/home/Home.tsx b/frontend/src/pages/home/Home.tsx
index 46d7d44c44..4f4ac78de2 100644
--- a/frontend/src/pages/home/Home.tsx
+++ b/frontend/src/pages/home/Home.tsx
@@ -8,7 +8,7 @@ import ProjectsSection from './projects/ProjectsSection';
 import { useAIFlows } from './aiFlows/useAIFlows';
 import { useResourcesSection } from './resources/useResourcesSection';
 import { useEnableTeamSection } from './useEnableTeamSection';
-import HomeHint from './HomeHint';
+import LandingPageHomeHint from './LandingPageHomeHint';
 
 const Home: React.FC = () => {
   const { status: projectsAvailable } = useIsAreaAvailable(SupportedArea.DS_PROJECTS_VIEW);
@@ -18,7 +18,7 @@ const Home: React.FC = () => {
 
   return (
     <div data-testid="home-page">
-      <HomeHint />
+      <LandingPageHomeHint />
       {!projectsAvailable && !aiFlows && !resourcesSection && !enableTeamSection ? (
         <PageSection
           hasBodyWrapper={false}
diff --git a/frontend/src/pages/home/HomeHint.tsx b/frontend/src/pages/home/HomeHint.tsx
index e3a5eaf22f..8ab2f37a1a 100644
--- a/frontend/src/pages/home/HomeHint.tsx
+++ b/frontend/src/pages/home/HomeHint.tsx
@@ -4,28 +4,29 @@ import {
   Card,
   CardBody,
   CardHeader,
+  Content,
   Flex,
   FlexItem,
   PageSection,
-  Content,
 } from '@patternfly/react-core';
 import { TimesIcon } from '@patternfly/react-icons';
 import { useBrowserStorage } from '~/components/browserStorage';
-import TitleWithIcon from '~/concepts/design/TitleWithIcon';
-import { ProjectObjectType } from '~/concepts/design/utils';
-import ExternalLink from '~/components/ExternalLink';
-import { SupportedArea, useIsAreaAvailable } from '~/concepts/areas';
 
-const HomeHint: React.FC = () => {
+type HomeHintProps = {
+  title: React.ReactNode;
+  body: React.ReactNode;
+  isDisplayed: boolean;
+  homeHintKey: string;
+  image?: React.ReactNode;
+};
+
+const HomeHint: React.FC<HomeHintProps> = ({ title, body, isDisplayed, homeHintKey, image }) => {
   const [hintHidden, setHintHidden] = useBrowserStorage<boolean>(
-    'odh.dashboard.landing.hint',
+    `odh.dashboard.landing.hint-${homeHintKey}`,
     false,
   );
-  const isHardwareProfileAvailable = useIsAreaAvailable(SupportedArea.HARDWARE_PROFILES).status;
 
-  const releaseNoteDocumentation =
-    'https://docs.redhat.com/en/documentation/red_hat_openshift_ai/2025';
-  if (hintHidden || !isHardwareProfileAvailable) {
+  if (hintHidden || !isDisplayed) {
     return null;
   }
 
@@ -38,19 +39,7 @@ const HomeHint: React.FC = () => {
             justifyContent={{ default: 'justifyContentSpaceBetween' }}
           >
             <FlexItem>
-              <Content>
-                <Content component="h2">
-                  <TitleWithIcon
-                    title={
-                      <>
-                        Hardware profiles, formerly &quot;Accelerator profiles&quot;, have new
-                        features
-                      </>
-                    }
-                    objectType={ProjectObjectType.acceleratorProfile}
-                  />
-                </Content>
-              </Content>
+              <Content component="h2">{title}</Content>
             </FlexItem>
             <FlexItem>
               <Button
@@ -70,20 +59,8 @@ const HomeHint: React.FC = () => {
             gap={{ default: 'gapMd' }}
             flexWrap={{ default: 'nowrap' }}
           >
-            <FlexItem>
-              <Content>
-                <Content component="p" data-testid="hint-body-text">
-                  Hardware profiles offer more flexibility by enabling administrators to create
-                  profiles for additional types of identifiers, limit workload resource allocations,
-                  and target workloads to specific nodes by including tolerations and nodeSelectors
-                  in profiles.
-                </Content>
-                <ExternalLink
-                  text="Find the 2.19 release notes in the documentation"
-                  to={releaseNoteDocumentation}
-                />
-              </Content>
-            </FlexItem>
+            {image}
+            <FlexItem>{body}</FlexItem>
           </Flex>
         </CardBody>
       </Card>
diff --git a/frontend/src/pages/home/LandingPageHomeHint.tsx b/frontend/src/pages/home/LandingPageHomeHint.tsx
new file mode 100644
index 0000000000..bdf30c314f
--- /dev/null
+++ b/frontend/src/pages/home/LandingPageHomeHint.tsx
@@ -0,0 +1,41 @@
+import * as React from 'react';
+import { Content } from '@patternfly/react-core';
+import { Link } from 'react-router-dom';
+import jupyterImg from '~/images/jupyter.svg';
+import { ODH_PRODUCT_NAME } from '~/utilities/const';
+import { useCheckJupyterEnabled } from '~/utilities/notebookControllerUtils';
+import HomeHint from './HomeHint';
+
+const LandingPageHomeHint: React.FC = () => (
+  <HomeHint
+    title={<>Looking for the previous landing page?</>}
+    body={
+      <Content component="p" data-testid="hint-body-text">
+        {ODH_PRODUCT_NAME} has a new landing page. You can access applications that are enabled for
+        your organization, such as Jupyter, from the{' '}
+        <Link to="/enabled" data-testid="home-page-hint-navigate">
+          Enabled applications
+        </Link>{' '}
+        page.
+      </Content>
+    }
+    isDisplayed={useCheckJupyterEnabled()}
+    homeHintKey="new-landing-page-intro"
+    image={
+      <img
+        data-testid="jupyter-hint-icon"
+        src={jupyterImg}
+        alt="Jupyter"
+        style={{
+          height: 42,
+          maxWidth: 'unset',
+          backgroundColor: 'var(--pf-t--color--white)',
+          padding: 'var(--pf-t--global--spacer--xs)',
+          borderRadius: 'var(--pf-t--global--border--radius--small)',
+        }}
+      />
+    }
+  />
+);
+
+export default LandingPageHomeHint;


Reviews:
user: login: dpanshug
body: Can you add a TODO comment to the commented-out code that needs to be restored in the future?








state: CHANGES_REQUESTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-10T09:31:30Z
user: login: Gkrumbach07
state: CHANGES_REQUESTED
author_association: MEMBER
submitted_at: 2025-03-10T18:03:48Z
user: login: rsun19
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-10T18:49:57Z
user: login: rsun19
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-10T20:30:21Z
user: login: Gkrumbach07
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-11T13:41:23Z
user: login: DaoDaoNoCode
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-13T16:27:20Z
user: login: Gkrumbach07
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-13T21:04:21Z
user: login: Gkrumbach07
body: /lgtm
state: APPROVED
author_association: MEMBER
submitted_at: 2025-03-14T15:33:58Z

Review comments:
diff_hunk: @@ -18,7 +17,6 @@ const Home: React.FC = () => {
 
   return (
     <div data-testid="home-page">
-      <HomeHint />
path: frontend/src/pages/home/Home.tsx
user: login: Gkrumbach07
body: please bring back the old home hint
created_at: 2025-03-10T18:03:44Z
author_association: MEMBER
diff_hunk: @@ -18,7 +17,6 @@ const Home: React.FC = () => {
 
   return (
     <div data-testid="home-page">
-      <HomeHint />
path: frontend/src/pages/home/Home.tsx
user: login: rsun19
body: should i just comment it out then?
created_at: 2025-03-10T18:49:57Z
author_association: CONTRIBUTOR
diff_hunk: @@ -18,7 +17,6 @@ const Home: React.FC = () => {
 
   return (
     <div data-testid="home-page">
-      <HomeHint />
path: frontend/src/pages/home/Home.tsx
user: login: rsun19
body: other than that not sure how else to stash it
created_at: 2025-03-10T20:30:21Z
author_association: CONTRIBUTOR
diff_hunk: @@ -18,7 +17,6 @@ const Home: React.FC = () => {
 
   return (
     <div data-testid="home-page">
-      <HomeHint />
path: frontend/src/pages/home/Home.tsx
user: login: Gkrumbach07
body: so there was an old home hint that i link to in the PR in the jira. so we should being that bake but still keep this hardware profile one. So you will end with 
- HardwareProfileHomeHint
- WHateverTheOldHomeHint
- probably a BaseHomeHint
created_at: 2025-03-11T13:41:23Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,97 @@
+import * as React from 'react';
+import {
+  Button,
+  Card,
+  CardBody,
+  CardHeader,
+  Flex,
+  FlexItem,
+  Content,
+} from '@patternfly/react-core';
+import { TimesIcon } from '@patternfly/react-icons';
+import { useNavigate } from 'react-router-dom';
+import jupyterImg from '~/images/jupyter.svg';
+import { useBrowserStorage } from '~/components/browserStorage';
+import { ODH_PRODUCT_NAME } from '~/utilities/const';
+import { useCheckJupyterEnabled } from '~/utilities/notebookControllerUtils';
+
+const LandingPageHomeHint: React.FC = () => {
+  const navigate = useNavigate();
+  const [hintHidden, setHintHidden] = useBrowserStorage<boolean>(
+    'odh.dashboard.landing.hint',
+    false,
+  );
+  const jupyterEnabled = useCheckJupyterEnabled();
+
+  if (hintHidden || !jupyterEnabled) {
+    return null;
+  }
+
+  return (
+    <Card data-testid="home-page-hint" style={{ borderRadius: 16 }}>
+      <CardHeader>
+        <Flex
+          alignItems={{ default: 'alignItemsCenter' }}
+          justifyContent={{ default: 'justifyContentSpaceBetween' }}
+        >
+          <FlexItem>
+            <Content>
+              <Content component="h2">Looking for the previous landing page?</Content>
+            </Content>
+          </FlexItem>
+          <FlexItem>
+            <Button
+              icon={<TimesIcon />}
+              data-testid="home-page-hint-close"
+              aria-label="close landing page hint"
+              isInline
+              variant="plain"
+              onClick={() => setHintHidden(true)}
+            />
+          </FlexItem>
+        </Flex>
+      </CardHeader>
+      <CardBody style={{ maxWidth: 880 }}>
+        <Flex
+          alignItems={{ default: 'alignItemsCenter' }}
+          gap={{ default: 'gapMd' }}
+          flexWrap={{ default: 'nowrap' }}
+        >
+          <img
+            data-testid="jupyter-hint-icon"
+            src={jupyterImg}
+            alt="Jupyter"
+            style={{
+              height: 42,
+              maxWidth: 'unset',
+              backgroundColor: 'var(--pf-t--color--white)',
+              padding: 'var(--pf-t--global--spacer--xs)',
+              borderRadius: 'var(--pf-t--global--border--radius--small)',
+            }}
+          />
+          <FlexItem>
+            <Content>
+              <Content component="p" data-testid="hint-body-text">
+                {ODH_PRODUCT_NAME} has a new landing page. You can access applications that are
+                enabled for your organization, such as Jupyter, from the{' '}
+                <Button
path: frontend/src/pages/home/LandingPageHomeHint.tsx
user: login: DaoDaoNoCode
body: Cannot we replace this `Button` component with `Link` component simply? It will have only 2 props: `to='/enabled'` and `data-testid="home-page-hint-navigate"`
created_at: 2025-03-13T16:27:20Z
author_association: MEMBER
diff_hunk: @@ -4,28 +4,28 @@ import {
   Card,
   CardBody,
   CardHeader,
+  Content,
   Flex,
   FlexItem,
   PageSection,
-  Content,
 } from '@patternfly/react-core';
 import { TimesIcon } from '@patternfly/react-icons';
 import { useBrowserStorage } from '~/components/browserStorage';
-import TitleWithIcon from '~/concepts/design/TitleWithIcon';
-import { ProjectObjectType } from '~/concepts/design/utils';
-import ExternalLink from '~/components/ExternalLink';
-import { SupportedArea, useIsAreaAvailable } from '~/concepts/areas';
 
-const HomeHint: React.FC = () => {
+type HomeHintProps = {
+  title: React.ReactNode;
+  body: React.ReactNode;
+  isDisplayed: boolean;
+  image?: React.ReactNode;
+};
+
+const HomeHint: React.FC<HomeHintProps> = ({ title, image, body, isDisplayed }) => {
   const [hintHidden, setHintHidden] = useBrowserStorage<boolean>(
     'odh.dashboard.landing.hint',
     false,
   );
path: frontend/src/pages/home/HomeHint.tsx
user: login: Gkrumbach07
body: this key needs to chnage based on the type of home hint. becuase if we change the home hint then we will want users that have hidden the hint before to see the new one. probably passing some key or id in shoudl do the trick and slap it on the end of the key
created_at: 2025-03-13T21:04:21Z
author_association: MEMBER

PR comments:
user: login: codecov[bot]
created_at: 2025-03-07T22:15:50Z
body: ## [Codecov](https://app.codecov.io/gh/opendatahub-io/odh-dashboard/pull/3882?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=opendatahub-io) Report
All modified and coverable lines are covered by tests :white_check_mark:
> Project coverage is 84.46%. Comparing base [(`083683e`)](https://app.codecov.io/gh/opendatahub-io/odh-dashboard/commit/083683e37e041bdca1909ab8a87fbc4fa123c359?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=opendatahub-io) to head [(`2e90e9b`)](https://app.codecov.io/gh/opendatahub-io/odh-dashboard/commit/2e90e9b82317cf3b4415d01e334a811d4ba2ef63?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=opendatahub-io).
> Report is 72 commits behind head on main.

<details><summary>Additional details and impacted files</summary>


[![Impacted file tree graph](https://app.codecov.io/gh/opendatahub-io/odh-dashboard/pull/3882/graphs/tree.svg?width=650&height=150&src=pr&token=UQM7NLQUXJ&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=opendatahub-io)](https://app.codecov.io/gh/opendatahub-io/odh-dashboard/pull/3882?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=opendatahub-io)

```diff
@@            Coverage Diff             @@
##             main    #3882      +/-   ##
==========================================
+ Coverage   84.35%   84.46%   +0.11%     
==========================================
  Files        1548     1579      +31     
  Lines       36380    37500    +1120     
  Branches    10225    10577     +352     
==========================================
+ Hits        30687    31673     +986     
- Misses       5693     5827     +134     
```

[see 3127 files with indirect coverage changes](https://app.codecov.io/gh/opendatahub-io/odh-dashboard/pull/3882/indirect-changes?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=opendatahub-io)

------

[Continue to review full report in Codecov by Sentry](https://app.codecov.io/gh/opendatahub-io/odh-dashboard/pull/3882?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=opendatahub-io).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=opendatahub-io)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://app.codecov.io/gh/opendatahub-io/odh-dashboard/pull/3882?dropdown=coverage&src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=opendatahub-io). Last update [083683e...2e90e9b](https://app.codecov.io/gh/opendatahub-io/odh-dashboard/pull/3882?dropdown=coverage&src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=opendatahub-io). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=opendatahub-io).

</details>
<details><summary>🚀 New features to boost your workflow: </summary>

- ❄ [Test Analytics](https://docs.codecov.com/docs/test-analytics): Detect flaky tests, report on failures, and find test suite problems.
- 📦 [JS Bundle Analysis](https://docs.codecov.com/docs/javascript-bundle-analysis): Save yourself from yourself by tracking and limiting bundle sizes in JS merges.
</details>
author_association: NONE
user: login: rsun19
created_at: 2025-03-10T13:25:03Z
body: /retest
author_association: CONTRIBUTOR
user: login: rsun19
created_at: 2025-03-13T16:19:59Z
body: fixed
author_association: CONTRIBUTOR
user: login: DaoDaoNoCode
created_at: 2025-03-13T16:31:10Z
body: Also, I am wondering if we could make a generic component for the home hint here. I saw so many custom styles and they are duplicated in different components. Unless all the hints are very different, we should look into making a generic component and pass necessary props to it like title, body, image...
author_association: MEMBER
user: login: rsun19
created_at: 2025-03-13T17:06:03Z
body: > Also, I am wondering if we could make a generic component for the home hint here. I saw so many custom styles and they are duplicated in different components. Unless all the hints are very different, we should look into making a generic component and pass necessary props to it like title, body, image...

if we do it this way, we need to find a way to stash the props. Maybe I can do this?

```
<homehint with old props />
{/* <homehint with hardware profile props /> */}
```

my concern is that the commented out props might not look as clean, but that's just my two cents
author_association: CONTRIBUTOR
user: login: DaoDaoNoCode
created_at: 2025-03-13T17:11:53Z
body: @rsun19 No, I mean we can still keep `LandingPageHomeHint` and `HardwareProfilesHomeHint` components, which will wrap the generic component I mentioned.
like
```
const LandingPageHomeHint = () => {
  const jupyterEnabled = useCheckJupyterEnabled();
  return <HomeHint isDisabled={!jupyterEnabled} {...otherLandingPageProps like title, body, image...} />
}
```
and
```
const HardwareProfilesHomeHint = () => {
  const isHardwareProfileAvailable = useIsAreaAvailable(SupportedArea.HARDWARE_PROFILES).status;
  return <HomeHint isDisabled={!isHardwareProfileAvailable} {...otherHardwareProfilesProps like title, body, image...} />
}
```
and in `HomeHint`, you can do all the state management there like `hintHidden`, and receive all the props you need to render the `Card` component.
And you can still render LandingPageHomeHint in your `HomeHintBase` (Actually, I think it still should be renamed to `HomeHint`, and we should name the generic component as `HomeHintBase`)
Let me know if that makes sense!
author_association: MEMBER
user: login: rsun19
created_at: 2025-03-13T18:10:12Z
body: @DaoDaoNoCode let me know if this is what you mean
author_association: CONTRIBUTOR
user: login: DaoDaoNoCode
created_at: 2025-03-13T18:13:18Z
body: @rsun19 Exactly!
author_association: MEMBER
user: login: openshift-ci[bot]
created_at: 2025-03-14T15:34:09Z
body: [APPROVALNOTIFIER] This PR is **APPROVED**

This pull-request has been approved by: *<a href="https://github.com/opendatahub-io/odh-dashboard/pull/3882#pullrequestreview-2685944077" title="LGTM">Gkrumbach07</a>*

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=opendatahub-io%2Fodh-dashboard).

The pull request process is described [here](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process)

<details >
Needs approval from an approver in each of these files:

- ~~[frontend/OWNERS](https://github.com/opendatahub-io/odh-dashboard/blob/main/frontend/OWNERS)~~ [Gkrumbach07]

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":[]} -->
author_association: CONTRIBUTOR