mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
filter plugins and layout mode
This commit is contained in:
parent
e8cc0f3fff
commit
0b7576a1f9
24
public/app/core/components/LayoutSelector/LayoutSelector.tsx
Normal file
24
public/app/core/components/LayoutSelector/LayoutSelector.tsx
Normal file
@ -0,0 +1,24 @@
|
||||
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>
|
||||
);
|
||||
}
|
@ -1,24 +1,62 @@
|
||||
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>
|
||||
</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>
|
||||
);
|
||||
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>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
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>;
|
||||
|
||||
|
@ -1,12 +1,18 @@
|
||||
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;
|
||||
};
|
||||
|
@ -1 +1,10 @@
|
||||
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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user