diff --git a/frontend/__tests__/components/operator-lifecycle-manager/install-plan.spec.tsx b/frontend/__tests__/components/operator-lifecycle-manager/install-plan.spec.tsx index ae8d5aea28a..57abb252785 100644 --- a/frontend/__tests__/components/operator-lifecycle-manager/install-plan.spec.tsx +++ b/frontend/__tests__/components/operator-lifecycle-manager/install-plan.spec.tsx @@ -3,11 +3,12 @@ import * as _ from 'lodash'; import { shallow, ShallowWrapper } from 'enzyme'; import { Link } from 'react-router-dom'; import Spy = jasmine.Spy; +import { Button } from '@patternfly/react-core'; import { InstallPlanTableHeader, InstallPlanTableRow, InstallPlanTableRowProps, InstallPlansList, InstallPlansListProps, InstallPlansPage, InstallPlansPageProps, InstallPlanDetailsPage, InstallPlanPreview, InstallPlanPreviewProps, InstallPlanPreviewState, InstallPlanDetailsPageProps, InstallPlanDetails, InstallPlanDetailsProps } from '../../../public/components/operator-lifecycle-manager/install-plan'; import { InstallPlanKind, InstallPlanApproval, referenceForStepResource } from '../../../public/components/operator-lifecycle-manager'; import { Table, TableRow, MultiListPage, DetailsPage } from '../../../public/components/factory'; -import { ResourceKebab, ResourceLink, ResourceIcon, Kebab, MsgBox } from '../../../public/components/utils'; +import { ResourceKebab, ResourceLink, ResourceIcon, Kebab, MsgBox, HintBlock } from '../../../public/components/utils'; import { testInstallPlan } from '../../../__mocks__/k8sResourcesMocks'; import { InstallPlanModel, ClusterServiceVersionModel, OperatorGroupModel, CustomResourceDefinitionModel } from '../../../public/models'; import * as k8s from '../../../public/module/k8s'; @@ -160,7 +161,7 @@ describe(InstallPlanPreview.name, () => { it('renders button to approve install plan if requires approval', () => { wrapper = wrapper.setState({needsApproval: true}); - expect(wrapper.find('.co-well').find('button').at(0).text()).toEqual('Approve'); + expect(wrapper.find(HintBlock).shallow().find(Button).at(0).render().text()).toEqual('Approve'); }); it('calls `k8sUpdate` to set `approved: true` when button is clicked', (done) => { @@ -171,13 +172,13 @@ describe(InstallPlanPreview.name, () => { }); wrapper = wrapper.setState({needsApproval: true}); - wrapper.find('.co-well').find('button').at(0).simulate('click'); + wrapper.find(HintBlock).shallow().find(Button).at(0).simulate('click'); }); it('renders button to deny install plan if requires approval', () => { wrapper = wrapper.setState({needsApproval: true}); - expect(wrapper.find('.co-well').find('button').at(1).text()).toEqual('Deny'); + expect(wrapper.find(HintBlock).shallow().find(Button).at(1).render().text()).toEqual('Deny'); }); it('renders section for each resolving `ClusterServiceVersion`', () => { @@ -218,11 +219,11 @@ describe(InstallPlanDetails.displayName, () => { installPlan.spec.approved = false; wrapper = wrapper.setProps({obj: installPlan}); - expect(wrapper.find('.co-well').find(Link).props().to).toEqual(`/k8s/ns/default/${k8s.referenceForModel(InstallPlanModel)}/${testInstallPlan.metadata.name}/components`); + expect(wrapper.find(HintBlock).shallow().find(Link).props().to).toEqual(`/k8s/ns/default/${k8s.referenceForModel(InstallPlanModel)}/${testInstallPlan.metadata.name}/components`); }); it('does not render link to "Components" tab if install plan does not need approval"', () => { - expect(wrapper.find('.co-well').exists()).toBe(false); + expect(wrapper.find(HintBlock).exists()).toBe(false); }); }); diff --git a/frontend/integration-tests/views/catalog.view.ts b/frontend/integration-tests/views/catalog.view.ts index aeed9948ce8..a69a4958c35 100644 --- a/frontend/integration-tests/views/catalog.view.ts +++ b/frontend/integration-tests/views/catalog.view.ts @@ -8,4 +8,4 @@ export const pageHeadingNumberOfItems = () => pageNumberItemsHeading.getText() export const catalogDetailsLoaded = () => browser.wait(until.presenceOf($('.modal-content')), 10000).then(() => browser.sleep(1000)); export const createServiceInstanceButton = $('.co-catalog-page__overlay-create'); export const createServiceInstanceForm = $('.co-create-service-instance'); -export const createServiceBindingButton = $('.co-well').element(by.buttonText('Create Service Binding')); +export const createServiceBindingButton = $('.co-hint-block').element(by.buttonText('Create Service Binding')); diff --git a/frontend/integration-tests/views/operator-hub.view.ts b/frontend/integration-tests/views/operator-hub.view.ts index 34dc0243187..34d598085ad 100644 --- a/frontend/integration-tests/views/operator-hub.view.ts +++ b/frontend/integration-tests/views/operator-hub.view.ts @@ -9,7 +9,7 @@ export const operatorModalUninstallBtn = operatorModal.element(by.buttonText('Un export const closeOperatorModal = () => operatorModal.$('.close').click(); export const operatorModalIsClosed = () => browser.wait(until.not(until.presenceOf(operatorModal)), 1000) .then(() => browser.sleep(500)); -export const viewInstalledOperator = () => $('.hint-block-pf').element(by.linkText('View it here.')).click(); +export const viewInstalledOperator = () => $('.co-hint-block').element(by.linkText('View it here.')).click(); export const createSubscriptionFormTitle = element(by.cssContainingText('h1', 'Create Operator Subscription')); export const createSubscriptionFormName = $('.co-clusterserviceversion-logo__name__clusterserviceversion'); diff --git a/frontend/packages/dev-console/src/components/AddPage.tsx b/frontend/packages/dev-console/src/components/AddPage.tsx index 85bb5575698..af27f811745 100644 --- a/frontend/packages/dev-console/src/components/AddPage.tsx +++ b/frontend/packages/dev-console/src/components/AddPage.tsx @@ -1,9 +1,8 @@ import * as React from 'react'; import * as _ from 'lodash'; import { Helmet } from 'react-helmet'; -import { HintBlock } from 'patternfly-react'; import { match as RMatch } from 'react-router'; -import { history, Firehose, FirehoseResource } from '@console/internal/components/utils'; +import { history, Firehose, FirehoseResource, HintBlock } from '@console/internal/components/utils'; import { createProjectModal } from '@console/internal/components/modals'; import { K8sResourceKind } from '@console/internal/module/k8s'; import ODCEmptyState from './EmptyState'; @@ -61,10 +60,12 @@ const EmptyStateLoader: React.FC = ({ resources, loaded, + +

+ To add content to your project, create an application, component or service using one of + these options. +

+
} /> ) : ( diff --git a/frontend/packages/dev-console/src/components/ProjectsExistWrapper.tsx b/frontend/packages/dev-console/src/components/ProjectsExistWrapper.tsx index 58dacd20f13..52a44f2cdaa 100644 --- a/frontend/packages/dev-console/src/components/ProjectsExistWrapper.tsx +++ b/frontend/packages/dev-console/src/components/ProjectsExistWrapper.tsx @@ -1,7 +1,6 @@ import * as React from 'react'; import * as _ from 'lodash'; -import { HintBlock } from 'patternfly-react'; -import { LoadingBox } from '@console/internal/components/utils'; +import { HintBlock, LoadingBox } from '@console/internal/components/utils'; import ODCEmptyState from './EmptyState'; export interface ProjectsExistWrapperProps { @@ -24,11 +23,12 @@ const ProjectsExistWrapper: React.FC = ({ + +

+ Select one of the following options to create an application, component or service. As + part of the creation process a project and application will be created. +

+
} /> ); diff --git a/frontend/packages/dev-console/src/components/topology/TopologyPage.tsx b/frontend/packages/dev-console/src/components/topology/TopologyPage.tsx index 11aab456a3f..d7166c7b35c 100644 --- a/frontend/packages/dev-console/src/components/topology/TopologyPage.tsx +++ b/frontend/packages/dev-console/src/components/topology/TopologyPage.tsx @@ -2,10 +2,9 @@ import * as React from 'react'; import { Helmet } from 'react-helmet'; import { connect } from 'react-redux'; import { match as RMatch } from 'react-router-dom'; -import { HintBlock } from 'patternfly-react'; import { getActiveApplication } from '@console/internal/reducers/ui'; import { ALL_APPLICATIONS_KEY } from '@console/internal/const'; -import { StatusBox, Firehose } from '@console/internal/components/utils'; +import { StatusBox, Firehose, HintBlock } from '@console/internal/components/utils'; import { RootState } from '@console/internal/redux'; import { FLAG_KNATIVE_SERVING_SERVICE } from '@console/knative-plugin/src/const'; import EmptyState from '../EmptyState'; @@ -34,10 +33,12 @@ const EmptyMsg = () => ( + +

+ To add content to your project, create an application, component or service using one of + these options. +

+
} /> ); diff --git a/frontend/public/components/catalog/_catalog.scss b/frontend/public/components/catalog/_catalog.scss index 36ffdd354d5..1ef17ce6385 100644 --- a/frontend/public/components/catalog/_catalog.scss +++ b/frontend/public/components/catalog/_catalog.scss @@ -142,7 +142,7 @@ $co-modal-ignore-warning-icon-width: 30px; // Enable scrolling on the modal &__overlay { - .modal-body .hint-block-pf { + .modal-body .co-hint-block { margin-bottom: 10px; } diff --git a/frontend/public/components/chargeback.tsx b/frontend/public/components/chargeback.tsx index ad2f65c516f..b033721efea 100644 --- a/frontend/public/components/chargeback.tsx +++ b/frontend/public/components/chargeback.tsx @@ -2,9 +2,8 @@ import * as React from 'react'; import * as _ from 'lodash-es'; import * as classNames from 'classnames'; import { sortable } from '@patternfly/react-table'; -import { ExternalLinkAltIcon } from '@patternfly/react-icons'; -import { connectToFlags, flagPending } from '../reducers/features'; +import { connectToFlags } from '../reducers/features'; import { FLAGS } from '../const'; import { Conditions } from './conditions'; import { DetailsPage, ListPage, Table, TableRow, TableData } from './factory'; @@ -12,7 +11,6 @@ import { coFetchJSON } from '../co-fetch'; import { ChargebackReportModel } from '../models'; import { LoadError, - LoadingBox, LoadingInline, MsgBox, } from './utils/status-box'; @@ -367,33 +365,9 @@ const EmptyMsg = () => ; const ReportsPage_: React.SFC = props => { - if (flagPending(props.flags[FLAGS.CHARGEBACK])) { - return ; - } - if (props.flags[FLAGS.CHARGEBACK]) { - return
- - -
; - } return
-
-

Getting Started

-

- Chargeback is not yet installed and enabled. - See our documention for instructions on how to install Chargeback Report on your Tectonic Cluster. -

-

- Chargeback is an alpha feature. -

- - - -
- -
- -
+ +
; }; diff --git a/frontend/public/components/operator-hub/operator-hub-item-details.tsx b/frontend/public/components/operator-hub/operator-hub-item-details.tsx index 85774d7f302..b53f4f298d6 100644 --- a/frontend/public/components/operator-hub/operator-hub-item-details.tsx +++ b/frontend/public/components/operator-hub/operator-hub-item-details.tsx @@ -1,11 +1,11 @@ import * as React from 'react'; -import { HintBlock, Modal } from 'patternfly-react'; +import { Modal } from 'patternfly-react'; import { Button } from '@patternfly/react-core'; import { CatalogItemHeader, PropertiesSidePanel, PropertyItem } from 'patternfly-react-extensions'; import { Link } from 'react-router-dom'; import { MarkdownView } from '../operator-lifecycle-manager/clusterserviceversion'; -import { history, ExternalLink } from '../utils'; +import { history, ExternalLink, HintBlock } from '../utils'; import { RH_OPERATOR_SUPPORT_POLICY_LINK } from '../../const'; import { OperatorHubItem } from './index'; import { SubscriptionModel } from '../../models'; @@ -36,37 +36,31 @@ export const OperatorHubItemDetails: React.SFC = ({ const getHintBlock = () => { if (installed) { return ( - - This Operator has been installed on the cluster.{' '} - - View it here. - - - } - /> + +

+ This Operator has been installed on the cluster.{' '} + + View it here. + +

+
); } if (providerType === 'Community') { return ( - - This is a community provided operator. These are operators which have not been vetted or verified by Red Hat. - Community Operators should be used with caution because their stability is unknown. - Red Hat provides no support for Community Operators. - {RH_OPERATOR_SUPPORT_POLICY_LINK && ( - - - - )} + +

+ This is a community provided operator. These are operators which have not been vetted or verified by Red Hat. + Community Operators should be used with caution because their stability is unknown. + Red Hat provides no support for Community Operators. +

+ {RH_OPERATOR_SUPPORT_POLICY_LINK && ( + + - } - /> + )} +
); } diff --git a/frontend/public/components/operator-lifecycle-manager/install-plan.tsx b/frontend/public/components/operator-lifecycle-manager/install-plan.tsx index 9c495e8b573..019490d3bfe 100644 --- a/frontend/public/components/operator-lifecycle-manager/install-plan.tsx +++ b/frontend/public/components/operator-lifecycle-manager/install-plan.tsx @@ -5,9 +5,10 @@ import { Map as ImmutableMap } from 'immutable'; import { sortable } from '@patternfly/react-table'; import * as classNames from 'classnames'; import { AddCircleOIcon } from '@patternfly/react-icons'; +import { Button } from '@patternfly/react-core'; import { MultiListPage, DetailsPage, Table, TableRow, TableData } from '../factory'; -import { SectionHeading, MsgBox, ResourceLink, ResourceKebab, Kebab, ResourceIcon, navFactory, ResourceSummary, history } from '../utils'; +import { SectionHeading, MsgBox, ResourceLink, ResourceKebab, Kebab, ResourceIcon, navFactory, ResourceSummary, history, HintBlock } from '../utils'; import { InstallPlanKind, InstallPlanApproval, olmNamespace, Step, referenceForStepResource } from './index'; import { K8sResourceKind, referenceForModel, referenceForOwnerRef, k8sUpdate, apiVersionForReference } from '../../module/k8s'; import { SubscriptionModel, ClusterServiceVersionModel, InstallPlanModel, CatalogSourceModel, OperatorGroupModel } from '../../models'; @@ -125,12 +126,13 @@ export const InstallPlanDetails: React.SFC = ({obj}) => const needsApproval = obj.spec.approval === InstallPlanApproval.Manual && obj.spec.approved === false; return - { needsApproval &&
-

Review Manual Install Plan

-

Inspect the requirements for the components specified in this install plan before approving.

- - - + { needsApproval &&
+ +

Inspect the requirements for the components specified in this install plan before approving.

+ + + +
}
@@ -187,21 +189,24 @@ export class InstallPlanPreview extends React.Component 0 ? { this.state.error &&
{this.state.error}
} - { this.state.needsApproval &&
-

Review Manual Install Plan

-

Once approved, the following resources will be created in order to satisfy the requirements for the components specified in the plan. Click the resource name to view the resource in detail.

- - + { this.state.needsApproval &&
+ +

Once approved, the following resources will be created in order to satisfy the requirements for the components specified in the plan. Click the resource name to view the resource in detail.

+
+ + +
+
} { stepsByCSV.map((steps, i) =>
diff --git a/frontend/public/components/service-instance.tsx b/frontend/public/components/service-instance.tsx index 58ff7774486..90107516b3f 100644 --- a/frontend/public/components/service-instance.tsx +++ b/frontend/public/components/service-instance.tsx @@ -3,7 +3,7 @@ import * as _ from 'lodash-es'; import { Link, withRouter, RouteComponentProps, match } from 'react-router-dom'; import { sortable } from '@patternfly/react-table'; import * as classNames from 'classnames'; -import { Alert } from '@patternfly/react-core'; +import { Alert, Button } from '@patternfly/react-core'; import { k8sList, K8sResourceKind, planExternalName, serviceCatalogStatus, referenceForModel } from '../module/k8s'; import { DetailsPage, ListPage, Table, TableRow, TableData } from './factory'; @@ -19,6 +19,7 @@ import { Timestamp, history, navFactory, + HintBlock, } from './utils'; import { ResourceEventStream } from './events'; import { Conditions } from './conditions'; @@ -102,10 +103,11 @@ class ServiceInstanceMessage_ extends React.Component -

Create Service Binding

- - + return
+ + + +
; } diff --git a/frontend/public/components/start-guide.tsx b/frontend/public/components/start-guide.tsx index 381e369dcd0..139cce42b70 100644 --- a/frontend/public/components/start-guide.tsx +++ b/frontend/public/components/start-guide.tsx @@ -2,55 +2,40 @@ import * as _ from 'lodash-es'; import * as React from 'react'; import { connect } from 'react-redux'; import { Link } from 'react-router-dom'; -import { Button } from 'patternfly-react'; -import { CloseIcon } from '@patternfly/react-icons'; +import { Button } from '@patternfly/react-core'; import { createProjectMessageStateToProps } from '../reducers/ui'; -import { Disabled } from './utils'; +import { Disabled, HintBlock } from './utils'; import { connectToFlags } from '../reducers/features'; import { FLAGS } from '../const'; import { ProjectModel, RoleModel, StorageClassModel } from '../models'; const WHITELIST = [RoleModel.kind, StorageClassModel.kind]; -export const StartGuide: React.FC = (props) => { - const {dismissKey, startGuide} = props; - let visible; - try { - visible = !dismissKey || !localStorage.getItem(dismissKey); - } catch (ignored) { - // ignored - } - const [isVisible, setIsVisible] = React.useState(visible); - - const dismiss = () => { - setIsVisible(false); - localStorage.setItem(dismissKey, 'true'); - }; - - return isVisible - ?
- {dismissKey && } +export const StartGuide: React.FC = ({startGuide}) => { + return ( +
{startGuide}
- : null; + ); }; export const OpenShiftGettingStarted = connect(createProjectMessageStateToProps)( ({createProjectMessage}) => - -

Getting Started

- { createProjectMessage + + {createProjectMessage ?

{createProjectMessage}

:

OpenShift helps you quickly develop, host, and scale applications. To get started, create a project for your application.

} - - - -
+

+ + + +

+ ); export const withStartGuide = (WrappedComponent, doNotDisable: boolean = false) => @@ -81,7 +66,6 @@ export const withStartGuide = (WrappedComponent, doNotDisable: boolean = false) ); type StartGuideProps = { - dismissKey?: string; startGuide: React.ReactNode; }; diff --git a/frontend/public/components/utils/_hint-block.scss b/frontend/public/components/utils/_hint-block.scss new file mode 100644 index 00000000000..f7bdc537fc2 --- /dev/null +++ b/frontend/public/components/utils/_hint-block.scss @@ -0,0 +1,5 @@ +.co-hint-block { + background-color: $pf-color-blue-50; + color: $pf-color-blue-600; + padding: 5px 15px 10px; +} diff --git a/frontend/public/components/utils/hint-block.tsx b/frontend/public/components/utils/hint-block.tsx new file mode 100644 index 00000000000..13282b92ffc --- /dev/null +++ b/frontend/public/components/utils/hint-block.tsx @@ -0,0 +1,19 @@ +import * as React from 'react'; +import classNames from 'classnames'; + +export const HintBlock: React.FC = ({ title, children, className }) => { + const classes = classNames('co-hint-block', className); + + return ( +
+

{title}

+
{children}
+
+ ); +}; + +export type HintBlockProps = { + title: string; + children: React.ReactNode; + className?: string; +}; diff --git a/frontend/public/components/utils/index.tsx b/frontend/public/components/utils/index.tsx index 9f46edd964b..c338943188e 100644 --- a/frontend/public/components/utils/index.tsx +++ b/frontend/public/components/utils/index.tsx @@ -56,6 +56,7 @@ export * from './expand-collapse'; export * from './volume-type'; export * from './skeleton-catalog'; export * from './dom-utils'; +export * from './hint-block'; /* Add the enum for NameValueEditorPair here and not in its namesake file because the editor should always be diff --git a/frontend/public/style.scss b/frontend/public/style.scss index 2ec1bc9148a..2cd234639ea 100644 --- a/frontend/public/style.scss +++ b/frontend/public/style.scss @@ -45,6 +45,7 @@ @import "components/utils/log-window"; @import "components/utils/resource-log"; @import "components/utils/list-input"; +@import "components/utils/hint-block"; @import "components/image-stream"; @import "components/about-modal"; @import "components/build-pipeline"; diff --git a/frontend/public/style/_common.scss b/frontend/public/style/_common.scss index 070e47a1930..04c17d9b8d1 100644 --- a/frontend/public/style/_common.scss +++ b/frontend/public/style/_common.scss @@ -198,29 +198,6 @@ $co-external-link-padding-right: 15px; white-space: pre-wrap; } -.co-well { - color: $color-pf-blue-600; - background-color: $color-pf-blue-50; - padding: 20px; - margin: ($grid-gutter-width / 2); - - @media (min-width: $screen-sm-min) { - margin: $grid-gutter-width; - } - - .co-well__close-button { - float: right; - } - - .co-well__close-button { - color: $color-pf-blue-600; - } - - .co-well__close-button:hover, .co-well__close-button:active { - color: $color-pf-blue-400; - } -} - // Prevent iOS phones from zooming on form inputs @supports (-webkit-overflow-scrolling: touch) { // Target mobile Safari @media (max-width: $grid-float-breakpoint-max) { // Target phones diff --git a/frontend/public/vendor.scss b/frontend/public/vendor.scss index 8f8c3a30031..abaa8ec7a11 100644 --- a/frontend/public/vendor.scss +++ b/frontend/public/vendor.scss @@ -35,7 +35,6 @@ @import '~patternfly/dist/sass/patternfly/buttons'; @import '~patternfly/dist/sass/patternfly/dropdowns'; // required by @patternfly/react-console @import '~patternfly/dist/sass/patternfly/breadcrumbs'; -@import '~patternfly/dist/sass/patternfly/hint-block'; @import '~patternfly/dist/sass/patternfly/modals'; @import '~patternfly/dist/sass/patternfly/toolbar'; @import '~patternfly/dist/sass/patternfly/list-view';