From cf58eea1dbbc40df3a2c5ca07a31e343e226c728 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Fri, 31 Aug 2018 13:24:36 +0200 Subject: [PATCH] redux: wip progress for using redux --- docker/blocks/openldap/ldap_dev.toml | 1 + .../containers/ServerStats/ServerStats.tsx | 52 -------------- public/app/core/actions/index.ts | 3 + public/app/core/actions/navModel.ts | 11 +++ .../core/components/PageHeader/PageHeader.tsx | 2 +- public/app/core/components/grafana_app.ts | 2 +- public/app/core/reducers/index.ts | 5 ++ public/app/core/reducers/navModel.ts | 64 +++++++++++++++++ .../server-stats}/ServerStats.test.tsx | 0 .../app/features/server-stats/ServerStats.tsx | 69 +++++++++++++++++++ .../__snapshots__/ServerStats.test.tsx.snap | 0 public/app/routes/ReactContainer.tsx | 10 ++- public/app/routes/routes.ts | 2 +- public/app/store/nav/actions.ts | 30 -------- public/app/store/nav/reducers.ts | 30 -------- .../app/{store => stores}/configureStore.ts | 4 +- public/app/types/container.ts | 6 ++ public/app/types/index.ts | 4 ++ public/app/types/navModel.ts | 19 +++++ 19 files changed, 194 insertions(+), 120 deletions(-) delete mode 100644 public/app/containers/ServerStats/ServerStats.tsx create mode 100644 public/app/core/actions/index.ts create mode 100644 public/app/core/actions/navModel.ts create mode 100644 public/app/core/reducers/index.ts create mode 100644 public/app/core/reducers/navModel.ts rename public/app/{containers/ServerStats => features/server-stats}/ServerStats.test.tsx (100%) create mode 100644 public/app/features/server-stats/ServerStats.tsx rename public/app/{containers/ServerStats => features/server-stats}/__snapshots__/ServerStats.test.tsx.snap (100%) delete mode 100644 public/app/store/nav/actions.ts delete mode 100644 public/app/store/nav/reducers.ts rename public/app/{store => stores}/configureStore.ts (86%) create mode 100644 public/app/types/container.ts create mode 100644 public/app/types/index.ts create mode 100644 public/app/types/navModel.ts diff --git a/docker/blocks/openldap/ldap_dev.toml b/docker/blocks/openldap/ldap_dev.toml index e79771b57de..8767ff3c64a 100644 --- a/docker/blocks/openldap/ldap_dev.toml +++ b/docker/blocks/openldap/ldap_dev.toml @@ -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 diff --git a/public/app/containers/ServerStats/ServerStats.tsx b/public/app/containers/ServerStats/ServerStats.tsx deleted file mode 100644 index fe3ef0ecfd1..00000000000 --- a/public/app/containers/ServerStats/ServerStats.tsx +++ /dev/null @@ -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 { - 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 ( -
- -
- - - - - - - - {serverStats.stats.map(StatItem)} -
NameValue
-
-
- ); - } -} - -function StatItem(stat) { - return ( - - {stat.name} - {stat.value} - - ); -} - -export default hot(module)(ServerStats); diff --git a/public/app/core/actions/index.ts b/public/app/core/actions/index.ts new file mode 100644 index 00000000000..3c23dbbbe54 --- /dev/null +++ b/public/app/core/actions/index.ts @@ -0,0 +1,3 @@ +import { initNav } from './navModel'; + +export { initNav }; diff --git a/public/app/core/actions/navModel.ts b/public/app/core/actions/navModel.ts new file mode 100644 index 00000000000..048afd4f8ff --- /dev/null +++ b/public/app/core/actions/navModel.ts @@ -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, +}); diff --git a/public/app/core/components/PageHeader/PageHeader.tsx b/public/app/core/components/PageHeader/PageHeader.tsx index b7bef2495bb..9feddde68ce 100644 --- a/public/app/core/components/PageHeader/PageHeader.tsx +++ b/public/app/core/components/PageHeader/PageHeader.tsx @@ -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'; diff --git a/public/app/core/components/grafana_app.ts b/public/app/core/components/grafana_app.ts index c1cd0e2b5f2..085f0db0a6d 100644 --- a/public/app/core/components/grafana_app.ts +++ b/public/app/core/components/grafana_app.ts @@ -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 */ diff --git a/public/app/core/reducers/index.ts b/public/app/core/reducers/index.ts new file mode 100644 index 00000000000..0779111c16e --- /dev/null +++ b/public/app/core/reducers/index.ts @@ -0,0 +1,5 @@ +import navModel from './navModel'; + +export default { + navModel, +}; diff --git a/public/app/core/reducers/navModel.ts b/public/app/core/reducers/navModel.ts new file mode 100644 index 00000000000..c00441c4881 --- /dev/null +++ b/public/app/core/reducers/navModel.ts @@ -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; diff --git a/public/app/containers/ServerStats/ServerStats.test.tsx b/public/app/features/server-stats/ServerStats.test.tsx similarity index 100% rename from public/app/containers/ServerStats/ServerStats.test.tsx rename to public/app/features/server-stats/ServerStats.test.tsx diff --git a/public/app/features/server-stats/ServerStats.tsx b/public/app/features/server-stats/ServerStats.tsx new file mode 100644 index 00000000000..b499fb725a8 --- /dev/null +++ b/public/app/features/server-stats/ServerStats.tsx @@ -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 { + 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 ( +
+ +

aasd

+
+ ); + // const { nav, serverStats } = this.props; + // return ( + //
+ // + //
+ // + // + // + // + // + // + // + // {serverStats.stats.map(StatItem)} + //
NameValue
+ //
+ //
+ // ); + } +} + +function StatItem(stat) { + return ( + + {stat.name} + {stat.value} + + ); +} + +const mapStateToProps = state => ({ + navModel: state.navModel, +}); + +const mapDispatchToProps = { + initNav, +}; + +export default hot(module)(connect(mapStateToProps, mapDispatchToProps)(ServerStats)); diff --git a/public/app/containers/ServerStats/__snapshots__/ServerStats.test.tsx.snap b/public/app/features/server-stats/__snapshots__/ServerStats.test.tsx.snap similarity index 100% rename from public/app/containers/ServerStats/__snapshots__/ServerStats.test.tsx.snap rename to public/app/features/server-stats/__snapshots__/ServerStats.test.tsx.snap diff --git a/public/app/routes/ReactContainer.tsx b/public/app/routes/ReactContainer.tsx index b161a5e7a87..3ed534da587 100644 --- a/public/app/routes/ReactContainer.tsx +++ b/public/app/routes/ReactContainer.tsx @@ -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 ( - - - + + + + + ); } diff --git a/public/app/routes/routes.ts b/public/app/routes/routes.ts index d12711aca5b..7fcab26645f 100644 --- a/public/app/routes/routes.ts +++ b/public/app/routes/routes.ts @@ -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'; diff --git a/public/app/store/nav/actions.ts b/public/app/store/nav/actions.ts deleted file mode 100644 index eca99cc2b90..00000000000 --- a/public/app/store/nav/actions.ts +++ /dev/null @@ -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 }, -}); diff --git a/public/app/store/nav/reducers.ts b/public/app/store/nav/reducers.ts deleted file mode 100644 index 6e9d6e713a0..00000000000 --- a/public/app/store/nav/reducers.ts +++ /dev/null @@ -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; - } - } -}; diff --git a/public/app/store/configureStore.ts b/public/app/stores/configureStore.ts similarity index 86% rename from public/app/store/configureStore.ts rename to public/app/stores/configureStore.ts index a0dfe576ed6..3a7d16da76d 100644 --- a/public/app/store/configureStore.ts +++ b/public/app/stores/configureStore.ts @@ -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; diff --git a/public/app/types/container.ts b/public/app/types/container.ts new file mode 100644 index 00000000000..174bc0c8460 --- /dev/null +++ b/public/app/types/container.ts @@ -0,0 +1,6 @@ +import { NavModel } from './navModel'; + +export interface ContainerProps { + navModel: NavModel; + initNav: (...args: string[]) => void; +} diff --git a/public/app/types/index.ts b/public/app/types/index.ts new file mode 100644 index 00000000000..43d921e3964 --- /dev/null +++ b/public/app/types/index.ts @@ -0,0 +1,4 @@ +import { NavModel, NavModelItem } from './navModel'; +import { ContainerProps } from './container'; + +export { NavModel, NavModelItem, ContainerProps }; diff --git a/public/app/types/navModel.ts b/public/app/types/navModel.ts new file mode 100644 index 00000000000..e1a4265847c --- /dev/null +++ b/public/app/types/navModel.ts @@ -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; +}