diff --git a/.travis.yml b/.travis.yml index c3bc70a41a..3b9b016d9a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,11 +1,12 @@ language: node_js sudo: required +dist: jammy notifications: email: false slack: secure: 'd3g5oKl5kfzi2L96QTrj2g77lzLWzjnM6Ct2OTXRrk90GxxhwHS8RH4Q1IgBqkQjw68nkq7CNE9oAs+pt3si8kT4GQ164YLoTMVkDPBGOoOoMACPyanxQOEluUfdLEDIzChy/7EdlY3l1J2IM+lOK4e95jUwsT9BSXBsSladP++1EUiZfon9JcQSiSZa0e1/cVxLpEDuBB2cruUSTZ9sUATe/XZ0uH1EGzrooQJMkRgdty5UyNSsMxkvAY0Haivq8u9/gWAsLar0bA/90M5CVK7yohh9fY9UfTUbXVqwR3dFAXuW+SURrFVnPAX4FLZt/D09cg/CVCvoasiZdNi9RAeKOCfN+FoxB2ZJNnuM+4KDJX3dxnatd/stmEH1bcd75i4mh9zOWE1HX5d23HuZ4sKdDPpvhG3l7SpZfhLv0/EKL10ld9RdIaiTO2uPI3rsoyDeArzeV+09+dbB1iPKnS/3/Iw5KLhbew3mdJXKVfRk6KYcJySjT8EltrNy5Y7mty7/JzWssSpIpkMCnu6RGAtXO2v/jUfFm1WvsKK5BeH5efbLi1sjMNbVTeA3Bp8pvRPuw+50l94uDfeQ1HUTrq5zKXMUaG9dTdaYZX4fEDMmrbM1TLudjb9Xj4elaA5ioBH0gRFxAnSVTmrKFtFoCRVaqfmj3ceqxttCLUpkfvI=' node_js: -- '16' +- '18' before_install: - npm install -g npm@latest install: @@ -38,4 +39,4 @@ env: cache: directories: - "$HOME/.npm" - - ".cache" \ No newline at end of file + - ".cache" diff --git a/config/webpack.config.js b/config/webpack.config.js index 21ca19c115..a84daec37a 100644 --- a/config/webpack.config.js +++ b/config/webpack.config.js @@ -198,7 +198,7 @@ const pfConfig = { path: path.resolve(__dirname, '../build/js/pf'), // the HMR needs dynamic entry filename to remove name conflicts filename: '[name].js', - publicPath: `${publicPath}pf/`, + publicPath: `auto`, }, plugins: [new MiniCssExtractPlugin()], stats: { diff --git a/cypress/e2e/release-gate/search.cy.tsx b/cypress/e2e/release-gate/search.cy.tsx new file mode 100644 index 0000000000..b88347640b --- /dev/null +++ b/cypress/e2e/release-gate/search.cy.tsx @@ -0,0 +1,69 @@ +const searchResponse = { + response: { + numFound: 2, + start: 0, + maxScore: 10.0, + docs: [ + { + id: 'hcc-module-/openshift/create-OPENSHIFT.cluster.create.azure', + view_uri: 'https://console.redhat.com/openshift/create', + documentKind: 'ModuleDefinition', + allTitle: 'Azure Red Hat OpenShift', + bundle: ['openshift'], + bundle_title: ['OpenShift'], + relative_uri: '/openshift/create', + alt_titles: ['ARO', 'Azure', 'OpenShift on Azure'], + abstract: 'https://console.redhat.com/openshift/create', + timestamp: '2023-08-22T17:01:31.717Z', + _version_: 1774949404248113152, + }, + { + id: 'hcc-module-/openshift/releases-openshift.releases', + view_uri: 'https://console.redhat.com/openshift/releases', + documentKind: 'ModuleDefinition', + allTitle: 'Releases', + bundle: ['openshift'], + bundle_title: ['OpenShift'], + relative_uri: '/openshift/releases', + icons: 'InfrastructureIcon', + abstract: 'View general information on the most recent OpenShift Container Platform release versions that you can install.', + timestamp: '2023-08-15T10:55:46.769Z', + _version_: 1774949404248113152, + }, + ], + }, + highlighting: { + 'hcc-module-/openshift/create-OPENSHIFT.cluster.create.azure': { + abstract: ['https://console.redhat.com/openshift/create'], + allTitle: ['Azure Red Hat OpenShift'], + bundle: ['openshift'], + }, + 'hcc-module-/openshift/releases-openshift.releases': { + abstract: ['View general information on the most recent OpenShift Container Platform release versions that you can install.'], + allTitle: ['Releases'], + bundle: ['openshift'], + }, + }, +}; + +describe('Search', () => { + it('search for openshift services', () => { + cy.login(); + cy.visit('/'); + cy.intercept( + { + method: 'GET', + url: '**/hydra/rest/search/**', + }, + searchResponse + ).as('search'); + cy.get('.chr-c-search__input').click().type('openshift'); + cy.wait('@search').its('response.statusCode').should('equal', 200); + cy.get('@search.all').should('have.length', 1); + cy.screenshot(); + cy.get('.chr-c-search__input').should('contain', 'Top 2 results'); + cy.get('.chr-c-search__input li').first().should('contain', 'Azure'); + cy.get('.chr-c-search__input li').last().should('contain', 'Releases').click(); + cy.url().should('contain', '/openshift/releases'); + }); +}); diff --git a/docs/localWSDevelopment.md b/docs/localWSDevelopment.md index 004d61c6c8..24cbecdddb 100644 --- a/docs/localWSDevelopment.md +++ b/docs/localWSDevelopment.md @@ -9,7 +9,7 @@ ## Setting up the development environment -### Chrome service backend +### Chrome Service Backend The chrome service backend is the bridge between kafka and the browser client. It exposes a WS endpoint that allows the browser to connect to the service. @@ -18,14 +18,46 @@ The chrome service backend is the bridge between kafka and the browser client. I To enable it for local development with chrome UI follow these steps: 1. Make sure you are on the `main` branch or have created new branch fro the latest `main`. -2. If the WS feature is hidden behind a feature flag, and you don't want to go through the FF setup, [bypass this condition](https://github.com/RedHatInsights/chrome-service-backend/blob/main/main.go#L61) by adding `true || ..` to the condition in your local repository. -3. Start the kafka container by running `make kafka`. -4. Start the chrome service by running `go run .` in the repo root. -5. Run a `go run cmd/kafka/testMessage.go` to test the connection. You should see a log in the terminal from where the go server was started. +2. Start the kafka and unleash containers by running `make infra`. +3. Start the chrome service by running `make dev` in the repo root. +4. Run a `go run cmd/kafka/testMessage.go` to test the connection. You should see a log in the terminal from where the go server was started. -#### The `make kafka` command failed. -It is possible that you have services running on your machine that occupy either the kafka or postgres ports. To change the default values, open the `local/kafka-compose.yaml` and change the postgres or kafka (or both) port bindings: + +### Chrome Frontend + +1. Ensure you are on the latest version for chrome `master` branch. The support for WS client was added in [#2525](https://github.com/RedHatInsights/insights-chrome/pull/2525). +2. Once your chrome service backend is running, start the chrome dev server with the chrome service config using this command: `CHROME_SERVICE=8000 yarn dev`. +3. The WS client connection is hidden behind a `platform.chrome.notifications-drawer` feature flag. If its not available in your current environment (stage or prod or EE), bypass the feature flag condition in the `src/hooks/useChromeServiceEvents.ts` file. +4. Open the browser, open the browser console, emit a custom message from the chrome service terminal using `go run cmd/kafka/testMessage.go`. +5. In the network tab of your browser console, filter only to show `ws` communication, click on related ws connection (there will be a couple for webpack dev server, ignore these and find `wss://stage.foo.redhat.com:1337/wss/chrome-service/v1/ws`). +6. Click the 'messages' tab in chrome or the 'response' tab in firefox and observe the messages being pushed down to the browser. The messages should be similar to the sample payload below. + +#### Sample WS message payload + +```js +{ + // the actual payload consumed by chrome + data: { + description: "Some longer description", + title: "New notification" + }, + // cloud events sub protocol metadata + datacontenttype: "application/json", + id: "test-message", + source: "https://whatever.service.com", + specversion: "1.0.2", + time: "2023-05-23T11:54:03.879689005+02:00", + // a type field used to identify message purpose + type: "notifications.drawer" +} +``` + +## Troubleshooting + +#### The `make infra` command failed. + +It is possible that you have services running on your machine that occupy either the kafka or postgres ports. To change the default values, open the `local/full-stack-compose.yaml` and change the postgres or kafka or unleash (or all) port bindings: ```diff diff --git a/local/kafka-compose.yaml b/local/kafka-compose.yaml @@ -55,33 +87,4 @@ index f8f3451..60fc9cd 100644 #### The `go run cmd/kafka/testMessage.go` -The command will not work if the main server is not running, or the ws consumer did not start. Ensure you either have feature flags setup or you have bypassed the condition listed in the [step 2](#bypass). - - -### Chrome frontend - -1. ensure you are on the latest version for chrome `master` branch. The support for WS client was added in [#2525](https://github.com/RedHatInsights/insights-chrome/pull/2525). -2. Once your chrome service backend is running, start the chrome dev server with the chrome service config using this command: `CHROME_SERVICE=8000 yarn dev`. -3. The WS client connection is hidden behind a `platform.chrome.notifications-drawer` feature flag. If its not available in your current environment (stage or prod or EE), bypass the feature flag condition in the `src/hooks/useChromeServiceEvents.ts` file. -4. OPen the browser, open the browser console, emit a custom message from the chrome service terminal using `go run cmd/kafka/testMessage.go`. -5. In the network tab of your browser console, filter only to show `ws` communication, click on related ws connection (there will be a couple for webpack dev server, ignore these) and observer the messages being pushed down to the browser. - -#### Sample WS message payload - -```js -{ - // the actual payload consumed by chrome - data: { - description: "Some longer description", - title: "New notification" - }, - // cloud events sub protocol metadata - datacontenttype: "application/json", - id: "test-message", - source: "https://whatever.service.com", - specversion: "1.0.2", - time: "2023-05-23T11:54:03.879689005+02:00", - // a type field used to identify message purpose - type: "notifications.drawer" -} -``` +The command will not work if the main server is not running, or the ws consumer did not start. Ensure you either have feature flags setup or the pods are running correctly with `podman ps`. diff --git a/src/auth/index.ts b/src/auth/index.ts index 7e0b8ba239..0005a535cb 100644 --- a/src/auth/index.ts +++ b/src/auth/index.ts @@ -6,7 +6,7 @@ import { Store } from 'redux'; import * as jwt from '../jwt/jwt'; import { getTokenWithAuthorizationCode } from '../cognito/auth'; -import { ITLess } from '../utils/common'; +import { ITLessCognito } from '../utils/common'; import consts, { defaultAuthOptions as defaultOptions } from '../utils/consts'; import { ACCOUNT_REQUEST_TIMEOUT, ACTIVE_REMOTE_REQUEST, CROSS_ACCESS_ACCOUNT_NUMBER, CROSS_ACCESS_ORG_ID } from '../utils/consts'; import qe from '../utils/iqeEnablement'; @@ -20,7 +20,7 @@ export type LibJWT = { }; const TIMER_STR = '[JWT][jwt.js] Auth time'; -const isITLessEnv = ITLess(); +const isITLessCognito = ITLessCognito(); function bouncer() { if (!jwt.isAuthenticated()) { cookie.remove(defaultOptions.cookieName); @@ -48,6 +48,7 @@ export const createAuthObject = (libjwt: LibJWT, getUser: () => Promise libjwt.jwt.doOffline(consts.noAuthParam, consts.offlineToken, globalConfig?.chrome?.ssoUrl || globalConfig?.chrome?.config?.ssoUrl), getToken: () => libjwt.initPromise.then(() => libjwt.jwt.getUserInfo().then(() => libjwt.jwt.getEncodedToken())), + getRefreshToken: () => libjwt.jwt.getRefreshToken(), getUser, qe: { ...qe, @@ -67,7 +68,7 @@ export const createGetUser = (libjwt: LibJWT): (() => Promise Promise) => { const fetchPermissions = createFetchPermissionsWatcher(getUser); return async (app = '', bypassCache?: boolean) => { - if (isITLessEnv) { + if (isITLessCognito) { const cogToken = await getTokenWithAuthorizationCode(); return fetchPermissions(cogToken || '', app, bypassCache); } else { @@ -98,7 +99,7 @@ export default ({ ssoUrl, ssoScopes }: { ssoUrl?: string; ssoScopes: string[] }) const promise = jwt.init(options, ssoUrl).then(bouncer); return { - getOfflineToken: () => (isITLessEnv ? getTokenWithAuthorizationCode() : getOfflineToken(options.realm, options.clientId, ssoUrl)), + getOfflineToken: () => (isITLessCognito ? getTokenWithAuthorizationCode() : getOfflineToken(options.realm, options.clientId, ssoUrl)), jwt: jwt, initPromise: promise, }; diff --git a/src/bootstrap.tsx b/src/bootstrap.tsx index ef9bf46525..7c808a97ca 100644 --- a/src/bootstrap.tsx +++ b/src/bootstrap.tsx @@ -12,7 +12,7 @@ import { ACTIVE_REMOTE_REQUEST, CROSS_ACCESS_ACCOUNT_NUMBER } from './utils/cons import auth, { LibJWT, createGetUserPermissions, crossAccountBouncer } from './auth'; import sentry from './utils/sentry'; import registerAnalyticsObserver from './analytics/analyticsObserver'; -import { ITLess, generateRoutesList, getEnv, loadFedModules, noop, trustarcScriptSetup } from './utils/common'; +import { ITLess, ITLessCognito, generateRoutesList, getEnv, loadFedModules, noop, trustarcScriptSetup } from './utils/common'; import messages from './locales/data.json'; import ErrorBoundary from './components/ErrorComponents/ErrorBoundary'; import LibtJWTContext from './components/LibJWTContext'; @@ -135,7 +135,7 @@ const App = () => { document.title = `${title}console.redhat.com`; }, [documentTitle]); - if (isITLessEnv) { + if (ITLessCognito()) { return isReady && modules && scalprumConfig ? ( ) : ( diff --git a/src/chrome/create-chrome.ts b/src/chrome/create-chrome.ts index 19a61dd2b8..603b60a6c0 100644 --- a/src/chrome/create-chrome.ts +++ b/src/chrome/create-chrome.ts @@ -19,7 +19,7 @@ import { toggleFeedbackModal, toggleGlobalFilter, } from '../redux/actions'; -import { ITLess, getEnv, getEnvDetails, isBeta, isProd, updateDocumentTitle } from '../utils/common'; +import { ITLess, ITLessCognito, getEnv, getEnvDetails, isBeta, isProd, updateDocumentTitle } from '../utils/common'; import { createSupportCase } from '../utils/createCase'; import debugFunctions from '../utils/debugFunctions'; import { flatTags } from '../components/GlobalFilter/globalFilterApi'; @@ -99,10 +99,11 @@ export const createChromeContext = ({ }; const isITLessEnv = ITLess(); + const isITLessCognito = ITLessCognito(); const api: ChromeAPI = { ...actions, - auth: isITLessEnv ? createCognitoAuthObject(store) : createAuthObject(libJwt, getUser, store, modulesConfig), + auth: isITLessCognito ? createCognitoAuthObject(store) : createAuthObject(libJwt, getUser, store, modulesConfig), initialized: true, isProd, forceDemo: () => Cookies.set('cs_demo', 'true'), @@ -113,7 +114,7 @@ export const createChromeContext = ({ getEnvironmentDetails: () => getEnvDetails(), createCase: (fields?: any) => getUser().then((user) => createSupportCase(user!.identity, libJwt, fields)), getUserPermissions: async (app = '', bypassCache?: boolean) => { - if (isITLessEnv) { + if (isITLessCognito) { const cogToken = await getTokenWithAuthorizationCode(); return fetchPermissions(cogToken || '', app, bypassCache); } else { diff --git a/src/cognito/auth.ts b/src/cognito/auth.ts index 7cee76cd8f..2e3bbef17d 100644 --- a/src/cognito/auth.ts +++ b/src/cognito/auth.ts @@ -56,6 +56,7 @@ export async function getTokenWithAuthorizationCode() { const redirectUri = dataConfig?.redirectUri; if (!code && !refreshToken) { + localStorage.clear(); window.location.href = loginUrl; } if (refreshToken) { @@ -68,6 +69,7 @@ export async function getTokenWithAuthorizationCode() { body: `grant_type=refresh_token&client_id=${dataConfig?.ClientId}&refresh_token=${localStorage.getItem('REFRESH_TOKEN')}`, }); if (!response.ok) { + localStorage.clear(); window.location.href = loginUrl; throw new Error(`Request failed with status code ${response.status}`); } diff --git a/src/components/AppFilter/useAppFilter.test.js b/src/components/AppFilter/useAppFilter.test.js index 573b351d7d..9e7f2017da 100644 --- a/src/components/AppFilter/useAppFilter.test.js +++ b/src/components/AppFilter/useAppFilter.test.js @@ -368,13 +368,11 @@ describe('useAppFilter', () => { appId: 'foo', href: '/openshift/subscriptions/foo', title: 'subs-nested-ins', - isFedramp: false, }, { appId: 'foo', href: '/insights/subscriptions/foo', title: 'subs-nested-o', - isFedramp: false, }, ], title: 'Subscriptions', diff --git a/src/components/AppFilter/useAppFilter.ts b/src/components/AppFilter/useAppFilter.ts index c71dc4b273..6b59cd25dc 100644 --- a/src/components/AppFilter/useAppFilter.ts +++ b/src/components/AppFilter/useAppFilter.ts @@ -3,9 +3,8 @@ import { useEffect, useState } from 'react'; import { useSelector } from 'react-redux'; import { BundleNavigation, ChromeModule, NavItem } from '../../@types/types'; import { ReduxState } from '../../redux/store'; -import { ITLess, getChromeStaticPathname, isBeta, isProd } from '../../utils/common'; +import { getChromeStaticPathname, isBeta, isProd } from '../../utils/common'; import { evaluateVisibility } from '../../utils/isNavItemVisible'; -import { computeFedrampResult } from '../../utils/useRenderFedramp'; export type AppFilterBucket = { id: string; @@ -27,6 +26,8 @@ export const requiredBundles = [ ...(!isProd() ? previewBundles : isBeta() ? previewBundles : []), ]; +export const itLessBundles = ['openshift', 'insights', 'settings', 'iam']; + const bundlesOrder = [ 'application-services', 'openshift', @@ -41,8 +42,6 @@ const bundlesOrder = [ 'business-services', ]; -const isITLessEnv = ITLess(); - function findModuleByLink(href: string, { modules }: Pick = { modules: [] }) { const routes = (modules || []) .flatMap(({ routes }) => routes.map((route) => (typeof route === 'string' ? route : route.pathname))) @@ -55,7 +54,6 @@ function getBundleLink({ title, isExternal, href, routes, expandable, ...rest }: const subscriptionsLinks: NavItem[] = []; let url = href; let appId = rest.appId!; - let isFedramp = computeFedrampResult(isITLessEnv, url, modules[appId]); if (expandable) { routes?.forEach(({ href, title, ...rest }) => { if (href?.includes('/openshift/cost-management') && rest.filterable !== false) { @@ -65,7 +63,6 @@ function getBundleLink({ title, isExternal, href, routes, expandable, ...rest }: if (rest.filterable !== false && (href?.includes('/insights/subscriptions') || href?.includes('/openshift/subscriptions'))) { subscriptionsLinks.push({ ...rest, - isFedramp: false, // openshift and subs are never visible on fedramp. href, title, }); @@ -76,14 +73,12 @@ function getBundleLink({ title, isExternal, href, routes, expandable, ...rest }: const truncatedRoute = href.split('/').slice(0, 3).join('/'); url = isExternal ? href : moduleRoute.length > truncatedRoute.length ? moduleRoute : truncatedRoute; appId = rest.appId ? rest.appId : appId; - isFedramp = computeFedrampResult(isITLessEnv, url, modules[appId]); } }); } return { ...rest, - isFedramp, appId, isExternal, title, @@ -142,7 +137,6 @@ const useAppFilter = () => { }, []) .flat() .map((link) => getBundleLink(link, modules || {})) - .filter(({ isFedramp }) => (isITLessEnv ? !!isFedramp : true)) .filter(({ filterable }) => filterable !== false) || []; const bundleLinks: NavItem[] = []; const extraLinks: { cost: NavItem[]; subs: NavItem[] } = { diff --git a/src/components/ChromeRoute/ChromeRoute.tsx b/src/components/ChromeRoute/ChromeRoute.tsx index 1d401ce913..dbc64f6907 100644 --- a/src/components/ChromeRoute/ChromeRoute.tsx +++ b/src/components/ChromeRoute/ChromeRoute.tsx @@ -46,11 +46,13 @@ const ChromeRoute = memo( /** * update pendo metadata on application change */ - try { - window?.pendo?.updateOptions(getPendoConf(user as DeepRequired)); - } catch (error) { - console.error('Unable to update pendo options'); - console.error(error); + if (window.pendo) { + try { + window.pendo.updateOptions(getPendoConf(user as DeepRequired)); + } catch (error) { + console.error('Unable to update pendo options'); + console.error(error); + } } /** diff --git a/src/components/Header/Tools.tsx b/src/components/Header/Tools.tsx index cec8e2951a..93d5b460c9 100644 --- a/src/components/Header/Tools.tsx +++ b/src/components/Header/Tools.tsx @@ -88,7 +88,7 @@ const Tools = () => { const libjwt = useContext(LibtJWTContext); const intl = useIntl(); const location = useLocation(); - const settingsPath = `/settings/sources`; + const settingsPath = isITLessEnv ? `/settings/my-user-access` : `/settings/sources`; const identityAndAccessManagmentPath = '/iam/user-access/users'; const betaSwitcherTitle = `${isBeta() ? intl.formatMessage(messages.stopUsing) : intl.formatMessage(messages.use)} ${intl.formatMessage( messages.betaRelease @@ -132,7 +132,7 @@ const Tools = () => { const aboutMenuDropdownItems = [ { title: `${intl.formatMessage(messages.apiDocumentation)}`, - url: `https://developers.redhat.com/api-catalog/`, + onClick: () => window.open('https://developers.redhat.com/api-catalog/', '_blank'), isHidden: isITLessEnv, }, { @@ -143,17 +143,16 @@ const Tools = () => { }, { title: `${intl.formatMessage(messages.statusPage)}`, - url: 'https://status.redhat.com/', + onClick: () => window.open('https://status.redhat.com/', '_blank'), isHidden: isITLessEnv, }, { title: `${intl.formatMessage(messages.supportOptions)}`, - url: 'https://access.redhat.com/support', - isHidden: isITLessEnv, + url: isITLessEnv ? 'https://redhatgov.servicenowservices.com/css' : 'https://access.redhat.com/support', }, { title: `${intl.formatMessage(messages.insightsRhelDocumentation)}`, - url: `https://access.redhat.com/documentation/en-us/red_hat_insights`, + onClick: () => window.open('https://access.redhat.com/documentation/en-us/red_hat_insights', '_blank'), isHidden: getSection() !== 'insights' || isITLessEnv, }, diff --git a/src/components/Header/UserToggle.tsx b/src/components/Header/UserToggle.tsx index 98ac72ad4e..b04a655c04 100644 --- a/src/components/Header/UserToggle.tsx +++ b/src/components/Header/UserToggle.tsx @@ -6,7 +6,7 @@ import { Tooltip } from '@patternfly/react-core/dist/dynamic/components/Tooltip' import QuestionCircleIcon from '@patternfly/react-icons/dist/dynamic/icons/question-circle-icon'; import UserIcon from './UserIcon'; import { useSelector } from 'react-redux'; -import { ITLess, getEnv, isProd as isProdEnv } from '../../utils/common'; +import { ITLess, ITLessCognito, getEnv, isProd as isProdEnv } from '../../utils/common'; import ChromeLink from '../ChromeLink/ChromeLink'; import { useIntl } from 'react-intl'; import messages from '../../locales/Messages'; @@ -97,7 +97,7 @@ const buildItems = (username = '', isOrgAdmin?: boolean, accountNumber?: string, )} , - (isITLessEnv ? cogLogout() : logout(true))}> + (ITLessCognito() ? cogLogout() : logout(true))}> {intl.formatMessage(messages.logout)} , extraItems, diff --git a/src/components/Navigation/ChromeNavExpandable.tsx b/src/components/Navigation/ChromeNavExpandable.tsx index a8fcf5728f..ac570e8c40 100644 --- a/src/components/Navigation/ChromeNavExpandable.tsx +++ b/src/components/Navigation/ChromeNavExpandable.tsx @@ -1,29 +1,17 @@ import React from 'react'; import { NavExpandable } from '@patternfly/react-core/dist/dynamic/components/Nav'; import ChromeNavItemFactory from './ChromeNavItemFactory'; -import { useSelector } from 'react-redux'; -import { ITLess } from '../../utils/common'; -import { computeFedrampResult } from '../../utils/useRenderFedramp'; -import { ReduxState } from '../../redux/store'; import { ChromeNavExpandableProps } from '../../@types/types'; const ChromeNavExpandable = ({ title, routes, active, isHidden, id }: ChromeNavExpandableProps) => { - const modules = useSelector((state: ReduxState) => state.chrome.modules); - let filteredFedrampRoutes = routes; - if (ITLess()) { - filteredFedrampRoutes = routes.filter(({ appId, href }) => { - return appId && computeFedrampResult(appId, href, modules![appId]); - }); - } - - if (isHidden || filteredFedrampRoutes.filter(({ appId, expandable }) => expandable || !!appId).length === 0) { + if (isHidden || routes.filter(({ appId, expandable }) => expandable || !!appId).length === 0) { return null; } const quickStartHighlightId = title.replace(/\s/g, '-'); return ( - {filteredFedrampRoutes.map((item, index) => ( + {routes.map((item, index) => ( ))} diff --git a/src/components/Navigation/ChromeNavItem.tsx b/src/components/Navigation/ChromeNavItem.tsx index dcc5733408..c0f4181b31 100644 --- a/src/components/Navigation/ChromeNavItem.tsx +++ b/src/components/Navigation/ChromeNavItem.tsx @@ -13,7 +13,6 @@ import get from 'lodash/get'; import { isBeta } from '../../utils/common'; import ChromeLink, { LinkWrapperProps } from '../ChromeLink/ChromeLink'; import { useDispatch, useSelector } from 'react-redux'; -import useRenderFedramp from '../../utils/useRenderFedramp'; import { markActiveProduct } from '../../redux/actions'; import { ChromeNavItemProps } from '../../@types/types'; import useFavoritePagesWrapper from '../../hooks/useFavoritePagesWrapper'; @@ -32,7 +31,6 @@ const ChromeNavItem = ({ notifier = '', }: ChromeNavItemProps) => { const hasNotifier = useSelector((state) => get(state, notifier)); - const renderFedramp = useRenderFedramp(appId, href); const dispatch = useDispatch(); const { favoritePages } = useFavoritePagesWrapper(); const isFavorited = useMemo(() => favoritePages.find(({ favorite, pathname }) => favorite && pathname === href), [href, favoritePages]); @@ -42,9 +40,6 @@ const ChromeNavItem = ({ dispatch(markActiveProduct(product)); } }, [active]); - if (renderFedramp !== true) { - return null; - } if (isHidden) { return null; diff --git a/src/components/Routes/Routes.tsx b/src/components/Routes/Routes.tsx index 61a4754c26..8804ecea09 100644 --- a/src/components/Routes/Routes.tsx +++ b/src/components/Routes/Routes.tsx @@ -5,7 +5,6 @@ import ChromeRoute from '../ChromeRoute'; import NotFoundRoute from '../NotFoundRoute'; import LoadingFallback from '../../utils/loading-fallback'; import { ReduxState } from '../../redux/store'; -import { ITLess } from '../../utils/common'; const QuickstartCatalogRoute = lazy(() => import('../QuickstartsCatalogRoute')); @@ -44,11 +43,6 @@ const ChromeRoutes = ({ routesProps }: RoutesProps) => { const moduleRoutes = useSelector(({ chrome: { moduleRoutes } }: ReduxState) => moduleRoutes); const showBundleCatalog = localStorage.getItem('chrome:experimental:quickstarts') === 'true'; - let list = moduleRoutes; - if (ITLess()) { - list = list.filter((list) => list.isFedramp); - } - return ( {showBundleCatalog && ( @@ -64,7 +58,7 @@ const ChromeRoutes = ({ routesProps }: RoutesProps) => { {redirects.map(({ path, to }) => ( } /> ))} - {list.map((app) => ( + {moduleRoutes.map((app) => ( } /> ))} } /> diff --git a/src/components/Stratosphere/ProductSelection.tsx b/src/components/Stratosphere/ProductSelection.tsx index 540aa0e6e5..03607b5897 100644 --- a/src/components/Stratosphere/ProductSelection.tsx +++ b/src/components/Stratosphere/ProductSelection.tsx @@ -14,76 +14,84 @@ import ProductCard from './ProductCard'; import { Header } from '../Header/Header'; import ChromeLink from '../ChromeLink/ChromeLink'; import Footer from './Footer'; +import useMarketplacePartner from '../../hooks/useMarketplacePartner'; import './product-selection.scss'; -const ProductSelection = () => ( -
- -
- - } - > -
- - - - - - - - - - - - - - Congratulations, +const ProductSelection = () => { + const { partner, partnerId } = useMarketplacePartner(); + return ( + <div id="chrome-app-render-root"> + <Page + header={ + <Masthead className="chr-c-masthead"> + <Header /> + </Masthead> + } + > + <div className="chr-c-product-selection pf-u-pt-lg pf-u-pb-lg"> + <Stack hasGutter> + <StackItem> + <Bullseye> + <Icon size="xl"> + <CheckCircleIcon color="var(--pf-global--success-color--100)" /> + </Icon> + </Bullseye> + </StackItem> + <StackItem> + <Stack> + <StackItem> + <Bullseye> + <Title size="3xl" headingLevel="h1"> + Congratulations, + + + + + + your Red Hat and {partner} accounts are connected and you can now access Red Hat support resources - - - - - your Red Hat and AWS accounts are connected and you can now access Red Hat support resources - - - - - - - - To get started using your Red Hat products, follow the links below - - - - - -
- {productsList.map((item, i) => ( - - ))} -
-
-
- - - - - To manage or learn more about your Red Hat subscriptions, visit{' '} - - subscriptions. - - - - - -
-
-
- -
-); + + + + {partnerId !== 'from-azure' && ( + <> + + + + To get started using your Red Hat products, follow the links below + + + + + +
+ {productsList.map((item, i) => ( + + ))} +
+
+
+ + )} + + + + + To manage or learn more about your Red Hat subscriptions, visit{' '} + + subscriptions. + + + + + + + +