import Button from '@material-ui/core/Button'; import Card from '@material-ui/core/Card'; import CardContent from '@material-ui/core/CardContent'; import ConfigureProfilesMsg from './ConfigureProfilesMsg.jsx'; import Divider from '@material-ui/core/Divider'; import ErrorBanner from './ErrorBanner.jsx'; import FormControl from '@material-ui/core/FormControl'; import FormHelperText from '@material-ui/core/FormHelperText'; import Grid from '@material-ui/core/Grid'; import InputLabel from '@material-ui/core/InputLabel'; import MenuItem from '@material-ui/core/MenuItem'; import PropTypes from 'prop-types'; import QueryToCliCmd from './QueryToCliCmd.jsx'; import React from 'react'; import Select from '@material-ui/core/Select'; import TopRoutesModule from './TopRoutesModule.jsx'; import Typography from '@material-ui/core/Typography'; import _ from 'lodash'; import { groupResourcesByNs } from './util/MetricUtils.jsx'; import { withContext } from './util/AppContext.jsx'; import { withStyles } from '@material-ui/core/styles'; const styles = theme => ({ root: { marginTop: 3 * theme.spacing.unit, marginBottom:theme.spacing.unit, }, formControl: { minWidth: 200, }, }); class TopRoutes extends React.Component { static propTypes = { api: PropTypes.shape({ PrefixedLink: PropTypes.func.isRequired, }).isRequired, classes: PropTypes.shape({}).isRequired } constructor(props) { super(props); this.api = this.props.api; this.state = { query: { resource_name: '', namespace: '', from_name: '', from_type: '', from_namespace: '' }, error: null, services: [], namespaces: [], resourcesByNs: {}, pollingInterval: 5000, pendingRequests: false, requestInProgress: false }; } componentDidMount() { this.startServerPolling(); } componentWillUnmount() { this.stopServerPolling(); } loadFromServer = () => { if (this.state.pendingRequests) { return; // don't make more requests if the ones we sent haven't completed } this.setState({ pendingRequests: true }); let allMetricsUrl = this.api.urlsForResource("all"); this.api.setCurrentRequests([ this.api.fetchServices(), this.api.fetchMetrics(allMetricsUrl) ]); this.serverPromise = Promise.all(this.api.getCurrentPromises()) .then(([svcList, allMetrics]) => { let services = _.get(svcList, 'services', []); let namespaces = _.uniq(_.map(services, 'namespace')); let { resourcesByNs } = groupResourcesByNs(allMetrics); this.setState({ services, namespaces, resourcesByNs, pendingRequests: false, error: null }); }) .catch(this.handleApiError); } handleApiError = e => { if (e.isCanceled) { return; } this.setState({ pendingRequests: false, error: e }); } startServerPolling = () => { this.loadFromServer(); this.timerId = window.setInterval(this.loadFromServer, this.state.pollingInterval); } stopServerPolling = () => { window.clearInterval(this.timerId); this.api.cancelCurrentRequests(); } handleBtnClick = inProgress => () => { this.setState({ requestInProgress: inProgress }); } handleNamespaceSelect = e => { let query = this.state.query; query.namespace = _.get(e, 'target.value'); this.setState({ query }); }; handleResourceSelect = e => { let query = this.state.query; let resource = _.get(e, 'target.value'); let [resource_type, resource_name] = resource.split("/"); query.resource_name = resource_name; query.resource_type = resource_type; this.setState({ query }); } renderRoutesQueryForm = () => { const { classes } = this.props; return ( { this.renderNamespaceDropdown("Namespace", "namespace", "Namespace to query") } { this.renderServiceDropdown() } You can also create a new profile ); } renderNamespaceDropdown = (title, key, helperText) => { const { classes } = this.props; return ( {title} {helperText} ); } renderServiceDropdown = () => { const { classes } = this.props; let { query, services, resourcesByNs } = this.state; let key = "resource_name"; let servicesWithPrefix = _.chain(services) .filter(['namespace', query.namespace]) .map(svc => `service/${svc.name}`).value(); let otherResources = resourcesByNs[query.namespace] || []; let dropdownOptions = _.sortBy(_.concat(servicesWithPrefix, otherResources)); let dropdownVal = _.isEmpty(query.resource_name) || _.isEmpty(query.resource_type) ? "" : query.resource_type + "/" + query.resource_name; return ( Resource Resource to query ); } render() { let query = this.state.query; let emptyQuery = _.isEmpty(query.resource_name) || _.isEmpty(query.resource_type); return (
{ !this.state.error ? null : this.setState({ error: null })} /> } { this.renderRoutesQueryForm() } { emptyQuery ? null : } { !this.state.requestInProgress ? null : }
); } } export default withContext(withStyles(styles, { withTheme: true })(TopRoutes));