import _ from 'lodash'; import { apiErrorPropType } from './util/ApiHelpers.jsx'; import ErrorBanner from './ErrorBanner.jsx'; import MetricsTable from './MetricsTable.jsx'; import PageHeader from './PageHeader.jsx'; import PropTypes from 'prop-types'; import React from 'react'; import { singularResource } from './util/Utils.js'; import { Spin } from 'antd'; import withREST from './util/withREST.jsx'; import { metricsPropType, processSingleResourceRollup } from './util/MetricUtils.js'; import 'whatwg-fetch'; const getResourceFromUrl = (match, pathPrefix) => { let resource = { namespace: match.params.namespace }; let regExp = RegExp(`${pathPrefix || ""}/namespaces/${match.params.namespace}/([^/]+)/([^/]+)`); let urlParts = match.url.match(regExp); resource.type = singularResource(urlParts[1]); resource.name = urlParts[2]; if (match.params[resource.type] !== resource.name) { console.error("Failed to extract resource from URL"); } return resource; }; export class ResourceDetailBase extends React.Component { static defaultProps = { error: null } static propTypes = { api: PropTypes.shape({ PrefixedLink: PropTypes.func.isRequired, }).isRequired, data: PropTypes.arrayOf(metricsPropType.isRequired).isRequired, error: apiErrorPropType, loading: PropTypes.bool.isRequired, match: PropTypes.shape({}).isRequired, pathPrefix: PropTypes.string.isRequired } constructor(props) { super(props); this.state = this.getInitialState(props.match, props.pathPrefix); } getInitialState(match, pathPrefix) { let resource = getResourceFromUrl(match, pathPrefix); return { namespace: resource.namespace, resourceName: resource.name, resourceType: resource.type }; } banner = () => { const {error} = this.props; if (!error) { return; } return ; } content = () => { const {data, loading, error} = this.props; if (loading && !error) { return ; } let processedMetrics = []; if (_.has(data, '[0].ok')) { processedMetrics = processSingleResourceRollup(data[0]); } return ( ); } render() { const {loading, api} = this.props; let resourceBreadcrumb = ( {this.state.namespace} > {`${this.state.resourceType}/${this.state.resourceName}`} ); return (
{this.banner()} {loading ? null : } {resourceBreadcrumb} {this.content()}
); } } export default withREST( ResourceDetailBase, ({api, match, pathPrefix}) => { let resource = getResourceFromUrl(match, pathPrefix); return [api.fetchMetrics(api.urlsForResource(resource.type, resource.namespace) + "&resource_name=" + resource.name)]; }, { resetProps: ['resource'], }, );