Ver código fonte

wip: moving things around

Torkel Ödegaard 7 anos atrás
pai
commit
6efe9da10f

+ 26 - 0
public/app/features/admin/apis/index.ts

@@ -0,0 +1,26 @@
+import { getBackendSrv } from 'app/core/services/backend_srv';
+
+export interface ServerStat {
+  name: string;
+  value: string;
+}
+
+export const getServerStats = async (): Promise<ServerStat[]> => {
+  try {
+    const res = await getBackendSrv().get('api/admin/stats');
+    return [
+      { name: 'Total users', value: res.users },
+      { name: 'Total dashboards', value: res.dashboards },
+      { name: 'Active users (seen last 30 days)', value: res.activeUsers },
+      { name: 'Total orgs', value: res.orgs },
+      { name: 'Total playlists', value: res.playlists },
+      { name: 'Total snapshots', value: res.snapshots },
+      { name: 'Total dashboard tags', value: res.tags },
+      { name: 'Total starred dashboards', value: res.stars },
+      { name: 'Total alerts', value: res.alerts },
+    ];
+  } catch (error) {
+    console.error(error);
+    throw error;
+  }
+};

+ 30 - 0
public/app/features/admin/containers/ServerStats.test.tsx

@@ -0,0 +1,30 @@
+import React from 'react';
+import renderer from 'react-test-renderer';
+import { ServerStats } from './ServerStats';
+import { RootStore } from 'app/stores/RootStore/RootStore';
+import { backendSrv, createNavTree } from 'test/mocks/common';
+
+describe('ServerStats', () => {
+  it('Should render table with stats', done => {
+    backendSrv.get.mockReturnValue(
+      Promise.resolve({
+        dashboards: 10,
+      })
+    );
+
+    const store = RootStore.create(
+      {},
+      {
+        backendSrv: backendSrv,
+        navTree: createNavTree('cfg', 'admin', 'server-stats'),
+      }
+    );
+
+    const page = renderer.create(<ServerStats backendSrv={backendSrv} {...store} />);
+
+    setTimeout(() => {
+      expect(page.toJSON()).toMatchSnapshot();
+      done();
+    });
+  });
+});

+ 78 - 0
public/app/features/admin/containers/ServerStats.tsx

@@ -0,0 +1,78 @@
+import React from 'react';
+import { hot } from 'react-hot-loader';
+import { connect } from 'react-redux';
+import { initNav } from 'app/core/actions';
+import { ContainerProps } from 'app/types';
+import { getServerStats, ServerStat } from '../apis';
+import PageHeader from 'app/core/components/PageHeader/PageHeader';
+
+interface Props extends ContainerProps {
+  getServerStats: () => Promise<ServerStat[]>;
+}
+
+interface State {
+  stats: ServerStat[];
+}
+
+export class ServerStats extends React.Component<Props, State> {
+  constructor(props) {
+    super(props);
+
+    this.state = {
+      stats: [],
+    };
+
+    this.props.initNav('cfg', 'admin', 'server-stats');
+  }
+
+  async componentDidMount() {
+    try {
+      const stats = await this.props.getServerStats();
+      this.setState({ stats });
+    } catch (error) {
+      console.error(error);
+    }
+  }
+
+  render() {
+    const { navModel } = this.props;
+    const { stats } = this.state;
+
+    return (
+      <div>
+        <PageHeader model={navModel} />
+        <div className="page-container page-body">
+          <table className="filter-table form-inline">
+            <thead>
+              <tr>
+                <th>Name</th>
+                <th>Value</th>
+              </tr>
+            </thead>
+            <tbody>{stats.map(StatItem)}</tbody>
+          </table>
+        </div>
+      </div>
+    );
+  }
+}
+
+function StatItem(stat: ServerStat) {
+  return (
+    <tr key={stat.name}>
+      <td>{stat.name}</td>
+      <td>{stat.value}</td>
+    </tr>
+  );
+}
+
+const mapStateToProps = state => ({
+  navModel: state.navModel,
+  getServerStats: getServerStats,
+});
+
+const mapDispatchToProps = {
+  initNav,
+};
+
+export default hot(module)(connect(mapStateToProps, mapDispatchToProps)(ServerStats));

+ 170 - 0
public/app/features/admin/containers/__snapshots__/ServerStats.test.tsx.snap

@@ -0,0 +1,170 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`ServerStats Should render table with stats 1`] = `
+<div>
+  <div
+    className="page-header-canvas"
+  >
+    <div
+      className="page-container"
+    >
+      <div
+        className="page-header"
+      >
+        <div
+          className="page-header__inner"
+        >
+          <span
+            className="page-header__logo"
+          >
+            
+            
+          </span>
+          <div
+            className="page-header__info-block"
+          >
+            <h1
+              className="page-header__title"
+            >
+              admin-Text
+            </h1>
+            
+          </div>
+        </div>
+        <nav>
+          <div
+            className="gf-form-select-wrapper width-20 page-header__select-nav"
+          >
+            <label
+              className="gf-form-select-icon "
+              htmlFor="page-header-select-nav"
+            />
+            <select
+              className="gf-select-nav gf-form-input"
+              id="page-header-select-nav"
+              onChange={[Function]}
+              value="/url/server-stats"
+            >
+              <option
+                value="/url/server-stats"
+              >
+                server-stats-Text
+              </option>
+            </select>
+          </div>
+          <ul
+            className="gf-tabs page-header__tabs"
+          >
+            <li
+              className="gf-tabs-item"
+            >
+              <a
+                className="gf-tabs-link active"
+                href="/url/server-stats"
+                target={undefined}
+              >
+                <i
+                  className=""
+                />
+                server-stats-Text
+              </a>
+            </li>
+          </ul>
+        </nav>
+      </div>
+    </div>
+  </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>
+`;