Commit 0b7576a1 by Peter Holmberg

filter plugins and layout mode

parent e8cc0f3f
import React from 'react';
export default function LayoutSelector({ mode, onLayoutModeChanged }) {
return (
<div className="layout-selector">
<button
onClick={() => {
onLayoutModeChanged('list');
}}
className={mode === 'list' ? 'active' : ''}
>
<i className="fa fa-list" />
</button>
<button
onClick={() => {
onLayoutModeChanged('grid');
}}
className={mode === 'grid' ? 'active' : ''}
>
<i className="fa fa-th" />
</button>
</div>
);
}
import React from 'react';
import React, { PureComponent } from 'react';
import { connect } from 'react-redux';
import LayoutSelector from '../../core/components/LayoutSelector/LayoutSelector';
import { setLayoutMode, setPluginsSearchQuery } from './state/actions';
import { getPluginsSearchQuery, getLayoutMode } from './state/selectors';
export default function({ searchQuery, onQueryChange }) {
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={onQueryChange}
placeholder="Filter by name or type"
/>
<i className="gf-form-input-icon fa fa-search" />
</label>
export interface Props {
searchQuery: string;
layoutMode: string;
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 => 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>
<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);
......@@ -7,11 +7,12 @@ import PluginList from './PluginList';
import { NavModel, Plugin } from '../../types';
import { loadPlugins } from './state/actions';
import { getNavModel } from '../../core/selectors/navModel';
import { getPlugins } from './state/selectors';
import { getLayoutMode, getPlugins } from './state/selectors';
interface Props {
navModel: NavModel;
plugins: Plugin[];
layoutMode: string;
loadPlugins: typeof loadPlugins;
}
......@@ -25,14 +26,14 @@ export class PluginListPage extends PureComponent<Props> {
}
render() {
const { navModel, plugins } = this.props;
const { navModel, plugins, layoutMode } = this.props;
return (
<div>
<PageHeader model={navModel} />
<div className="page-container page-body">
<PluginActionBar searchQuery="" onQueryChange={() => {}} />
{plugins && <PluginList plugins={plugins} layout="grid" />}
{plugins && <PluginList plugins={plugins} layout={layoutMode} />}
</div>
</div>
);
......@@ -43,6 +44,7 @@ function mapStateToProps(state) {
return {
navModel: getNavModel(state.navIndex, 'plugins'),
plugins: getPlugins(state.plugins),
layoutMode: getLayoutMode(state.plugins),
};
}
......
......@@ -4,6 +4,8 @@ import { getBackendSrv } from '../../../core/services/backend_srv';
export enum ActionTypes {
LoadPlugins = 'LOAD_PLUGINS',
SetPluginsSearchQuery = 'SET_PLUGIN_SEARCH_QUERY',
SetLayoutMode = 'SET_LAYOUT_MODE',
}
export interface LoadPluginsAction {
......@@ -11,12 +13,32 @@ export interface LoadPluginsAction {
payload: Plugin[];
}
export const pluginsLoaded = (plugins: Plugin[]): LoadPluginsAction => ({
export interface SetPluginsSearchQueryAction {
type: ActionTypes.SetPluginsSearchQuery;
payload: string;
}
export interface SetLayoutModeAction {
type: ActionTypes.SetLayoutMode;
payload: string;
}
export const setLayoutMode = (mode: string): SetLayoutModeAction => ({
type: ActionTypes.SetLayoutMode,
payload: mode,
});
export const setPluginsSearchQuery = (query: string): SetPluginsSearchQueryAction => ({
type: ActionTypes.SetPluginsSearchQuery,
payload: query,
});
const pluginsLoaded = (plugins: Plugin[]): LoadPluginsAction => ({
type: ActionTypes.LoadPlugins,
payload: plugins,
});
export type Action = LoadPluginsAction;
export type Action = LoadPluginsAction | SetPluginsSearchQueryAction | SetLayoutModeAction;
type ThunkResult<R> = ThunkAction<R, StoreState, undefined, Action>;
......
import { Action, ActionTypes } from './actions';
import { Plugin, PluginsState } from 'app/types';
export const initialState: PluginsState = { plugins: [] as Plugin[] };
export const initialState: PluginsState = { plugins: [] as Plugin[], searchQuery: '', layoutMode: 'grid' };
export const pluginsReducer = (state = initialState, action: Action): PluginsState => {
switch (action.type) {
case ActionTypes.LoadPlugins:
return { ...state, plugins: action.payload };
case ActionTypes.SetPluginsSearchQuery:
return { ...state, searchQuery: action.payload };
case ActionTypes.SetLayoutMode:
return { ...state, layoutMode: action.payload };
}
return state;
};
......
export const getPlugins = state => state.plugins;
export const getPlugins = state => {
const regex = new RegExp(state.searchQuery, 'i');
return state.plugins.filter(item => {
return regex.test(item.name);
});
};
export const getPluginsSearchQuery = state => state.searchQuery;
export const getLayoutMode = state => state.layoutMode;
......@@ -46,4 +46,6 @@ export interface Plugin {
export interface PluginsState {
plugins: Plugin[];
searchQuery: string;
layoutMode: string;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment