mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
redux: wip progress for using redux
This commit is contained in:
parent
ad9f38ae4d
commit
cf58eea1db
@ -72,6 +72,7 @@ email = "email"
|
||||
[[servers.group_mappings]]
|
||||
group_dn = "cn=admins,ou=groups,dc=grafana,dc=org"
|
||||
org_role = "Admin"
|
||||
grafana_admin = true
|
||||
# The Grafana organization database id, optional, if left out the default org (id 1) will be used
|
||||
# org_id = 1
|
||||
|
||||
|
@ -1,52 +0,0 @@
|
||||
import React from 'react';
|
||||
import { hot } from 'react-hot-loader';
|
||||
import { inject, observer } from 'mobx-react';
|
||||
import PageHeader from 'app/core/components/PageHeader/PageHeader';
|
||||
import { store } from 'app/store/configureStore';
|
||||
import { setNav } from 'app/store/nav/actions';
|
||||
import ContainerProps from 'app/containers/ContainerProps';
|
||||
|
||||
@inject('nav', 'serverStats')
|
||||
@observer
|
||||
export class ServerStats extends React.Component<ContainerProps, any> {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
const { nav, serverStats } = this.props;
|
||||
|
||||
nav.load('cfg', 'admin', 'server-stats');
|
||||
serverStats.load();
|
||||
|
||||
store.dispatch(setNav('new', { asd: 'tasd' }));
|
||||
}
|
||||
|
||||
render() {
|
||||
const { nav, serverStats } = this.props;
|
||||
return (
|
||||
<div>
|
||||
<PageHeader model={nav as any} />
|
||||
<div className="page-container page-body">
|
||||
<table className="filter-table form-inline">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Value</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>{serverStats.stats.map(StatItem)}</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function StatItem(stat) {
|
||||
return (
|
||||
<tr key={stat.name}>
|
||||
<td>{stat.name}</td>
|
||||
<td>{stat.value}</td>
|
||||
</tr>
|
||||
);
|
||||
}
|
||||
|
||||
export default hot(module)(ServerStats);
|
3
public/app/core/actions/index.ts
Normal file
3
public/app/core/actions/index.ts
Normal file
@ -0,0 +1,3 @@
|
||||
import { initNav } from './navModel';
|
||||
|
||||
export { initNav };
|
11
public/app/core/actions/navModel.ts
Normal file
11
public/app/core/actions/navModel.ts
Normal file
@ -0,0 +1,11 @@
|
||||
export type Action = InitNavModelAction;
|
||||
|
||||
export interface InitNavModelAction {
|
||||
type: 'INIT_NAV_MODEL';
|
||||
args: string[];
|
||||
}
|
||||
|
||||
export const initNav = (...args: string[]): InitNavModelAction => ({
|
||||
type: 'INIT_NAV_MODEL',
|
||||
args: args,
|
||||
});
|
@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
import { observer } from 'mobx-react';
|
||||
import { NavModel, NavModelItem } from '../../nav_model_srv';
|
||||
import { NavModel, NavModelItem } from 'app/types';
|
||||
import classNames from 'classnames';
|
||||
import appEvents from 'app/core/app_events';
|
||||
import { toJS } from 'mobx';
|
||||
|
@ -10,7 +10,7 @@ import { createStore } from 'app/stores/store';
|
||||
import colors from 'app/core/utils/colors';
|
||||
import { BackendSrv, setBackendSrv } from 'app/core/services/backend_srv';
|
||||
import { DatasourceSrv } from 'app/features/plugins/datasource_srv';
|
||||
import { configureStore } from 'app/store/configureStore';
|
||||
import { configureStore } from 'app/stores/configureStore';
|
||||
|
||||
export class GrafanaCtrl {
|
||||
/** @ngInject */
|
||||
|
5
public/app/core/reducers/index.ts
Normal file
5
public/app/core/reducers/index.ts
Normal file
@ -0,0 +1,5 @@
|
||||
import navModel from './navModel';
|
||||
|
||||
export default {
|
||||
navModel,
|
||||
};
|
64
public/app/core/reducers/navModel.ts
Normal file
64
public/app/core/reducers/navModel.ts
Normal file
@ -0,0 +1,64 @@
|
||||
import { Action } from 'app/core/actions/navModel';
|
||||
import { NavModel, NavModelItem } from 'app/types';
|
||||
import config from 'app/core/config';
|
||||
|
||||
function getNotFoundModel(): NavModel {
|
||||
var node: NavModelItem = {
|
||||
id: 'not-found',
|
||||
text: 'Page not found',
|
||||
icon: 'fa fa-fw fa-warning',
|
||||
subTitle: '404 Error',
|
||||
url: 'not-found',
|
||||
};
|
||||
|
||||
return {
|
||||
breadcrumbs: [node],
|
||||
node: node,
|
||||
main: node,
|
||||
};
|
||||
}
|
||||
|
||||
export const initialState: NavModel = getNotFoundModel();
|
||||
|
||||
const navModelReducer = (state = initialState, action: Action): NavModel => {
|
||||
switch (action.type) {
|
||||
case 'INIT_NAV_MODEL': {
|
||||
let children = config.bootData.navTree as NavModelItem[];
|
||||
let main, node;
|
||||
const parents = [];
|
||||
|
||||
for (const id of action.args) {
|
||||
node = children.find(el => el.id === id);
|
||||
|
||||
if (!node) {
|
||||
throw new Error(`NavItem with id ${id} not found`);
|
||||
}
|
||||
|
||||
children = node.children;
|
||||
parents.push(node);
|
||||
}
|
||||
|
||||
main = parents[parents.length - 2];
|
||||
|
||||
if (main.children) {
|
||||
for (const item of main.children) {
|
||||
item.active = false;
|
||||
|
||||
if (item.url === node.url) {
|
||||
item.active = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
main: main,
|
||||
node: node,
|
||||
breadcrumbs: [],
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return state;
|
||||
};
|
||||
|
||||
export default navModelReducer;
|
69
public/app/features/server-stats/ServerStats.tsx
Normal file
69
public/app/features/server-stats/ServerStats.tsx
Normal file
@ -0,0 +1,69 @@
|
||||
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 PageHeader from 'app/core/components/PageHeader/PageHeader';
|
||||
|
||||
interface Props extends ContainerProps {}
|
||||
|
||||
export class ServerStats extends React.Component<Props, any> {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.props.initNav('cfg', 'admin', 'server-stats');
|
||||
// const { nav, serverStats } = this.props;
|
||||
//
|
||||
// nav.load('cfg', 'admin', 'server-stats');
|
||||
// serverStats.load();
|
||||
//
|
||||
// store.dispatch(setNav('new', { asd: 'tasd' }));
|
||||
}
|
||||
|
||||
render() {
|
||||
const { navModel } = this.props;
|
||||
console.log('render', navModel);
|
||||
return (
|
||||
<div>
|
||||
<PageHeader model={navModel} />
|
||||
<h2>aasd</h2>
|
||||
</div>
|
||||
);
|
||||
// const { nav, serverStats } = this.props;
|
||||
// return (
|
||||
// <div>
|
||||
// <PageHeader model={nav as any} />
|
||||
// <div className="page-container page-body">
|
||||
// <table className="filter-table form-inline">
|
||||
// <thead>
|
||||
// <tr>
|
||||
// <th>Name</th>
|
||||
// <th>Value</th>
|
||||
// </tr>
|
||||
// </thead>
|
||||
// <tbody>{serverStats.stats.map(StatItem)}</tbody>
|
||||
// </table>
|
||||
// </div>
|
||||
// </div>
|
||||
// );
|
||||
}
|
||||
}
|
||||
|
||||
function StatItem(stat) {
|
||||
return (
|
||||
<tr key={stat.name}>
|
||||
<td>{stat.name}</td>
|
||||
<td>{stat.value}</td>
|
||||
</tr>
|
||||
);
|
||||
}
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
navModel: state.navModel,
|
||||
});
|
||||
|
||||
const mapDispatchToProps = {
|
||||
initNav,
|
||||
};
|
||||
|
||||
export default hot(module)(connect(mapStateToProps, mapDispatchToProps)(ServerStats));
|
@ -1,18 +1,22 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import { Provider } from 'mobx-react';
|
||||
import { Provider as ReduxProvider } from 'react-redux';
|
||||
|
||||
import coreModule from 'app/core/core_module';
|
||||
import { store } from 'app/stores/store';
|
||||
import { store as reduxStore } from 'app/stores/configureStore';
|
||||
import { BackendSrv } from 'app/core/services/backend_srv';
|
||||
import { DatasourceSrv } from 'app/features/plugins/datasource_srv';
|
||||
import { ContextSrv } from 'app/core/services/context_srv';
|
||||
|
||||
function WrapInProvider(store, Component, props) {
|
||||
return (
|
||||
<Provider {...store}>
|
||||
<Component {...props} />
|
||||
</Provider>
|
||||
<ReduxProvider store={reduxStore}>
|
||||
<Provider {...store}>
|
||||
<Component {...props} />
|
||||
</Provider>
|
||||
</ReduxProvider>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
import './dashboard_loaders';
|
||||
import './ReactContainer';
|
||||
|
||||
import ServerStats from 'app/containers/ServerStats/ServerStats';
|
||||
import ServerStats from 'app/features/server-stats/ServerStats';
|
||||
import AlertRuleList from 'app/containers/AlertRuleList/AlertRuleList';
|
||||
import FolderSettings from 'app/containers/ManageDashboards/FolderSettings';
|
||||
import FolderPermissions from 'app/containers/ManageDashboards/FolderPermissions';
|
||||
|
@ -1,30 +0,0 @@
|
||||
//
|
||||
// Only test actions to test redux & typescript
|
||||
//
|
||||
|
||||
export enum ActionTypes {
|
||||
SET_NAV = 'SET_NAV',
|
||||
SET_QUERY = 'SET_QUERY',
|
||||
}
|
||||
|
||||
export interface SetNavAction {
|
||||
type: ActionTypes.SET_NAV;
|
||||
payload: {
|
||||
path: string;
|
||||
query: object;
|
||||
};
|
||||
}
|
||||
|
||||
export interface SetQueryAction {
|
||||
type: ActionTypes.SET_QUERY;
|
||||
payload: {
|
||||
query: object;
|
||||
};
|
||||
}
|
||||
|
||||
export type Action = SetNavAction | SetQueryAction;
|
||||
|
||||
export const setNav = (path: string, query: object): SetNavAction => ({
|
||||
type: ActionTypes.SET_NAV,
|
||||
payload: { path: path, query: query },
|
||||
});
|
@ -1,30 +0,0 @@
|
||||
import { Action, ActionTypes } from './actions';
|
||||
|
||||
export interface NavState {
|
||||
path: string;
|
||||
query: object;
|
||||
}
|
||||
|
||||
const initialState: NavState = {
|
||||
path: '/test',
|
||||
query: {},
|
||||
};
|
||||
|
||||
export const navReducer = (state: NavState = initialState, action: Action): NavState => {
|
||||
switch (action.type) {
|
||||
case ActionTypes.SET_NAV: {
|
||||
return { ...state, path: action.payload.path, query: action.payload.query };
|
||||
}
|
||||
|
||||
case ActionTypes.SET_QUERY: {
|
||||
return {
|
||||
...state,
|
||||
query: action.payload.query,
|
||||
};
|
||||
}
|
||||
|
||||
default: {
|
||||
return state;
|
||||
}
|
||||
}
|
||||
};
|
@ -1,10 +1,10 @@
|
||||
import { createStore, applyMiddleware, compose, combineReducers } from 'redux';
|
||||
import thunk from 'redux-thunk';
|
||||
import { createLogger } from 'redux-logger';
|
||||
import { navReducer } from './nav/reducers';
|
||||
import sharedReducers from 'app/core/reducers';
|
||||
|
||||
const rootReducer = combineReducers({
|
||||
nav: navReducer,
|
||||
...sharedReducers
|
||||
});
|
||||
|
||||
export let store;
|
6
public/app/types/container.ts
Normal file
6
public/app/types/container.ts
Normal file
@ -0,0 +1,6 @@
|
||||
import { NavModel } from './navModel';
|
||||
|
||||
export interface ContainerProps {
|
||||
navModel: NavModel;
|
||||
initNav: (...args: string[]) => void;
|
||||
}
|
4
public/app/types/index.ts
Normal file
4
public/app/types/index.ts
Normal file
@ -0,0 +1,4 @@
|
||||
import { NavModel, NavModelItem } from './navModel';
|
||||
import { ContainerProps } from './container';
|
||||
|
||||
export { NavModel, NavModelItem, ContainerProps };
|
19
public/app/types/navModel.ts
Normal file
19
public/app/types/navModel.ts
Normal file
@ -0,0 +1,19 @@
|
||||
export interface NavModelItem {
|
||||
text: string;
|
||||
url: string;
|
||||
subTitle?: string;
|
||||
icon?: string;
|
||||
img?: string;
|
||||
id: string;
|
||||
active?: boolean;
|
||||
hideFromTabs?: boolean;
|
||||
divider?: boolean;
|
||||
children?: NavModelItem[];
|
||||
target?: string;
|
||||
}
|
||||
|
||||
export interface NavModel {
|
||||
breadcrumbs: NavModelItem[];
|
||||
main: NavModelItem;
|
||||
node: NavModelItem;
|
||||
}
|
Loading…
Reference in New Issue
Block a user