diff --git a/src/actions/catalog.ts b/src/actions/catalog.ts index a050ca07650..89511de8ff6 100644 --- a/src/actions/catalog.ts +++ b/src/actions/catalog.ts @@ -135,3 +135,11 @@ export function getCatalog() { dispatch(getPlans()); }; } + +export function checkCatalogInstalled() { + return async (dispatch: Dispatch) => { + const isInstalled = await ServiceCatalog.isCatalogInstalled(); + isInstalled ? dispatch(installed()) : dispatch(notInstalled()); + return isInstalled; + }; +} diff --git a/src/components/Config/ServiceBrokerList/index.tsx b/src/components/Config/ServiceBrokerList/index.tsx index f489e9df271..569d70733fa 100644 --- a/src/components/Config/ServiceBrokerList/index.tsx +++ b/src/components/Config/ServiceBrokerList/index.tsx @@ -14,22 +14,29 @@ export const ServiceBrokerList = (props: IServiceBrokerListProps) => { return (

Brokers

- - {brokers.map(broker => { - const card = ( -
- } - /> -
- ); - return card; - })} -
+ {brokers.length > 0 ? ( + + {brokers.map(broker => { + const card = ( +
+ } + /> +
+ ); + return card; + })} +
+ ) : ( +
+ No service brokers are installed in your cluster. Please ask an administrator to install + it. +
+ )}
); }; diff --git a/src/components/Config/ServiceCatalog/index.tsx b/src/components/Config/ServiceCatalog/index.tsx index 08da6988d07..7bdab3577c8 100644 --- a/src/components/Config/ServiceCatalog/index.tsx +++ b/src/components/Config/ServiceCatalog/index.tsx @@ -5,7 +5,7 @@ import { IServiceCatalogState } from "../../../reducers/catalog"; import { ServiceBrokerList } from "../ServiceBrokerList"; export interface IServiceCatalogDispatch { - checkCatalogInstalled: () => Promise; + checkCatalogInstalled: () => Promise; getCatalog: () => Promise; sync: () => Promise; } diff --git a/src/components/InstanceListView/InstanceCardList.tsx b/src/components/InstanceListView/InstanceCardList.tsx new file mode 100644 index 00000000000..557018ceeb2 --- /dev/null +++ b/src/components/InstanceListView/InstanceCardList.tsx @@ -0,0 +1,55 @@ +import * as React from "react"; + +import { IClusterServiceClass } from "../../shared/ClusterServiceClass"; +import { IServiceInstance } from "../../shared/ServiceInstance"; +import { Card, CardContainer } from "../Card"; + +export interface InstanceCardListProps { + classes: IClusterServiceClass[]; + instances: IServiceInstance[]; +} + +export const InstanceCardList = (props: InstanceCardListProps) => { + const { instances, classes } = props; + return ( +
+
+ + {instances.length > 0 && + instances.map(instance => { + const conditions = [...instance.status.conditions]; + const status = conditions.shift(); // first in list is most recent + const message = status ? status.message : ""; + const svcClass = classes.find( + potential => potential.metadata.name === instance.spec.clusterServiceClassRef.name, + ); + const broker = svcClass && svcClass.spec.clusterServiceBrokerName; + const icon = + svcClass && + svcClass.spec.externalMetadata && + svcClass.spec.externalMetadata.imageUrl; + + const card = ( + + {instance.metadata.namespace}/{instance.metadata.name} + + } + icon={icon} + body={message} + buttonText="Details" + linkTo={`/services/brokers/${broker}/instances/${instance.metadata.namespace}/${ + instance.metadata.name + }/`} + notes={{instance.spec.clusterServicePlanExternalName}} + /> + ); + return card; + })} + +
+
+ ); +}; diff --git a/src/components/InstanceListView/index.tsx b/src/components/InstanceListView/index.tsx index f8f69c51a13..e9e07328851 100644 --- a/src/components/InstanceListView/index.tsx +++ b/src/components/InstanceListView/index.tsx @@ -4,79 +4,64 @@ import { Link } from "react-router-dom"; import { IClusterServiceClass } from "../../shared/ClusterServiceClass"; import { IServiceBroker, IServicePlan } from "../../shared/ServiceCatalog"; import { IServiceInstance } from "../../shared/ServiceInstance"; -import { Card, CardContainer } from "../Card"; +import { InstanceCardList } from "./InstanceCardList"; export interface InstanceListViewProps { brokers: IServiceBroker[]; classes: IClusterServiceClass[]; getCatalog: () => Promise; + checkCatalogInstalled: () => Promise; instances: IServiceInstance[]; plans: IServicePlan[]; + isInstalled: boolean; } export class InstanceListView extends React.PureComponent { public async componentDidMount() { + this.props.checkCatalogInstalled(); this.props.getCatalog(); } public render() { - const { brokers, instances, classes } = this.props; + const { isInstalled, brokers, instances, classes } = this.props; return (
- {brokers && ( +

Service Instances

+ + {isInstalled ? (
-
-
-

Service Instances

-

Service instances from your brokers:

+ {brokers.length > 0 ? ( +
+
+
+

Service instances from your brokers:

+
+
+ + + +
+
+ {instances.length > 0 ? ( + + ) : ( +
No service instances are found.
+ )}
-
- - - + ) : ( +
+ No service brokers are installed in your cluster. Please ask an administrator to + install it.
-
- - - - {instances.length > 0 && - instances.map(instance => { - const conditions = [...instance.status.conditions]; - const status = conditions.shift(); // first in list is most recent - const message = status ? status.message : ""; - const svcClass = classes.find( - potential => - potential.metadata.name === instance.spec.clusterServiceClassRef.name, - ); - const broker = svcClass && svcClass.spec.clusterServiceBrokerName; - const icon = - svcClass && - svcClass.spec.externalMetadata && - svcClass.spec.externalMetadata.imageUrl; - - const card = ( - - {instance.metadata.namespace}/{instance.metadata.name} - - } - icon={icon} - body={message} - buttonText="Details" - linkTo={`/services/brokers/${broker}/instances/${ - instance.metadata.namespace - }/${instance.metadata.name}/`} - notes={{instance.spec.clusterServicePlanExternalName}} - /> - ); - return card; - })} - - -
+ )} +
+ ) : ( +
+
No Service Catalog is installed.
+ + Install Catalog +
)}
diff --git a/src/components/ProvisionButton/index.tsx b/src/components/ProvisionButton/index.tsx index cf30cd4f751..54bcd700456 100644 --- a/src/components/ProvisionButton/index.tsx +++ b/src/components/ProvisionButton/index.tsx @@ -186,7 +186,7 @@ class ProvisionButton extends React.Component) { return { + checkCatalogInstalled: async () => { + dispatch(actions.catalog.checkCatalogInstalled()); + }, getCatalog: async () => { dispatch(actions.catalog.getCatalog()); }, diff --git a/src/containers/ServiceCatalogContainer.ts b/src/containers/ServiceCatalogContainer.ts index d0e872f2e57..1c3fcae7e3a 100644 --- a/src/containers/ServiceCatalogContainer.ts +++ b/src/containers/ServiceCatalogContainer.ts @@ -3,7 +3,7 @@ import { Dispatch } from "redux"; import actions from "../actions"; import { ServiceCatalogView } from "../components/Config/ServiceCatalog"; -import { IServiceBroker, ServiceCatalog } from "../shared/ServiceCatalog"; +import { IServiceBroker } from "../shared/ServiceCatalog"; import { IStoreState } from "../shared/types"; function mapStateToProps({ catalog }: IStoreState) { @@ -15,11 +15,7 @@ function mapStateToProps({ catalog }: IStoreState) { function mapDispatchToProps(dispatch: Dispatch) { return { checkCatalogInstalled: async () => { - const isInstalled = await ServiceCatalog.isCatalogInstalled(); - isInstalled - ? dispatch(actions.catalog.installed()) - : dispatch(actions.catalog.notInstalled()); - return isInstalled; + dispatch(actions.catalog.checkCatalogInstalled()); }, getCatalog: () => dispatch(actions.catalog.getCatalog()), sync: (broker: IServiceBroker) => dispatch(actions.catalog.sync(broker)),