basic/cluster/ClusterServicesList.js
import React from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import DataTable from '../dataTable/DataTable';
import IdPopup from '../IdPopup';
import ClusterService from './ClusterService';
import NodeStatus from './NodeStatus';
import { nodeServicesPropType } from './NodeServices';
import { clusterNodeStatuses, clusterServiceEnum, clusterServiceStatuses, clusterServiceBgColor } from './consts';
const PublicIP = ({ ip, serviceName }) =>
ip && serviceName === clusterServiceEnum.manager ? (
<a href={`http://${ip}`} target="_blank" rel="noopener noreferrer">
{ip}
</a>
) : (
ip
);
PublicIP.propTypes = {
ip: PropTypes.string,
serviceName: PropTypes.string.isRequired
};
PublicIP.defaultProps = {
ip: ''
};
function ClusterServicesList({ services, toolbox }) {
const noServicesMessage = 'There are no Cluster Services available.';
return (
<DataTable
fetchData={toolbox.refresh}
noDataMessage={noServicesMessage}
noDataAvailable={_.isEmpty(services)}
selectable
>
<DataTable.Column label="Service Type" width="20%" />
<DataTable.Column label="Node Name" width="25%" />
<DataTable.Column label="Status" width="5%" />
<DataTable.Column label="Private IP" width="15%" />
<DataTable.Column label="Public IP / LB IP" width="15%" />
<DataTable.Column label="Version" width="15%" />
<DataTable.Column label="" width="1%" />
{_.map(services, (service, serviceName) => {
const numberOfNodes = _.size(service.nodes);
return _(service.nodes)
.map((node, nodeName) => ({ name: nodeName, ...node }))
.sortBy('name')
.map((node, index) => (
<DataTable.Row key={`${serviceName}_${node.name}_${node.node_id}`}>
{index === 0 && (
<DataTable.Data
rowsSpan={numberOfNodes}
style={{ backgroundColor: clusterServiceBgColor(service.status) }}
>
<ClusterService isExternal={service.is_external} name={serviceName} />
</DataTable.Data>
)}
<DataTable.Data>{node.name}</DataTable.Data>
<DataTable.Data>
<NodeStatus
name={node.name}
type={serviceName}
status={node.status}
services={node.services}
/>
</DataTable.Data>
<DataTable.Data>{node.private_ip}</DataTable.Data>
<DataTable.Data>
<PublicIP ip={node.public_ip} serviceName={serviceName} />
</DataTable.Data>
<DataTable.Data>{node.version}</DataTable.Data>
<DataTable.Data>
<IdPopup selected id={node.node_id} buttonPosition="right" />
</DataTable.Data>
</DataTable.Row>
))
.value();
})}
</DataTable>
);
}
const clusterServiceProps = PropTypes.shape({
status: PropTypes.oneOf(clusterServiceStatuses).isRequired,
nodes: PropTypes.objectOf(
PropTypes.shape({
status: PropTypes.oneOf(clusterNodeStatuses).isRequired,
public_ip: PropTypes.string,
version: PropTypes.string.isRequired,
node_id: PropTypes.string.isRequired,
private_ip: PropTypes.string.isRequired,
services: nodeServicesPropType
})
).isRequired,
is_external: PropTypes.bool.isRequired
}).isRequired;
ClusterServicesList.propTypes = {
services: PropTypes.shape(_.mapValues(clusterServiceEnum, () => clusterServiceProps)).isRequired,
toolbox: PropTypes.shape({ refresh: PropTypes.func.isRequired }).isRequired
};
const mapStateToProps = state => ({
services: _.get(state, 'manager.clusterStatus.services', {})
});
export default connect(mapStateToProps)(ClusterServicesList);