Make LayoutRenderer host agnostic and shared
parent
01ae8b1b82
commit
f5c58f70cd
|
@ -81,10 +81,3 @@ export function getAppsForHosts(proxyLink, hosts, appMappings) {
|
|||
return newHosts;
|
||||
});
|
||||
}
|
||||
|
||||
export function fetchLayouts() {
|
||||
return AJAX({
|
||||
url: `/chronograf/v1/layouts`,
|
||||
method: 'GET',
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,101 +0,0 @@
|
|||
import React, {PropTypes} from 'react';
|
||||
import AutoRefresh from 'shared/components/AutoRefresh';
|
||||
import LineGraph from 'shared/components/LineGraph';
|
||||
import ReactGridLayout from 'react-grid-layout';
|
||||
import _ from 'lodash';
|
||||
|
||||
const RefreshingLineGraph = AutoRefresh(LineGraph);
|
||||
|
||||
export const LayoutRenderer = React.createClass({
|
||||
propTypes: {
|
||||
timeRange: PropTypes.shape({
|
||||
defaultGroupBy: PropTypes.string.isRequired,
|
||||
queryValue: PropTypes.string.isRequired,
|
||||
}).isRequired,
|
||||
cells: PropTypes.arrayOf(
|
||||
PropTypes.shape({
|
||||
queries: PropTypes.arrayOf(
|
||||
PropTypes.shape({
|
||||
rp: PropTypes.string.isRequired,
|
||||
text: PropTypes.string.isRequired,
|
||||
database: PropTypes.string.isRequired,
|
||||
groupbys: PropTypes.arrayOf(PropTypes.string),
|
||||
wheres: PropTypes.arrayOf(PropTypes.string),
|
||||
}).isRequired
|
||||
).isRequired,
|
||||
x: PropTypes.number.isRequired,
|
||||
y: PropTypes.number.isRequired,
|
||||
w: PropTypes.number.isRequired,
|
||||
h: PropTypes.number.isRequired,
|
||||
i: PropTypes.string.isRequired,
|
||||
name: PropTypes.string.isRequired,
|
||||
}).isRequired
|
||||
),
|
||||
autoRefreshMs: PropTypes.number.isRequired,
|
||||
host: PropTypes.string.isRequired,
|
||||
source: PropTypes.string,
|
||||
},
|
||||
|
||||
getInitialState() {
|
||||
return ({
|
||||
layout: _.without(this.props.cells, ['queries']),
|
||||
});
|
||||
},
|
||||
|
||||
buildQuery(q) {
|
||||
const {timeRange, host} = this.props;
|
||||
const {wheres, groupbys} = q;
|
||||
|
||||
let text = q.text;
|
||||
text += ` where \"host\" = '${host}' and time > ${timeRange.queryValue}`;
|
||||
if (wheres && wheres.length > 0) {
|
||||
text += ` and ${wheres.join(' and ')}`;
|
||||
}
|
||||
if (groupbys) {
|
||||
if (groupbys.find((g) => g.includes("time"))) {
|
||||
text += ` group by ${groupbys.join(',')}`;
|
||||
} else if (groupbys.length > 0) {
|
||||
text += ` group by time(${timeRange.defaultGroupBy}),${groupbys.join(',')}`;
|
||||
} else {
|
||||
text += ` group by time(${timeRange.defaultGroupBy})`;
|
||||
}
|
||||
} else {
|
||||
text += ` group by time(${timeRange.defaultGroupBy})`;
|
||||
}
|
||||
return text;
|
||||
},
|
||||
|
||||
generateGraphs() {
|
||||
const {autoRefreshMs, source} = this.props;
|
||||
|
||||
return this.props.cells.map((cell) => {
|
||||
const qs = cell.queries.map((q) => {
|
||||
return Object.assign({}, q, {
|
||||
host: source,
|
||||
text: this.buildQuery(q),
|
||||
});
|
||||
});
|
||||
return (
|
||||
<div key={cell.i}>
|
||||
<h2 className="hosts-graph-heading">{cell.name}</h2>
|
||||
<div className="hosts-graph graph-panel__graph-container">
|
||||
<RefreshingLineGraph
|
||||
queries={qs}
|
||||
autoRefresh={autoRefreshMs}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
},
|
||||
|
||||
render() {
|
||||
return (
|
||||
<ReactGridLayout layout={this.state.layout} isDraggable={false} isResizable={false} cols={12} rowHeight={90} width={1200}>
|
||||
{this.generateGraphs()}
|
||||
</ReactGridLayout>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
export default LayoutRenderer;
|
|
@ -1,8 +1,9 @@
|
|||
import React, {PropTypes} from 'react';
|
||||
import LayoutRenderer from '../components/LayoutRenderer';
|
||||
import LayoutRenderer from 'shared/components/LayoutRenderer';
|
||||
import TimeRangeDropdown from '../../shared/components/TimeRangeDropdown';
|
||||
import timeRanges from 'hson!../../shared/data/timeRanges.hson';
|
||||
import {getMappings, getAppsForHosts, fetchLayouts} from '../apis';
|
||||
import {getMappings, getAppsForHosts} from '../apis';
|
||||
import {fetchLayouts} from 'shared/apis';
|
||||
|
||||
export const HostPage = React.createClass({
|
||||
propTypes: {
|
||||
|
|
|
@ -1,41 +0,0 @@
|
|||
import {proxy} from 'utils/queryUrlGenerator';
|
||||
import AJAX from 'utils/ajax';
|
||||
import _ from 'lodash';
|
||||
|
||||
export function getAppsForHosts(proxyLink, hosts, appMappings) {
|
||||
const measurements = appMappings.map((m) => `^${m.measurement}$`).join('|');
|
||||
const measurementsToApps = _.zipObject(appMappings.map(m => m.measurement), appMappings.map(m => m.name));
|
||||
return proxy({
|
||||
source: proxyLink,
|
||||
query: `show series from /${measurements}/`,
|
||||
db: 'telegraf',
|
||||
}).then((resp) => {
|
||||
const newHosts = Object.assign({}, hosts);
|
||||
const allSeries = _.get(resp, ['data', 'results', '0', 'series', '0', 'values'], []);
|
||||
allSeries.forEach(([series]) => {
|
||||
const matches = series.match(/(\w*).*,host=([^,]*)/);
|
||||
if (!matches || matches.length !== 3) { // eslint-disable-line no-magic-numbers
|
||||
return;
|
||||
}
|
||||
const measurement = matches[1];
|
||||
const host = matches[2];
|
||||
|
||||
if (!newHosts[host]) {
|
||||
return;
|
||||
}
|
||||
if (!newHosts[host].apps) {
|
||||
newHosts[host].apps = [];
|
||||
}
|
||||
newHosts[host].apps = _.uniq(newHosts[host].apps.concat(measurementsToApps[measurement]));
|
||||
});
|
||||
|
||||
return newHosts;
|
||||
});
|
||||
}
|
||||
|
||||
export function fetchLayouts() {
|
||||
return AJAX({
|
||||
url: `/chronograf/v1/layouts`,
|
||||
method: 'GET',
|
||||
});
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
import React, {PropTypes} from 'react';
|
||||
import LayoutRenderer from '../components/LayoutRenderer';
|
||||
import LayoutRenderer from 'shared/components/LayoutRenderer';
|
||||
import TimeRangeDropdown from '../../shared/components/TimeRangeDropdown';
|
||||
import timeRanges from 'hson!../../shared/data/timeRanges.hson';
|
||||
|
||||
|
@ -57,13 +57,19 @@ export const KubernetesPage = React.createClass({
|
|||
render() {
|
||||
const {layouts} = this.props;
|
||||
const {timeRange} = this.state;
|
||||
const emptyState = (
|
||||
<div className="generic-empty-state">
|
||||
<span className="icon alert-triangle"></span>
|
||||
<h4>No Kubernetes configuration found</h4>
|
||||
</div>
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="host-dashboard hosts-page">
|
||||
<div className="enterprise-header hosts-dashboard-header">
|
||||
<div className="enterprise-header__container">
|
||||
<div className="enterprise-header__left">
|
||||
<h2>Kubernetes Dashboard</h2>
|
||||
<h1>Kubernetes Dashboard</h1>
|
||||
</div>
|
||||
<div className="enterprise-header__right">
|
||||
<h1>Range:</h1>
|
||||
|
@ -74,7 +80,7 @@ export const KubernetesPage = React.createClass({
|
|||
<div className="hosts-page-scroll-container">
|
||||
<div className="container-fluid hosts-dashboard">
|
||||
<div className="row">
|
||||
{ (layouts.length > 0) ? this.renderLayouts(layouts) : '' }
|
||||
{layouts.length ? this.renderLayouts(layouts) : emptyState}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import React, {PropTypes} from 'react';
|
||||
import {fetchLayouts} from '../apis';
|
||||
import {fetchLayouts} from 'shared/apis';
|
||||
import KubernetesDashboard from 'src/kubernetes/components/KubernetesDashboard';
|
||||
|
||||
export const KubernetesPage = React.createClass({
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
import AJAX from 'utils/ajax';
|
||||
import {proxy} from 'utils/queryUrlGenerator';
|
||||
|
||||
export function fetchLayouts() {
|
||||
return AJAX({
|
||||
url: `/chronograf/v1/layouts`,
|
||||
method: 'GET',
|
||||
});
|
||||
}
|
||||
|
||||
export function getSources() {
|
||||
return AJAX({
|
||||
|
|
|
@ -48,7 +48,7 @@ export const LayoutRenderer = React.createClass({
|
|||
|
||||
let text = q.text;
|
||||
|
||||
text += ` where time > ${timeRange.queryValue}`
|
||||
text += ` where time > ${timeRange.queryValue}`;
|
||||
|
||||
if (host) {
|
||||
text += ` and \"host\" = '${host}'`;
|
Loading…
Reference in New Issue