mirror of
https://github.com/grafana/grafana.git
synced 2026-07-30 00:08:10 -05:00
tech: minor progress on mobx state tree & react containers, working on unit testing
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
import React from 'react';
|
||||
import renderer from 'react-test-renderer';
|
||||
import { ServerStats } from './ServerStats';
|
||||
import { RootStore } from 'app/stores/RootStore';
|
||||
|
||||
describe('ServerStats', () => {
|
||||
it('Should render table with stats', done => {
|
||||
let backendSrvMock = {
|
||||
get: jest.fn().mockReturnValue(
|
||||
Promise.resolve({
|
||||
dashboards: 10,
|
||||
})
|
||||
),
|
||||
};
|
||||
|
||||
const store = RootStore.create({}, { backendSrv: backendSrvMock });
|
||||
const page = renderer.create(<ServerStats store={store} />);
|
||||
|
||||
setTimeout(() => {
|
||||
expect(page.toJSON()).toMatchSnapshot();
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
+4
-5
@@ -9,20 +9,19 @@ export interface IProps {
|
||||
|
||||
@inject('store')
|
||||
@observer
|
||||
export default class ServerStats extends React.Component<IProps, any> {
|
||||
navModel: NavModel;
|
||||
|
||||
export class ServerStats extends React.Component<IProps, any> {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.navModel = new NavModelSrv().getNav('cfg', 'admin', 'server-stats', 1);
|
||||
// this.navModel = new NavModelSrv().getNav('cfg', 'admin', 'server-stats', 1);
|
||||
this.props.store.nav.load('cfg', 'admin', 'server-stats');
|
||||
this.props.store.serverStats.load();
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<PageHeader model={this.navModel} />
|
||||
<PageHeader model={this.props.store.nav} />
|
||||
<div className="page-container page-body">
|
||||
<table className="filter-table form-inline">
|
||||
<thead>
|
||||
@@ -0,0 +1,99 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`ServerStats Should render table with stats 1`] = `
|
||||
<div>
|
||||
//
|
||||
<div
|
||||
className="page-container page-body"
|
||||
>
|
||||
<table
|
||||
className="filter-table form-inline"
|
||||
>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
Name
|
||||
</th>
|
||||
<th>
|
||||
Value
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
Total dashboards
|
||||
</td>
|
||||
<td>
|
||||
10
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
Total users
|
||||
</td>
|
||||
<td>
|
||||
0
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
Active users (seen last 30 days)
|
||||
</td>
|
||||
<td>
|
||||
0
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
Total orgs
|
||||
</td>
|
||||
<td>
|
||||
0
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
Total playlists
|
||||
</td>
|
||||
<td>
|
||||
0
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
Total snapshots
|
||||
</td>
|
||||
<td>
|
||||
0
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
Total dashboard tags
|
||||
</td>
|
||||
<td>
|
||||
0
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
Total starred dashboards
|
||||
</td>
|
||||
<td>
|
||||
0
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
Total alerts
|
||||
</td>
|
||||
<td>
|
||||
0
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
@@ -16,7 +16,7 @@ function WrapInProvider(store, Component, props) {
|
||||
export function reactContainer($route) {
|
||||
return {
|
||||
restrict: 'E',
|
||||
template: '<h2>hasad</h2>',
|
||||
template: '',
|
||||
link(scope, elem) {
|
||||
let component = $route.current.locals.component;
|
||||
let props = {};
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
export class BundleLoader {
|
||||
lazy: any;
|
||||
|
||||
constructor(bundleName) {
|
||||
var defer = null;
|
||||
|
||||
this.lazy = [
|
||||
'$q',
|
||||
'$route',
|
||||
'$rootScope',
|
||||
($q, $route, $rootScope) => {
|
||||
if (defer) {
|
||||
return defer.promise;
|
||||
}
|
||||
|
||||
defer = $q.defer();
|
||||
|
||||
System.import(bundleName).then(() => {
|
||||
defer.resolve();
|
||||
});
|
||||
|
||||
return defer.promise;
|
||||
},
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
import './dashboard_loaders';
|
||||
import './ReactContainer';
|
||||
import ServerStats from 'app/containers/ServerStats';
|
||||
import { ServerStats } from 'app/containers/ServerStats/ServerStats';
|
||||
|
||||
/** @ngInject **/
|
||||
export function setupAngularRoutes($routeProvider, $locationProvider) {
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
import { types } from 'mobx-state-tree';
|
||||
import config from 'app/core/config';
|
||||
import _ from 'lodash';
|
||||
|
||||
export const NavItem = types.model('NavItem', {
|
||||
id: types.identifier(types.string),
|
||||
text: types.string,
|
||||
url: types.optional(types.string, ''),
|
||||
description: types.optional(types.string, ''),
|
||||
icon: types.optional(types.string, ''),
|
||||
img: types.optional(types.string, ''),
|
||||
active: types.optional(types.boolean, false),
|
||||
children: types.optional(types.array(types.late(() => NavItem)), []),
|
||||
});
|
||||
|
||||
export const NavStore = types
|
||||
.model('NavStore', {
|
||||
main: types.maybe(NavItem),
|
||||
node: types.maybe(NavItem),
|
||||
breadcrumbs: types.optional(types.array(NavItem), []),
|
||||
})
|
||||
.actions(self => ({
|
||||
load(...args) {
|
||||
var children = config.bootData.navTree;
|
||||
let main, node;
|
||||
let breadcrumbs = [];
|
||||
|
||||
for (let id of args) {
|
||||
// if its a number then it's the index to use for main
|
||||
if (_.isNumber(id)) {
|
||||
main = breadcrumbs[id];
|
||||
break;
|
||||
}
|
||||
|
||||
let current = _.find(children, { id: id });
|
||||
breadcrumbs.push(current);
|
||||
main = node;
|
||||
node = current;
|
||||
children = node.children;
|
||||
}
|
||||
|
||||
if (main.children) {
|
||||
for (let item of main.children) {
|
||||
item.active = false;
|
||||
|
||||
if (item.url === node.url) {
|
||||
item.active = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.main = NavItem.create(main);
|
||||
self.node = NavItem.create(node);
|
||||
|
||||
for (let item of breadcrumbs) {
|
||||
self.breadcrumbs.push(NavItem.create(item));
|
||||
}
|
||||
|
||||
// self.main = NavItem.create({
|
||||
// id: 'test',
|
||||
// text: 'test',
|
||||
// url: '/test';
|
||||
// children: [
|
||||
// {
|
||||
// id: 'test',
|
||||
// text: 'text',
|
||||
// url: '/test',
|
||||
// active: true,
|
||||
// children: []
|
||||
// }
|
||||
// ]
|
||||
// });
|
||||
},
|
||||
}));
|
||||
@@ -1,6 +1,7 @@
|
||||
import { types } from 'mobx-state-tree';
|
||||
import { SearchStore } from './SearchStore';
|
||||
import { ServerStatsStore } from './ServerStatsStore';
|
||||
import { NavStore } from './NavStore/NavStore';
|
||||
|
||||
export const RootStore = types.model({
|
||||
search: types.optional(SearchStore, {
|
||||
@@ -9,6 +10,7 @@ export const RootStore = types.model({
|
||||
serverStats: types.optional(ServerStatsStore, {
|
||||
stats: [],
|
||||
}),
|
||||
nav: types.optional(NavStore, {}),
|
||||
});
|
||||
|
||||
type IRootStoreType = typeof RootStore.Type;
|
||||
|
||||
@@ -2,28 +2,33 @@ import { types, getEnv, flow } from 'mobx-state-tree';
|
||||
|
||||
export const ServerStat = types.model('ServerStat', {
|
||||
name: types.string,
|
||||
value: types.number,
|
||||
value: types.optional(types.number, 0),
|
||||
});
|
||||
|
||||
export const ServerStatsStore = types
|
||||
.model('ServerStatsStore', {
|
||||
stats: types.array(ServerStat),
|
||||
error: types.optional(types.string, ''),
|
||||
})
|
||||
.actions(self => ({
|
||||
load: flow(function* load() {
|
||||
let backendSrv = getEnv(self).backendSrv;
|
||||
|
||||
let res = yield backendSrv.get('/api/admin/stats');
|
||||
|
||||
self.stats.clear();
|
||||
self.stats.push(ServerStat.create({ name: 'Total dashboards', value: res.dashboards }));
|
||||
self.stats.push(ServerStat.create({ name: 'Total users', value: res.users }));
|
||||
self.stats.push(ServerStat.create({ name: 'Active users (seen last 30 days)', value: res.activeUsers }));
|
||||
self.stats.push(ServerStat.create({ name: 'Total orgs', value: res.orgs }));
|
||||
self.stats.push(ServerStat.create({ name: 'Total playlists', value: res.playlists }));
|
||||
self.stats.push(ServerStat.create({ name: 'Total snapshots', value: res.snapshots }));
|
||||
self.stats.push(ServerStat.create({ name: 'Total dashboard tags', value: res.tags }));
|
||||
self.stats.push(ServerStat.create({ name: 'Total starred dashboards', value: res.stars }));
|
||||
self.stats.push(ServerStat.create({ name: 'Total alerts', value: res.alerts }));
|
||||
try {
|
||||
let res = yield backendSrv.get('/api/admin/stats');
|
||||
self.stats.clear();
|
||||
self.stats.push(ServerStat.create({ name: 'Total dashboards', value: res.dashboards }));
|
||||
self.stats.push(ServerStat.create({ name: 'Total users', value: res.users }));
|
||||
self.stats.push(ServerStat.create({ name: 'Active users (seen last 30 days)', value: res.activeUsers }));
|
||||
self.stats.push(ServerStat.create({ name: 'Total orgs', value: res.orgs }));
|
||||
self.stats.push(ServerStat.create({ name: 'Total playlists', value: res.playlists }));
|
||||
self.stats.push(ServerStat.create({ name: 'Total snapshots', value: res.snapshots }));
|
||||
self.stats.push(ServerStat.create({ name: 'Total dashboard tags', value: res.tags }));
|
||||
self.stats.push(ServerStat.create({ name: 'Total starred dashboards', value: res.stars }));
|
||||
self.stats.push(ServerStat.create({ name: 'Total alerts', value: res.alerts }));
|
||||
} catch (err) {
|
||||
console.log('ServerStats.load error', err);
|
||||
self.error = err.toString();
|
||||
}
|
||||
}),
|
||||
}));
|
||||
|
||||
Reference in New Issue
Block a user