mirror of
https://github.com/Unleash/unleash.git
synced 2024-12-22 19:07:54 +01:00
add simple metrics ui
This commit is contained in:
parent
e4f826a5a2
commit
b375cb839a
@ -2,5 +2,8 @@
|
||||
"extends": [
|
||||
"finn",
|
||||
"finn/node"
|
||||
]
|
||||
],
|
||||
"rules": {
|
||||
"no-shadow": 0
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,31 @@
|
||||
import React, { Component } from 'react';
|
||||
import { List, ListItem, ListSubHeader, ListDivider } from 'react-toolbox/lib/list';
|
||||
import Chip from 'react-toolbox/lib/chip';
|
||||
|
||||
class Metrics extends Component {
|
||||
|
||||
componentDidMount () {
|
||||
this.props.fetchMetrics();
|
||||
}
|
||||
|
||||
render () {
|
||||
const { globalCount, apps, clientList } = this.props;
|
||||
|
||||
return (
|
||||
<List>
|
||||
<ListSubHeader caption={<span>Total of {globalCount} toggles checked from {apps.length} apps ({apps.join(', ')})</span>} />
|
||||
<ListDivider />
|
||||
{clientList.map(({ name, count, ping, appName }, i) =>
|
||||
<ListItem
|
||||
leftActions={[<Chip>{count}</Chip>]}
|
||||
key={name + i}
|
||||
caption={appName}
|
||||
legend={`${name} pinged ${ping}`} />
|
||||
)}
|
||||
</List>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export default Metrics;
|
@ -0,0 +1,39 @@
|
||||
import { connect } from 'react-redux';
|
||||
import Metrics from './metrics-component';
|
||||
import { fetchMetrics } from '../../store/metrics-actions';
|
||||
|
||||
const mapStateToProps = (state) => {
|
||||
const globalCount = state.metrics.get('globalCount');
|
||||
const apps = state.metrics.get('apps').toArray();
|
||||
const clients = state.metrics.get('clients').toJS();
|
||||
|
||||
const clientList = Object
|
||||
.keys(clients)
|
||||
.map((k) => {
|
||||
const client = clients[k];
|
||||
return {
|
||||
name: k,
|
||||
appName: client.appName,
|
||||
count: client.count,
|
||||
ping: new Date(client.ping),
|
||||
};
|
||||
})
|
||||
.sort((a, b) => (a.ping > b.ping ? -1 : 1));
|
||||
|
||||
|
||||
/*
|
||||
Possible stuff to ask/answer:
|
||||
* toggles in use but not in unleash-server
|
||||
* nr of toggles using fallbackValue
|
||||
* strategies implemented but not used
|
||||
*/
|
||||
return {
|
||||
globalCount,
|
||||
apps,
|
||||
clientList,
|
||||
};
|
||||
};
|
||||
|
||||
const MetricsContainer = connect(mapStateToProps, { fetchMetrics })(Metrics);
|
||||
|
||||
export default MetricsContainer;
|
@ -14,10 +14,11 @@ export default class UnleashNav extends Component {
|
||||
|
||||
return (
|
||||
<List selectable ripple className={style.navigation}>
|
||||
{createListItem('/features', 'Feature Toggles')}
|
||||
{createListItem('/features', 'Feature toggles')}
|
||||
{createListItem('/strategies', 'Strategies')}
|
||||
{createListItem('/history', 'Event History')}
|
||||
{createListItem('/archive', 'Archived Toggles')}
|
||||
{createListItem('/history', 'Event history')}
|
||||
{createListItem('/archive', 'Archived toggles')}
|
||||
{createListItem('/metrics', 'Client metrics')}
|
||||
|
||||
<ListDivider />
|
||||
|
||||
|
20
packages/unleash-frontend-next/src/data/metrics-api.js
Normal file
20
packages/unleash-frontend-next/src/data/metrics-api.js
Normal file
@ -0,0 +1,20 @@
|
||||
const URI = '/metrics';
|
||||
|
||||
function throwIfNotSuccess (response) {
|
||||
if (!response.ok) {
|
||||
let error = new Error('API call failed');
|
||||
error.status = response.status;
|
||||
throw error;
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
function fetchAll () {
|
||||
return fetch(URI)
|
||||
.then(throwIfNotSuccess)
|
||||
.then(response => response.json());
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
fetchAll,
|
||||
};
|
@ -15,6 +15,7 @@ import Strategies from './page/strategies';
|
||||
import CreateStrategies from './page/strategies/create';
|
||||
import HistoryPage from './page/history';
|
||||
import Archive from './page/archive';
|
||||
import Metrics from './page/metrics';
|
||||
|
||||
const unleashStore = createStore(
|
||||
store,
|
||||
@ -35,6 +36,7 @@ ReactDOM.render(
|
||||
<Route path="/strategies/create" component={CreateStrategies} />
|
||||
<Route path="/history" component={HistoryPage} />
|
||||
<Route path="/archive" component={Archive} />
|
||||
<Route path="/metrics" component={Metrics} />
|
||||
</Route>
|
||||
</Router>
|
||||
</Provider>, document.getElementById('app'));
|
||||
|
6
packages/unleash-frontend-next/src/page/metrics/index.js
Normal file
6
packages/unleash-frontend-next/src/page/metrics/index.js
Normal file
@ -0,0 +1,6 @@
|
||||
import React from 'react';
|
||||
import Metrics from '../../component/metrics/metrics-container';
|
||||
|
||||
const render = () => <Metrics />;
|
||||
|
||||
export default render;
|
@ -5,6 +5,7 @@ import input from './input-store';
|
||||
import history from './history-store'; // eslint-disable-line
|
||||
import archive from './archive-store';
|
||||
import error from './error-store';
|
||||
import metrics from './metrics-store';
|
||||
|
||||
const unleashStore = combineReducers({
|
||||
features,
|
||||
@ -13,6 +14,7 @@ const unleashStore = combineReducers({
|
||||
history,
|
||||
archive,
|
||||
error,
|
||||
metrics,
|
||||
});
|
||||
|
||||
export default unleashStore;
|
||||
|
20
packages/unleash-frontend-next/src/store/metrics-actions.js
Normal file
20
packages/unleash-frontend-next/src/store/metrics-actions.js
Normal file
@ -0,0 +1,20 @@
|
||||
import api from '../data/metrics-api';
|
||||
|
||||
export const RECEIVE_METRICS = 'RECEIVE_METRICS';
|
||||
export const ERROR_RECEIVE_METRICS = 'ERROR_RECEIVE_METRICS';
|
||||
|
||||
const receiveMetrics = (json) => ({
|
||||
type: RECEIVE_METRICS,
|
||||
value: json,
|
||||
});
|
||||
|
||||
const errorReceiveMetrics = (statusCode) => ({
|
||||
type: ERROR_RECEIVE_METRICS,
|
||||
statusCode,
|
||||
});
|
||||
|
||||
export function fetchMetrics () {
|
||||
return dispatch => api.fetchAll()
|
||||
.then(json => dispatch(receiveMetrics(json)))
|
||||
.catch(error => dispatch(errorReceiveMetrics(error)));
|
||||
}
|
21
packages/unleash-frontend-next/src/store/metrics-store.js
Normal file
21
packages/unleash-frontend-next/src/store/metrics-store.js
Normal file
@ -0,0 +1,21 @@
|
||||
import { fromJS } from 'immutable';
|
||||
import { RECEIVE_METRICS } from './metrics-actions';
|
||||
|
||||
function getInitState () {
|
||||
return fromJS({
|
||||
totalCount: 0,
|
||||
apps: [],
|
||||
clients: {},
|
||||
});
|
||||
}
|
||||
|
||||
const historyStore = (state = getInitState(), action) => {
|
||||
switch (action.type) {
|
||||
case RECEIVE_METRICS:
|
||||
return fromJS(action.value);
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
};
|
||||
|
||||
export default historyStore;
|
@ -73,6 +73,10 @@ module.exports = {
|
||||
target: 'http://localhost:4242',
|
||||
secure: false,
|
||||
},
|
||||
'/metrics': {
|
||||
target: 'http://localhost:4242',
|
||||
secure: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user