Selaa lähdekoodia

implemented general actionbar

Peter Holmberg 7 vuotta sitten
vanhempi
commit
21cfc11009

+ 38 - 0
public/app/core/components/OrgActionBar/OrgActionBar.tsx

@@ -0,0 +1,38 @@
+import React, { PureComponent } from 'react';
+import LayoutSelector, { LayoutMode } from '../LayoutSelector/LayoutSelector';
+
+export interface Props {
+  searchQuery: string;
+  layoutMode: LayoutMode;
+  setLayoutMode: (mode: LayoutMode) => {};
+  setSearchQuery: (value: string) => {};
+  linkButton: { href: string; title: string };
+}
+
+export default class OrgActionBar extends PureComponent<Props> {
+  render() {
+    const { searchQuery, layoutMode, setLayoutMode, linkButton, setSearchQuery } = this.props;
+
+    return (
+      <div className="page-action-bar">
+        <div className="gf-form gf-form--grow">
+          <label className="gf-form--has-input-icon">
+            <input
+              type="text"
+              className="gf-form-input width-20"
+              value={searchQuery}
+              onChange={event => setSearchQuery(event.target.value)}
+              placeholder="Filter by name or type"
+            />
+            <i className="gf-form-input-icon fa fa-search" />
+          </label>
+          <LayoutSelector mode={layoutMode} onLayoutModeChanged={(mode: LayoutMode) => setLayoutMode(mode)} />
+        </div>
+        <div className="page-action-bar__spacer" />
+        <a className="btn btn-success" href={linkButton.href} target="_blank">
+          {linkButton.title}
+        </a>
+      </div>
+    );
+  }
+}

+ 0 - 23
public/app/features/datasources/DataSourcesActionBar.test.tsx

@@ -1,23 +0,0 @@
-import React from 'react';
-import { shallow } from 'enzyme';
-import { DataSourcesActionBar, Props } from './DataSourcesActionBar';
-import { LayoutModes } from '../../core/components/LayoutSelector/LayoutSelector';
-
-const setup = (propOverrides?: object) => {
-  const props: Props = {
-    layoutMode: LayoutModes.Grid,
-    searchQuery: '',
-    setDataSourcesLayoutMode: jest.fn(),
-    setDataSourcesSearchQuery: jest.fn(),
-  };
-
-  return shallow(<DataSourcesActionBar {...props} />);
-};
-
-describe('Render', () => {
-  it('should render component', () => {
-    const wrapper = setup();
-
-    expect(wrapper).toMatchSnapshot();
-  });
-});

+ 0 - 62
public/app/features/datasources/DataSourcesActionBar.tsx

@@ -1,62 +0,0 @@
-import React, { PureComponent } from 'react';
-import { connect } from 'react-redux';
-import LayoutSelector, { LayoutMode } from '../../core/components/LayoutSelector/LayoutSelector';
-import { setDataSourcesLayoutMode, setDataSourcesSearchQuery } from './state/actions';
-import { getDataSourcesLayoutMode, getDataSourcesSearchQuery } from './state/selectors';
-
-export interface Props {
-  searchQuery: string;
-  layoutMode: LayoutMode;
-  setDataSourcesLayoutMode: typeof setDataSourcesLayoutMode;
-  setDataSourcesSearchQuery: typeof setDataSourcesSearchQuery;
-}
-
-export class DataSourcesActionBar extends PureComponent<Props> {
-  onSearchQueryChange = event => {
-    this.props.setDataSourcesSearchQuery(event.target.value);
-  };
-
-  render() {
-    const { searchQuery, layoutMode, setDataSourcesLayoutMode } = this.props;
-
-    return (
-      <div className="page-action-bar">
-        <div className="gf-form gf-form--grow">
-          <label className="gf-form--has-input-icon">
-            <input
-              type="text"
-              className="gf-form-input width-20"
-              value={searchQuery}
-              onChange={this.onSearchQueryChange}
-              placeholder="Filter by name or type"
-            />
-            <i className="gf-form-input-icon fa fa-search" />
-          </label>
-          <LayoutSelector
-            mode={layoutMode}
-            onLayoutModeChanged={(mode: LayoutMode) => setDataSourcesLayoutMode(mode)}
-          />
-        </div>
-        <div className="page-action-bar__spacer" />
-        <a className="page-header__cta btn btn-success" href="datasources/new">
-          <i className="fa fa-plus" />
-          Add data source
-        </a>
-      </div>
-    );
-  }
-}
-
-function mapStateToProps(state) {
-  return {
-    searchQuery: getDataSourcesSearchQuery(state.dataSources),
-    layoutMode: getDataSourcesLayoutMode(state.dataSources),
-  };
-}
-
-const mapDispatchToProps = {
-  setDataSourcesLayoutMode,
-  setDataSourcesSearchQuery,
-};
-
-export default connect(mapStateToProps, mapDispatchToProps)(DataSourcesActionBar);

+ 38 - 7
public/app/features/datasources/DataSourcesListPage.tsx

@@ -2,21 +2,29 @@ import React, { PureComponent } from 'react';
 import { connect } from 'react-redux';
 import { hot } from 'react-hot-loader';
 import PageHeader from '../../core/components/PageHeader/PageHeader';
-import DataSourcesActionBar from './DataSourcesActionBar';
+import OrgActionBar from '../../core/components/OrgActionBar/OrgActionBar';
+import EmptyListCTA from '../../core/components/EmptyListCTA/EmptyListCTA';
 import DataSourcesList from './DataSourcesList';
-import { loadDataSources } from './state/actions';
-import { getDataSources, getDataSourcesCount, getDataSourcesLayoutMode } from './state/selectors';
-import { getNavModel } from '../../core/selectors/navModel';
 import { DataSource, NavModel } from 'app/types';
 import { LayoutMode } from '../../core/components/LayoutSelector/LayoutSelector';
-import EmptyListCTA from '../../core/components/EmptyListCTA/EmptyListCTA';
+import { loadDataSources, setDataSourcesLayoutMode, setDataSourcesSearchQuery } from './state/actions';
+import { getNavModel } from '../../core/selectors/navModel';
+import {
+  getDataSources,
+  getDataSourcesCount,
+  getDataSourcesLayoutMode,
+  getDataSourcesSearchQuery,
+} from './state/selectors';
 
 export interface Props {
   navModel: NavModel;
   dataSources: DataSource[];
   dataSourcesCount: number;
   layoutMode: LayoutMode;
+  searchQuery: string;
   loadDataSources: typeof loadDataSources;
+  setDataSourcesLayoutMode: typeof setDataSourcesLayoutMode;
+  setDataSourcesSearchQuery: typeof setDataSourcesSearchQuery;
 }
 
 const emptyListModel = {
@@ -40,7 +48,20 @@ export class DataSourcesListPage extends PureComponent<Props> {
   }
 
   render() {
-    const { dataSources, dataSourcesCount, navModel, layoutMode } = this.props;
+    const {
+      dataSources,
+      dataSourcesCount,
+      navModel,
+      layoutMode,
+      searchQuery,
+      setDataSourcesSearchQuery,
+      setDataSourcesLayoutMode,
+    } = this.props;
+
+    const linkButton = {
+      href: 'datasources/new',
+      title: 'Add data source',
+    };
 
     return (
       <div>
@@ -50,7 +71,14 @@ export class DataSourcesListPage extends PureComponent<Props> {
             <EmptyListCTA model={emptyListModel} />
           ) : (
             [
-              <DataSourcesActionBar key="action-bar" />,
+              <OrgActionBar
+                layoutMode={layoutMode}
+                searchQuery={searchQuery}
+                setLayoutMode={mode => setDataSourcesLayoutMode(mode)}
+                setSearchQuery={query => setDataSourcesSearchQuery(query)}
+                linkButton={linkButton}
+                key="action-bar"
+              />,
               <DataSourcesList dataSources={dataSources} layoutMode={layoutMode} key="list" />,
             ]
           )}
@@ -66,11 +94,14 @@ function mapStateToProps(state) {
     dataSources: getDataSources(state.dataSources),
     layoutMode: getDataSourcesLayoutMode(state.dataSources),
     dataSourcesCount: getDataSourcesCount(state.dataSources),
+    searchQuery: getDataSourcesSearchQuery(state.dataSources),
   };
 }
 
 const mapDispatchToProps = {
   loadDataSources,
+  setDataSourcesSearchQuery,
+  setDataSourcesLayoutMode,
 };
 
 export default hot(module)(connect(mapStateToProps, mapDispatchToProps)(DataSourcesListPage));

+ 0 - 31
public/app/features/plugins/PluginActionBar.test.tsx

@@ -1,31 +0,0 @@
-import React from 'react';
-import { shallow } from 'enzyme';
-import { PluginActionBar, Props } from './PluginActionBar';
-import { LayoutModes } from '../../core/components/LayoutSelector/LayoutSelector';
-
-const setup = (propOverrides?: object) => {
-  const props: Props = {
-    searchQuery: '',
-    layoutMode: LayoutModes.Grid,
-    setLayoutMode: jest.fn(),
-    setPluginsSearchQuery: jest.fn(),
-  };
-
-  Object.assign(props, propOverrides);
-
-  const wrapper = shallow(<PluginActionBar {...props} />);
-  const instance = wrapper.instance() as PluginActionBar;
-
-  return {
-    wrapper,
-    instance,
-  };
-};
-
-describe('Render', () => {
-  it('should render component', () => {
-    const { wrapper } = setup();
-
-    expect(wrapper).toMatchSnapshot();
-  });
-});

+ 0 - 62
public/app/features/plugins/PluginActionBar.tsx

@@ -1,62 +0,0 @@
-import React, { PureComponent } from 'react';
-import { connect } from 'react-redux';
-import LayoutSelector, { LayoutMode } from '../../core/components/LayoutSelector/LayoutSelector';
-import { setLayoutMode, setPluginsSearchQuery } from './state/actions';
-import { getPluginsSearchQuery, getLayoutMode } from './state/selectors';
-
-export interface Props {
-  searchQuery: string;
-  layoutMode: LayoutMode;
-  setLayoutMode: typeof setLayoutMode;
-  setPluginsSearchQuery: typeof setPluginsSearchQuery;
-}
-
-export class PluginActionBar extends PureComponent<Props> {
-  onSearchQueryChange = event => {
-    this.props.setPluginsSearchQuery(event.target.value);
-  };
-
-  render() {
-    const { searchQuery, layoutMode, setLayoutMode } = this.props;
-
-    return (
-      <div className="page-action-bar">
-        <div className="gf-form gf-form--grow">
-          <label className="gf-form--has-input-icon">
-            <input
-              type="text"
-              className="gf-form-input width-20"
-              value={searchQuery}
-              onChange={this.onSearchQueryChange}
-              placeholder="Filter by name or type"
-            />
-            <i className="gf-form-input-icon fa fa-search" />
-          </label>
-          <LayoutSelector mode={layoutMode} onLayoutModeChanged={(mode: LayoutMode) => setLayoutMode(mode)} />
-        </div>
-        <div className="page-action-bar__spacer" />
-        <a
-          className="btn btn-success"
-          href="https://grafana.com/plugins?utm_source=grafana_plugin_list"
-          target="_blank"
-        >
-          Find more plugins on Grafana.com
-        </a>
-      </div>
-    );
-  }
-}
-
-function mapStateToProps(state) {
-  return {
-    searchQuery: getPluginsSearchQuery(state.plugins),
-    layoutMode: getLayoutMode(state.plugins),
-  };
-}
-
-const mapDispatchToProps = {
-  setPluginsSearchQuery,
-  setLayoutMode,
-};
-
-export default connect(mapStateToProps, mapDispatchToProps)(PluginActionBar);

+ 23 - 7
public/app/features/plugins/PluginListPage.tsx

@@ -1,20 +1,23 @@
 import React, { PureComponent } from 'react';
 import { hot } from 'react-hot-loader';
 import { connect } from 'react-redux';
-import PageHeader from '../../core/components/PageHeader/PageHeader';
-import PluginActionBar from './PluginActionBar';
+import PageHeader from 'app/core/components/PageHeader/PageHeader';
+import OrgActionBar from 'app/core/components/OrgActionBar/OrgActionBar';
 import PluginList from './PluginList';
-import { NavModel, Plugin } from '../../types';
-import { loadPlugins } from './state/actions';
+import { NavModel, Plugin } from 'app/types';
+import { loadPlugins, setPluginsLayoutMode, setPluginsSearchQuery } from './state/actions';
 import { getNavModel } from '../../core/selectors/navModel';
-import { getLayoutMode, getPlugins } from './state/selectors';
+import { getLayoutMode, getPlugins, getPluginsSearchQuery } from './state/selectors';
 import { LayoutMode } from '../../core/components/LayoutSelector/LayoutSelector';
 
 export interface Props {
   navModel: NavModel;
   plugins: Plugin[];
   layoutMode: LayoutMode;
+  searchQuery: string;
   loadPlugins: typeof loadPlugins;
+  setPluginsLayoutMoode: typeof setPluginsLayoutMode;
+  setPluginsSearchQuery: typeof setPluginsSearchQuery;
 }
 
 export class PluginListPage extends PureComponent<Props> {
@@ -27,13 +30,23 @@ export class PluginListPage extends PureComponent<Props> {
   }
 
   render() {
-    const { navModel, plugins, layoutMode } = this.props;
+    const { navModel, plugins, layoutMode, setPluginsLayoutMoode, setPluginsSearchQuery, searchQuery } = this.props;
 
+    const linkButton = {
+      href: 'https://grafana.com/plugins?utm_source=grafana_plugin_list',
+      title: 'Find more plugins on Grafana.com',
+    };
     return (
       <div>
         <PageHeader model={navModel} />
         <div className="page-container page-body">
-          <PluginActionBar />
+          <OrgActionBar
+            searchQuery={searchQuery}
+            layoutMode={layoutMode}
+            setLayoutMode={mode => setPluginsLayoutMoode(mode)}
+            setSearchQuery={query => setPluginsSearchQuery(query)}
+            linkButton={linkButton}
+          />
           {plugins && <PluginList plugins={plugins} layoutMode={layoutMode} />}
         </div>
       </div>
@@ -46,11 +59,14 @@ function mapStateToProps(state) {
     navModel: getNavModel(state.navIndex, 'plugins'),
     plugins: getPlugins(state.plugins),
     layoutMode: getLayoutMode(state.plugins),
+    searchQuery: getPluginsSearchQuery(state.plugins),
   };
 }
 
 const mapDispatchToProps = {
   loadPlugins,
+  setPluginsLayoutMode,
+  setPluginsSearchQuery,
 };
 
 export default hot(module)(connect(mapStateToProps, mapDispatchToProps)(PluginListPage));

+ 1 - 1
public/app/features/plugins/state/actions.ts

@@ -24,7 +24,7 @@ export interface SetLayoutModeAction {
   payload: LayoutMode;
 }
 
-export const setLayoutMode = (mode: LayoutMode): SetLayoutModeAction => ({
+export const setPluginsLayoutMode = (mode: LayoutMode): SetLayoutModeAction => ({
   type: ActionTypes.SetLayoutMode,
   payload: mode,
 });