Welcome to the Red Hat Demo Platform!
-Please wait a few seconds while we set up your catalog. If nothing happens refresh this page.
+Welcome to the Red Hat Demo Platform (RHDP)!
+At this time, it appears that your account is not listed as a pilot user for the beta version of RHDP. Please reach out to your account manager or Red Hat contact to request pilot access.
+Once approved, you will be able to log-in with your Red Hat credentials. We look forward to your engagement with our updated demo platform!
> - ) : groups.includes('salesforce-partner') ? ( + ) : groups.includes('salesforce-partner') && userInterface !== 'rhdp-partners' ? ( <>Sorry! Red Hat Demo Platform is not yet available for partners.
diff --git a/catalog/ui/src/app/Catalog/CatalogItemDetails.tsx b/catalog/ui/src/app/Catalog/CatalogItemDetails.tsx
index 08ce62c61..0c5d5ce31 100644
--- a/catalog/ui/src/app/Catalog/CatalogItemDetails.tsx
+++ b/catalog/ui/src/app/Catalog/CatalogItemDetails.tsx
@@ -38,7 +38,6 @@ import {
BABYLON_DOMAIN,
FETCH_BATCH_LIMIT,
isLabDeveloper,
- getHelpUrl,
isResourceClaimPartOfWorkshop,
compareK8sObjectsArr,
CATALOG_MANAGER_DOMAIN,
@@ -66,6 +65,7 @@ import CatalogItemHealthDisplay from './CatalogItemHealthDisplay';
import './catalog-item-details.css';
import { ExternalLinkAltIcon } from '@patternfly/react-icons';
+import useHelpLink from '@app/utils/useHelpLink';
enum CatalogItemAccess {
Allow,
@@ -84,6 +84,7 @@ const CatalogItemDetails: React.FC<{ catalogItem: CatalogItem; onClose: () => vo
const { description, descriptionFormat } = getDescription(catalogItem);
const lastSuccessfulProvisionTime = getLastSuccessfulProvisionTime(catalogItem);
const displayProvisionTime = provisionTimeEstimate && formatTime(provisionTimeEstimate);
+ const helpLink = useHelpLink();
const { data: userResourceClaims } = useSWR
You have reached your quota of 5 services. You will not be able to request any new applications until you retire
existing services. If you feel this is an error, please{' '}
-
+
contact us
.
@@ -188,13 +189,8 @@ const CatalogItemDetails: React.FC<{ catalogItem: CatalogItem; onClose: () => vo
}
}
- function getHelpLink() {
- const userEmail = userImpersonated ? userImpersonated : email;
- return getHelpUrl(userEmail);
- }
-
function requestInformation() {
- window.open(getHelpLink(), '_blank');
+ window.open(helpLink, '_blank');
}
return (
diff --git a/catalog/ui/src/app/Catalog/CatalogItemForm.spec.tsx b/catalog/ui/src/app/Catalog/CatalogItemForm.spec.tsx
index df99f0a1c..177ebf98c 100644
--- a/catalog/ui/src/app/Catalog/CatalogItemForm.spec.tsx
+++ b/catalog/ui/src/app/Catalog/CatalogItemForm.spec.tsx
@@ -5,6 +5,7 @@ import catalogItemObj from '../__mocks__/catalogItem.json';
import userEvent from '@testing-library/user-event';
import { CatalogItem, ServiceNamespace, UserNamespace } from '@app/types';
import useSession from '@app/utils/useSession';
+import useHelpLink from '@app/utils/useHelpLink';
jest.mock('@app/api', () => ({
...jest.requireActual('@app/api'),
@@ -33,6 +34,9 @@ jest.mock('@app/utils/useSession', () =>
}),
}))
);
+jest.mock('@app/utils/useHelpLink', () => {
+ return jest.fn(() => 'https://red.ht/open-support');
+});
describe('CatalogItemForm Component', () => {
test("When renders should display 'CatalogItem' properties and parameters", async () => {
diff --git a/catalog/ui/src/app/Catalog/CatalogItemForm.tsx b/catalog/ui/src/app/Catalog/CatalogItemForm.tsx
index df1ea3f15..c61db968d 100644
--- a/catalog/ui/src/app/Catalog/CatalogItemForm.tsx
+++ b/catalog/ui/src/app/Catalog/CatalogItemForm.tsx
@@ -38,14 +38,14 @@ import {
createWorkshopProvision,
fetcher,
} from '@app/api';
-import { CatalogItem } from '@app/types';
+import { CatalogItem, TPurposeOpts } from '@app/types';
import { displayName, isLabDeveloper, randomString } from '@app/util';
import Editor from '@app/components/Editor/Editor';
import useSession from '@app/utils/useSession';
import useDebounce from '@app/utils/useDebounce';
import PatientNumberInput from '@app/components/PatientNumberInput';
import DynamicFormInput from '@app/components/DynamicFormInput';
-import ActivityPurposeSelector, { ActivityOpts, PurposeOpts } from '@app/components/ActivityPurposeSelector';
+import ActivityPurposeSelector from '@app/components/ActivityPurposeSelector';
import ProjectSelector from '@app/components/ProjectSelector';
import TermsOfService from '@app/components/TermsOfService';
import { reduceFormState, checkEnableSubmit, checkConditionsInFormState } from './CatalogItemFormReducer';
@@ -67,7 +67,7 @@ const CatalogItemFormData: React.FC<{ catalogItemName: string; catalogNamespaceN
const { isAdmin, groups, roles, serviceNamespaces, userNamespace } = useSession().getSession();
const { data: catalogItem } = useSWRImmutable
Auto-Destroy can be extended by submitting a{' '}
-
+
support request
.
diff --git a/catalog/ui/src/app/Catalog/CatalogItemFormReducer.ts b/catalog/ui/src/app/Catalog/CatalogItemFormReducer.ts
index f71004a1c..385150380 100644
--- a/catalog/ui/src/app/Catalog/CatalogItemFormReducer.ts
+++ b/catalog/ui/src/app/Catalog/CatalogItemFormReducer.ts
@@ -1,9 +1,8 @@
import React from 'react';
import { checkSalesforceId } from '@app/api';
-import { CatalogItem, CatalogItemSpecParameter, ServiceNamespace } from '@app/types';
+import { CatalogItem, CatalogItemSpecParameter, ServiceNamespace, TPurposeOpts } from '@app/types';
import parseDuration from 'parse-duration';
import { isAutoStopDisabled } from './catalog-utils';
-import { ActivityOpts, PurposeOpts } from '@app/components/ActivityPurposeSelector';
type ConditionValues = {
[name: string]: boolean | number | string | string[] | undefined;
@@ -40,6 +39,7 @@ type FormState = {
endDate: Date;
activity: string;
purpose: string;
+ purposeOpts: TPurposeOpts;
explanation?: string;
salesforceId: {
required: boolean;
@@ -70,6 +70,7 @@ export type FormStateAction = {
user?: UserProps;
parameter?: ParameterProps;
purpose?: string;
+ purposeOpts?: TPurposeOpts;
activity?: string;
explanation?: string;
serviceNamespace?: ServiceNamespace;
@@ -240,7 +241,8 @@ export async function checkConditionsInFormState(
function reduceFormStateInit(
catalogItem: CatalogItem,
serviceNamespace: ServiceNamespace,
- { isAdmin, groups, roles }
+ { isAdmin, groups, roles },
+ purposeOpts: TPurposeOpts
): FormState {
const formGroups: FormStateParameterGroup[] = [];
const parameters: { [name: string]: FormStateParameter } = {};
@@ -303,6 +305,7 @@ function reduceFormStateInit(
usePoolIfAvailable: true,
activity: null,
purpose: null,
+ purposeOpts,
explanation: null,
salesforceId: {
required: false,
@@ -437,8 +440,7 @@ function reduceFormStatePurpose(
function salesforceIdRequired(state: FormState): boolean {
if (state.purpose) {
- const a = ActivityOpts.find((a) => a.name === state.activity);
- const p = PurposeOpts.find((p) => a.id === p.activityId && state.purpose.startsWith(p.name));
+ const p = state.purposeOpts.find((p) => state.activity === p.activity && state.purpose.startsWith(p.name));
if (p.sfdcRequired) return true;
}
if (state.user.isAdmin) return false;
@@ -462,7 +464,7 @@ function reduceFormStateSalesforceId(
export function reduceFormState(state: FormState, action: FormStateAction): FormState {
switch (action.type) {
case 'init':
- return reduceFormStateInit(action.catalogItem, action.serviceNamespace, action.user);
+ return reduceFormStateInit(action.catalogItem, action.serviceNamespace, action.user, action.purposeOpts);
case 'parameterUpdate':
return reduceFormStateParameterUpdate(state, {
name: action.parameter.name,
@@ -502,13 +504,15 @@ export function checkEnableSubmit(state: FormState): boolean {
return false;
}
- if (!state.purpose || !state.activity) {
- return false;
+ if (state.purposeOpts.length > 0) {
+ if (!state.purpose || !state.activity) {
+ return false;
+ }
+ if (state.salesforceId.required && !state.salesforceId.valid) {
+ return false;
+ }
}
- if (state.salesforceId.required && !state.salesforceId.valid) {
- return false;
- }
for (const parameter of Object.values(state.parameters)) {
if (!parameter.isDisabled && !parameter.isHidden) {
if (parameter.value === undefined || parameter.value === null) {
diff --git a/catalog/ui/src/app/Catalog/catalog-utils.ts b/catalog/ui/src/app/Catalog/catalog-utils.ts
index bbdc7bba2..39d8b7b10 100644
--- a/catalog/ui/src/app/Catalog/catalog-utils.ts
+++ b/catalog/ui/src/app/Catalog/catalog-utils.ts
@@ -159,6 +159,7 @@ export function setLastFilter(filter: string): void {
sessionStorage.setItem('lastCatalogFilter', filter);
}
export function formatString(string: string): string {
+ if (!string) return '';
return (string.charAt(0).toUpperCase() + string.slice(1)).replace(/_/g, ' ');
}
export function sortLabels([a_attr]: string[], [b_attr]: string[]) {
diff --git a/catalog/ui/src/app/Header/Header.tsx b/catalog/ui/src/app/Header/Header.tsx
index 88cc9a2ca..ab4eb6aab 100644
--- a/catalog/ui/src/app/Header/Header.tsx
+++ b/catalog/ui/src/app/Header/Header.tsx
@@ -19,7 +19,8 @@ import ImpersonateUserModal from '@app/components/ImpersonateUserModal';
import summitLogo from '@app/bgimages/Summit-Logo.svg';
import useImpersonateUser from '@app/utils/useImpersonateUser';
import useSession from '@app/utils/useSession';
-import { getHelpUrl } from '@app/util';
+import useHelpLink from '@app/utils/useHelpLink';
+import useInterfaceConfig from '@app/utils/useInterfaceConfig';
import './header.css';
@@ -35,6 +36,8 @@ const Header: React.FC<{
const [impersonateUserModalIsOpen, setImpersonateUserModalIsOpen] = useState(false);
const { isAdmin, email, userInterface } = useSession().getSession();
const navigate = useNavigate();
+ const helpLink = useHelpLink();
+ const { help_text, status_page_url, feedback_link } = useInterfaceConfig();
function clearUserImpersonation() {
clearImpersonation();
@@ -57,47 +60,53 @@ const Header: React.FC<{
}
const openSupportCase = (e: { preventDefault: () => void }) => {
e.preventDefault();
- const userEmail = userImpersonated ? userImpersonated : email;
- const url = getHelpUrl(userEmail);
- window.open(url, '_blank');
+ window.open(helpLink, '_blank');
return null;
};
const UserHelpDropdownItems = [