From e8cc0f3fff88f12a9759cbc30efc158a636901d7 Mon Sep 17 00:00:00 2001 From: Peter Holmberg Date: Tue, 25 Sep 2018 14:53:55 +0200 Subject: [PATCH 1/9] render list --- .../app/features/plugins/PluginActionBar.tsx | 24 +++++++++ public/app/features/plugins/PluginList.tsx | 21 ++++++++ .../app/features/plugins/PluginListItem.tsx | 30 +++++++++++ .../app/features/plugins/PluginListPage.tsx | 53 +++++++++++++++++++ public/app/features/plugins/state/actions.ts | 28 ++++++++++ public/app/features/plugins/state/reducers.ts | 16 ++++++ .../app/features/plugins/state/selectors.ts | 1 + public/app/routes/routes.ts | 8 +-- public/app/store/configureStore.ts | 2 + public/app/types/index.ts | 5 +- public/app/types/plugins.ts | 30 +++++++++++ 11 files changed, 214 insertions(+), 4 deletions(-) create mode 100644 public/app/features/plugins/PluginActionBar.tsx create mode 100644 public/app/features/plugins/PluginList.tsx create mode 100644 public/app/features/plugins/PluginListItem.tsx create mode 100644 public/app/features/plugins/PluginListPage.tsx create mode 100644 public/app/features/plugins/state/actions.ts create mode 100644 public/app/features/plugins/state/reducers.ts create mode 100644 public/app/features/plugins/state/selectors.ts diff --git a/public/app/features/plugins/PluginActionBar.tsx b/public/app/features/plugins/PluginActionBar.tsx new file mode 100644 index 00000000000..e420bc3eca6 --- /dev/null +++ b/public/app/features/plugins/PluginActionBar.tsx @@ -0,0 +1,24 @@ +import React from 'react'; + +export default function({ searchQuery, onQueryChange }) { + return ( +
+
+ +
+
+ + Find more plugins on Grafana.com + +
+ ); +} diff --git a/public/app/features/plugins/PluginList.tsx b/public/app/features/plugins/PluginList.tsx new file mode 100644 index 00000000000..02d7dac0dce --- /dev/null +++ b/public/app/features/plugins/PluginList.tsx @@ -0,0 +1,21 @@ +import React from 'react'; +import classNames from 'classnames/bind'; +import PluginListItem from './PluginListItem'; + +export default function PluginList({ plugins, layout }) { + const listStyle = classNames({ + 'card-section': true, + 'card-list-layout-grid': layout === 'grid', + 'card-list-layout-list': layout === 'list', + }); + + return ( +
+
    + {plugins.map((plugin, index) => { + return ; + })} +
+
+ ); +} diff --git a/public/app/features/plugins/PluginListItem.tsx b/public/app/features/plugins/PluginListItem.tsx new file mode 100644 index 00000000000..a143625459a --- /dev/null +++ b/public/app/features/plugins/PluginListItem.tsx @@ -0,0 +1,30 @@ +import React from 'react'; + +export default function PluginListItem({ plugin }) { + return ( +
  • + +
    +
    + + {plugin.type} +
    + {plugin.hasUpdate && ( +
    + Update available! +
    + )} +
    +
    +
    + +
    +
    +
    {plugin.name}
    +
    {`By ${plugin.info.author.name}`}
    +
    +
    +
    +
  • + ); +} diff --git a/public/app/features/plugins/PluginListPage.tsx b/public/app/features/plugins/PluginListPage.tsx new file mode 100644 index 00000000000..73837cfe75f --- /dev/null +++ b/public/app/features/plugins/PluginListPage.tsx @@ -0,0 +1,53 @@ +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 PluginList from './PluginList'; +import { NavModel, Plugin } from '../../types'; +import { loadPlugins } from './state/actions'; +import { getNavModel } from '../../core/selectors/navModel'; +import { getPlugins } from './state/selectors'; + +interface Props { + navModel: NavModel; + plugins: Plugin[]; + loadPlugins: typeof loadPlugins; +} + +export class PluginListPage extends PureComponent { + componentDidMount() { + this.fetchPlugins(); + } + + async fetchPlugins() { + await this.props.loadPlugins(); + } + + render() { + const { navModel, plugins } = this.props; + + return ( +
    + +
    + {}} /> + {plugins && } +
    +
    + ); + } +} + +function mapStateToProps(state) { + return { + navModel: getNavModel(state.navIndex, 'plugins'), + plugins: getPlugins(state.plugins), + }; +} + +const mapDispatchToProps = { + loadPlugins, +}; + +export default hot(module)(connect(mapStateToProps, mapDispatchToProps)(PluginListPage)); diff --git a/public/app/features/plugins/state/actions.ts b/public/app/features/plugins/state/actions.ts new file mode 100644 index 00000000000..d044a7ba56f --- /dev/null +++ b/public/app/features/plugins/state/actions.ts @@ -0,0 +1,28 @@ +import { Plugin, StoreState } from 'app/types'; +import { ThunkAction } from 'redux-thunk'; +import { getBackendSrv } from '../../../core/services/backend_srv'; + +export enum ActionTypes { + LoadPlugins = 'LOAD_PLUGINS', +} + +export interface LoadPluginsAction { + type: ActionTypes.LoadPlugins; + payload: Plugin[]; +} + +export const pluginsLoaded = (plugins: Plugin[]): LoadPluginsAction => ({ + type: ActionTypes.LoadPlugins, + payload: plugins, +}); + +export type Action = LoadPluginsAction; + +type ThunkResult = ThunkAction; + +export function loadPlugins(): ThunkResult { + return async dispatch => { + const result = await getBackendSrv().get('api/plugins', { embedded: 0 }); + dispatch(pluginsLoaded(result)); + }; +} diff --git a/public/app/features/plugins/state/reducers.ts b/public/app/features/plugins/state/reducers.ts new file mode 100644 index 00000000000..af4089220b6 --- /dev/null +++ b/public/app/features/plugins/state/reducers.ts @@ -0,0 +1,16 @@ +import { Action, ActionTypes } from './actions'; +import { Plugin, PluginsState } from 'app/types'; + +export const initialState: PluginsState = { plugins: [] as Plugin[] }; + +export const pluginsReducer = (state = initialState, action: Action): PluginsState => { + switch (action.type) { + case ActionTypes.LoadPlugins: + return { ...state, plugins: action.payload }; + } + return state; +}; + +export default { + plugins: pluginsReducer, +}; diff --git a/public/app/features/plugins/state/selectors.ts b/public/app/features/plugins/state/selectors.ts new file mode 100644 index 00000000000..d436e9fa016 --- /dev/null +++ b/public/app/features/plugins/state/selectors.ts @@ -0,0 +1 @@ +export const getPlugins = state => state.plugins; diff --git a/public/app/routes/routes.ts b/public/app/routes/routes.ts index 015b4ae0b51..e4662c77367 100644 --- a/public/app/routes/routes.ts +++ b/public/app/routes/routes.ts @@ -5,6 +5,7 @@ import ServerStats from 'app/features/admin/ServerStats'; import AlertRuleList from 'app/features/alerting/AlertRuleList'; import TeamPages from 'app/features/teams/TeamPages'; import TeamList from 'app/features/teams/TeamList'; +import PluginListPage from 'app/features/plugins/PluginListPage'; import FolderSettingsPage from 'app/features/folders/FolderSettingsPage'; import FolderPermissions from 'app/features/folders/FolderPermissions'; @@ -245,9 +246,10 @@ export function setupAngularRoutes($routeProvider, $locationProvider) { controllerAs: 'ctrl', }) .when('/plugins', { - templateUrl: 'public/app/features/plugins/partials/plugin_list.html', - controller: 'PluginListCtrl', - controllerAs: 'ctrl', + template: '', + resolve: { + component: () => PluginListPage, + }, }) .when('/plugins/:pluginId/edit', { templateUrl: 'public/app/features/plugins/partials/plugin_edit.html', diff --git a/public/app/store/configureStore.ts b/public/app/store/configureStore.ts index 8f6cf25043d..08d3d5bede0 100644 --- a/public/app/store/configureStore.ts +++ b/public/app/store/configureStore.ts @@ -6,6 +6,7 @@ import alertingReducers from 'app/features/alerting/state/reducers'; import teamsReducers from 'app/features/teams/state/reducers'; import foldersReducers from 'app/features/folders/state/reducers'; import dashboardReducers from 'app/features/dashboard/state/reducers'; +import pluginReducers from 'app/features/plugins/state/reducers'; const rootReducer = combineReducers({ ...sharedReducers, @@ -13,6 +14,7 @@ const rootReducer = combineReducers({ ...teamsReducers, ...foldersReducers, ...dashboardReducers, + ...pluginReducers, }); export let store; diff --git a/public/app/types/index.ts b/public/app/types/index.ts index 778a1b21b55..4ec5c6f02cc 100644 --- a/public/app/types/index.ts +++ b/public/app/types/index.ts @@ -6,7 +6,7 @@ import { FolderDTO, FolderState, FolderInfo } from './folders'; import { DashboardState } from './dashboard'; import { DashboardAcl, OrgRole, PermissionLevel } from './acl'; import { DataSource } from './datasources'; -import { PluginMeta } from './plugins'; +import { PluginMeta, Plugin, PluginInfo, PluginsState } from './plugins'; export { Team, @@ -33,6 +33,9 @@ export { PermissionLevel, DataSource, PluginMeta, + PluginInfo, + Plugin, + PluginsState, }; export interface StoreState { diff --git a/public/app/types/plugins.ts b/public/app/types/plugins.ts index d26085f8e73..e1594296acb 100644 --- a/public/app/types/plugins.ts +++ b/public/app/types/plugins.ts @@ -17,3 +17,33 @@ export interface PluginMetaInfo { small: string; }; } + +export interface PluginInfo { + author: { + name: string; + url: string; + }; + description: string; + links: string[]; + logos: { small: string; large: string }; + screenshots: string; + updated: string; + version: string; +} + +export interface Plugin { + defaultNavUrl: string; + enabled: boolean; + hasUpdate: boolean; + id: string; + info: PluginInfo; + latestVersion: string; + name: string; + pinned: boolean; + state: string; + type: string; +} + +export interface PluginsState { + plugins: Plugin[]; +} From 0b7576a1f92992e87fb90ef6d519c676a81d5236 Mon Sep 17 00:00:00 2001 From: Peter Holmberg Date: Tue, 25 Sep 2018 16:21:52 +0200 Subject: [PATCH 2/9] filter plugins and layout mode --- .../LayoutSelector/LayoutSelector.tsx | 24 ++++++ .../app/features/plugins/PluginActionBar.tsx | 82 ++++++++++++++----- .../app/features/plugins/PluginListPage.tsx | 8 +- public/app/features/plugins/state/actions.ts | 26 +++++- public/app/features/plugins/state/reducers.ts | 8 +- .../app/features/plugins/state/selectors.ts | 11 ++- public/app/types/plugins.ts | 2 + 7 files changed, 132 insertions(+), 29 deletions(-) create mode 100644 public/app/core/components/LayoutSelector/LayoutSelector.tsx diff --git a/public/app/core/components/LayoutSelector/LayoutSelector.tsx b/public/app/core/components/LayoutSelector/LayoutSelector.tsx new file mode 100644 index 00000000000..85322dc9da0 --- /dev/null +++ b/public/app/core/components/LayoutSelector/LayoutSelector.tsx @@ -0,0 +1,24 @@ +import React from 'react'; + +export default function LayoutSelector({ mode, onLayoutModeChanged }) { + return ( +
    + + +
    + ); +} diff --git a/public/app/features/plugins/PluginActionBar.tsx b/public/app/features/plugins/PluginActionBar.tsx index e420bc3eca6..12b1353e9dd 100644 --- a/public/app/features/plugins/PluginActionBar.tsx +++ b/public/app/features/plugins/PluginActionBar.tsx @@ -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 ( -
    -
    - -
    - - ); +export interface Props { + searchQuery: string; + layoutMode: string; + setLayoutMode: typeof setLayoutMode; + setPluginsSearchQuery: typeof setPluginsSearchQuery; } + +export class PluginActionBar extends PureComponent { + onSearchQueryChange = event => { + this.props.setPluginsSearchQuery(event.target.value); + }; + + render() { + const { searchQuery, layoutMode, setLayoutMode } = this.props; + + return ( +
    +
    + + setLayoutMode(mode)} /> +
    + + ); + } +} + +function mapStateToProps(state) { + return { + searchQuery: getPluginsSearchQuery(state.plugins), + layoutMode: getLayoutMode(state.plugins), + }; +} + +const mapDispatchToProps = { + setPluginsSearchQuery, + setLayoutMode, +}; + +export default connect(mapStateToProps, mapDispatchToProps)(PluginActionBar); diff --git a/public/app/features/plugins/PluginListPage.tsx b/public/app/features/plugins/PluginListPage.tsx index 73837cfe75f..a2b0348aefd 100644 --- a/public/app/features/plugins/PluginListPage.tsx +++ b/public/app/features/plugins/PluginListPage.tsx @@ -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 { } render() { - const { navModel, plugins } = this.props; + const { navModel, plugins, layoutMode } = this.props; return (
    {}} /> - {plugins && } + {plugins && }
    ); @@ -43,6 +44,7 @@ function mapStateToProps(state) { return { navModel: getNavModel(state.navIndex, 'plugins'), plugins: getPlugins(state.plugins), + layoutMode: getLayoutMode(state.plugins), }; } diff --git a/public/app/features/plugins/state/actions.ts b/public/app/features/plugins/state/actions.ts index d044a7ba56f..b842037ffc7 100644 --- a/public/app/features/plugins/state/actions.ts +++ b/public/app/features/plugins/state/actions.ts @@ -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 = ThunkAction; diff --git a/public/app/features/plugins/state/reducers.ts b/public/app/features/plugins/state/reducers.ts index af4089220b6..aadf78afe5e 100644 --- a/public/app/features/plugins/state/reducers.ts +++ b/public/app/features/plugins/state/reducers.ts @@ -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; }; diff --git a/public/app/features/plugins/state/selectors.ts b/public/app/features/plugins/state/selectors.ts index d436e9fa016..80c74649a4b 100644 --- a/public/app/features/plugins/state/selectors.ts +++ b/public/app/features/plugins/state/selectors.ts @@ -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; diff --git a/public/app/types/plugins.ts b/public/app/types/plugins.ts index e1594296acb..25c5b13153e 100644 --- a/public/app/types/plugins.ts +++ b/public/app/types/plugins.ts @@ -46,4 +46,6 @@ export interface Plugin { export interface PluginsState { plugins: Plugin[]; + searchQuery: string; + layoutMode: string; } From 64eace96c0a3b62895525be1ce4cd59897bfb7c0 Mon Sep 17 00:00:00 2001 From: Peter Holmberg Date: Tue, 25 Sep 2018 16:50:13 +0200 Subject: [PATCH 3/9] first test --- .../features/plugins/PluginListPage.test.tsx | 31 +++++++++++++++++++ .../app/features/plugins/PluginListPage.tsx | 2 +- .../PluginListPage.test.tsx.snap | 21 +++++++++++++ 3 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 public/app/features/plugins/PluginListPage.test.tsx create mode 100644 public/app/features/plugins/__snapshots__/PluginListPage.test.tsx.snap diff --git a/public/app/features/plugins/PluginListPage.test.tsx b/public/app/features/plugins/PluginListPage.test.tsx new file mode 100644 index 00000000000..830d1176eae --- /dev/null +++ b/public/app/features/plugins/PluginListPage.test.tsx @@ -0,0 +1,31 @@ +import React from 'react'; +import { shallow } from 'enzyme'; +import { PluginListPage, Props } from './PluginListPage'; +import { NavModel, Plugin } from '../../types'; + +const setup = (propOverrides?: object) => { + const props: Props = { + navModel: {} as NavModel, + plugins: [] as Plugin[], + layoutMode: 'grid', + loadPlugins: jest.fn(), + }; + + Object.assign(props, propOverrides); + + const wrapper = shallow(); + const instance = wrapper.instance() as PluginListPage; + + return { + wrapper, + instance, + }; +}; + +describe('Render', () => { + it('should render component', () => { + const { wrapper } = setup(); + + expect(wrapper).toMatchSnapshot(); + }); +}); diff --git a/public/app/features/plugins/PluginListPage.tsx b/public/app/features/plugins/PluginListPage.tsx index a2b0348aefd..358eb4a7887 100644 --- a/public/app/features/plugins/PluginListPage.tsx +++ b/public/app/features/plugins/PluginListPage.tsx @@ -9,7 +9,7 @@ import { loadPlugins } from './state/actions'; import { getNavModel } from '../../core/selectors/navModel'; import { getLayoutMode, getPlugins } from './state/selectors'; -interface Props { +export interface Props { navModel: NavModel; plugins: Plugin[]; layoutMode: string; diff --git a/public/app/features/plugins/__snapshots__/PluginListPage.test.tsx.snap b/public/app/features/plugins/__snapshots__/PluginListPage.test.tsx.snap new file mode 100644 index 00000000000..cb8c79bbcee --- /dev/null +++ b/public/app/features/plugins/__snapshots__/PluginListPage.test.tsx.snap @@ -0,0 +1,21 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Render should render component 1`] = ` +
    + +
    + + +
    +
    +`; From 70c3e1f3bcae133e05463cbdaeb71b4dd1206d3d Mon Sep 17 00:00:00 2001 From: Peter Holmberg Date: Wed, 26 Sep 2018 15:12:06 +0200 Subject: [PATCH 4/9] tests --- .../features/plugins/PluginActionBar.test.tsx | 30 +++ .../app/features/plugins/PluginList.test.tsx | 24 ++ .../features/plugins/PluginListItem.test.tsx | 33 +++ .../app/features/plugins/PluginListPage.tsx | 2 +- .../features/plugins/__mocks__/pluginMocks.ts | 59 +++++ .../PluginActionBar.test.tsx.snap | 40 ++++ .../__snapshots__/PluginList.test.tsx.snap | 210 ++++++++++++++++++ .../PluginListItem.test.tsx.snap | 106 +++++++++ .../PluginListPage.test.tsx.snap | 5 +- .../features/plugins/state/selectors.test.ts | 31 +++ .../app/features/plugins/state/selectors.ts | 2 +- 11 files changed, 536 insertions(+), 6 deletions(-) create mode 100644 public/app/features/plugins/PluginActionBar.test.tsx create mode 100644 public/app/features/plugins/PluginList.test.tsx create mode 100644 public/app/features/plugins/PluginListItem.test.tsx create mode 100644 public/app/features/plugins/__mocks__/pluginMocks.ts create mode 100644 public/app/features/plugins/__snapshots__/PluginActionBar.test.tsx.snap create mode 100644 public/app/features/plugins/__snapshots__/PluginList.test.tsx.snap create mode 100644 public/app/features/plugins/__snapshots__/PluginListItem.test.tsx.snap create mode 100644 public/app/features/plugins/state/selectors.test.ts diff --git a/public/app/features/plugins/PluginActionBar.test.tsx b/public/app/features/plugins/PluginActionBar.test.tsx new file mode 100644 index 00000000000..c761b37d9ea --- /dev/null +++ b/public/app/features/plugins/PluginActionBar.test.tsx @@ -0,0 +1,30 @@ +import React from 'react'; +import { shallow } from 'enzyme'; +import { PluginActionBar, Props } from './PluginActionBar'; + +const setup = (propOverrides?: object) => { + const props: Props = { + searchQuery: '', + layoutMode: 'grid', + setLayoutMode: jest.fn(), + setPluginsSearchQuery: jest.fn(), + }; + + Object.assign(props, propOverrides); + + const wrapper = shallow(); + const instance = wrapper.instance() as PluginActionBar; + + return { + wrapper, + instance, + }; +}; + +describe('Render', () => { + it('should render component', () => { + const { wrapper } = setup(); + + expect(wrapper).toMatchSnapshot(); + }); +}); diff --git a/public/app/features/plugins/PluginList.test.tsx b/public/app/features/plugins/PluginList.test.tsx new file mode 100644 index 00000000000..74f3ef441eb --- /dev/null +++ b/public/app/features/plugins/PluginList.test.tsx @@ -0,0 +1,24 @@ +import React from 'react'; +import { shallow } from 'enzyme'; +import PluginList from './PluginList'; +import { getMockPlugins } from './__mocks__/pluginMocks'; + +const setup = (propOverrides?: object) => { + const props = Object.assign( + { + plugins: getMockPlugins(5), + layout: 'grid', + }, + propOverrides + ); + + return shallow(); +}; + +describe('Render', () => { + it('should render component', () => { + const wrapper = setup(); + + expect(wrapper).toMatchSnapshot(); + }); +}); diff --git a/public/app/features/plugins/PluginListItem.test.tsx b/public/app/features/plugins/PluginListItem.test.tsx new file mode 100644 index 00000000000..175911c5e05 --- /dev/null +++ b/public/app/features/plugins/PluginListItem.test.tsx @@ -0,0 +1,33 @@ +import React from 'react'; +import { shallow } from 'enzyme'; +import PluginListItem from './PluginListItem'; +import { getMockPlugin } from './__mocks__/pluginMocks'; + +const setup = (propOverrides?: object) => { + const props = Object.assign( + { + plugin: getMockPlugin(), + }, + propOverrides + ); + + return shallow(); +}; + +describe('Render', () => { + it('should render component', () => { + const wrapper = setup(); + + expect(wrapper).toMatchSnapshot(); + }); + + it('should render has plugin section', () => { + const mockPlugin = getMockPlugin(); + mockPlugin.hasUpdate = true; + const wrapper = setup({ + plugin: mockPlugin, + }); + + expect(wrapper).toMatchSnapshot(); + }); +}); diff --git a/public/app/features/plugins/PluginListPage.tsx b/public/app/features/plugins/PluginListPage.tsx index 358eb4a7887..5a467881d94 100644 --- a/public/app/features/plugins/PluginListPage.tsx +++ b/public/app/features/plugins/PluginListPage.tsx @@ -32,7 +32,7 @@ export class PluginListPage extends PureComponent {
    - {}} /> + {plugins && }
    diff --git a/public/app/features/plugins/__mocks__/pluginMocks.ts b/public/app/features/plugins/__mocks__/pluginMocks.ts new file mode 100644 index 00000000000..d8dd67d5b61 --- /dev/null +++ b/public/app/features/plugins/__mocks__/pluginMocks.ts @@ -0,0 +1,59 @@ +import { Plugin } from 'app/types'; + +export const getMockPlugins = (amount: number): Plugin[] => { + const plugins = []; + + for (let i = 0; i <= amount; i++) { + plugins.push({ + defaultNavUrl: 'some/url', + enabled: false, + hasUpdate: false, + id: `${i}`, + info: { + author: { + name: 'Grafana Labs', + url: 'url/to/GrafanaLabs', + }, + description: 'pretty decent plugin', + links: ['one link'], + logos: { small: 'small/logo', large: 'large/logo' }, + screenshots: `screenshot/${i}`, + updated: '2018-09-26', + version: '1', + }, + latestVersion: `1.${i}`, + name: `pretty cool plugin-${i}`, + pinned: false, + state: '', + type: '', + }); + } + + return plugins; +}; + +export const getMockPlugin = () => { + return { + defaultNavUrl: 'some/url', + enabled: false, + hasUpdate: false, + id: '1', + info: { + author: { + name: 'Grafana Labs', + url: 'url/to/GrafanaLabs', + }, + description: 'pretty decent plugin', + links: ['one link'], + logos: { small: 'small/logo', large: 'large/logo' }, + screenshots: 'screenshot/1', + updated: '2018-09-26', + version: '1', + }, + latestVersion: '1', + name: 'pretty cool plugin 1', + pinned: false, + state: '', + type: '', + }; +}; diff --git a/public/app/features/plugins/__snapshots__/PluginActionBar.test.tsx.snap b/public/app/features/plugins/__snapshots__/PluginActionBar.test.tsx.snap new file mode 100644 index 00000000000..30cb53cea27 --- /dev/null +++ b/public/app/features/plugins/__snapshots__/PluginActionBar.test.tsx.snap @@ -0,0 +1,40 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Render should render component 1`] = ` +
    +
    + + +
    + +`; diff --git a/public/app/features/plugins/__snapshots__/PluginList.test.tsx.snap b/public/app/features/plugins/__snapshots__/PluginList.test.tsx.snap new file mode 100644 index 00000000000..176304b7b11 --- /dev/null +++ b/public/app/features/plugins/__snapshots__/PluginList.test.tsx.snap @@ -0,0 +1,210 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Render should render component 1`] = ` +
    +
      + + + + + + +
    +
    +`; diff --git a/public/app/features/plugins/__snapshots__/PluginListItem.test.tsx.snap b/public/app/features/plugins/__snapshots__/PluginListItem.test.tsx.snap new file mode 100644 index 00000000000..fc0cc68c522 --- /dev/null +++ b/public/app/features/plugins/__snapshots__/PluginListItem.test.tsx.snap @@ -0,0 +1,106 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Render should render component 1`] = ` +
  • + +
    +
    + +
    +
    +
    +
    + +
    +
    +
    + pretty cool plugin 1 +
    +
    + By Grafana Labs +
    +
    +
    +
    +
  • +`; + +exports[`Render should render has plugin section 1`] = ` +
  • + +
    +
    + +
    +
    + + Update available! + +
    +
    +
    +
    + +
    +
    +
    + pretty cool plugin 1 +
    +
    + By Grafana Labs +
    +
    +
    +
    +
  • +`; diff --git a/public/app/features/plugins/__snapshots__/PluginListPage.test.tsx.snap b/public/app/features/plugins/__snapshots__/PluginListPage.test.tsx.snap index cb8c79bbcee..9c428b54ca0 100644 --- a/public/app/features/plugins/__snapshots__/PluginListPage.test.tsx.snap +++ b/public/app/features/plugins/__snapshots__/PluginListPage.test.tsx.snap @@ -8,10 +8,7 @@ exports[`Render should render component 1`] = `
    - + { + const mockState = initialState; + + it('should return search query', () => { + mockState.searchQuery = 'test'; + const query = getPluginsSearchQuery(mockState); + + expect(query).toEqual(mockState.searchQuery); + }); + + it('should return plugins', () => { + mockState.plugins = getMockPlugins(5); + mockState.searchQuery = ''; + + const plugins = getPlugins(mockState); + + expect(plugins).toEqual(mockState.plugins); + }); + + it('should filter plugins', () => { + mockState.searchQuery = 'plugin-1'; + + const plugins = getPlugins(mockState); + + expect(plugins.length).toEqual(1); + }); +}); diff --git a/public/app/features/plugins/state/selectors.ts b/public/app/features/plugins/state/selectors.ts index 80c74649a4b..e1d16462527 100644 --- a/public/app/features/plugins/state/selectors.ts +++ b/public/app/features/plugins/state/selectors.ts @@ -2,7 +2,7 @@ export const getPlugins = state => { const regex = new RegExp(state.searchQuery, 'i'); return state.plugins.filter(item => { - return regex.test(item.name); + return regex.test(item.name) || regex.test(item.info.author.name) || regex.test(item.info.description); }); }; From 1e2c06083a3228864dabf7f7e5308718d41d00fb Mon Sep 17 00:00:00 2001 From: Peter Holmberg Date: Thu, 27 Sep 2018 12:15:41 +0200 Subject: [PATCH 5/9] rewrote to use react.sfc --- .../LayoutSelector/LayoutSelector.tsx | 29 ++++++++++++++----- .../features/plugins/PluginActionBar.test.tsx | 3 +- .../app/features/plugins/PluginActionBar.tsx | 6 ++-- .../app/features/plugins/PluginList.test.tsx | 3 +- public/app/features/plugins/PluginList.tsx | 21 ++++++++++---- .../app/features/plugins/PluginListItem.tsx | 15 ++++++++-- .../app/features/plugins/PluginListPage.tsx | 5 ++-- .../PluginListPage.test.tsx.snap | 2 +- public/app/features/plugins/state/actions.ts | 5 ++-- public/app/features/plugins/state/reducers.ts | 3 +- 10 files changed, 66 insertions(+), 26 deletions(-) diff --git a/public/app/core/components/LayoutSelector/LayoutSelector.tsx b/public/app/core/components/LayoutSelector/LayoutSelector.tsx index 85322dc9da0..d9e00102438 100644 --- a/public/app/core/components/LayoutSelector/LayoutSelector.tsx +++ b/public/app/core/components/LayoutSelector/LayoutSelector.tsx @@ -1,24 +1,39 @@ -import React from 'react'; +import React, { SFC } from 'react'; -export default function LayoutSelector({ mode, onLayoutModeChanged }) { +export type LayoutMode = LayoutModes.Grid | LayoutModes.List; + +export enum LayoutModes { + Grid = 'grid', + List = 'list', +} + +interface Props { + mode: LayoutMode; + onLayoutModeChanged: (mode: LayoutMode) => {}; +} + +const LayoutSelector: SFC = props => { + const { mode, onLayoutModeChanged } = props; return (
    ); -} +}; + +export default LayoutSelector; diff --git a/public/app/features/plugins/PluginActionBar.test.tsx b/public/app/features/plugins/PluginActionBar.test.tsx index c761b37d9ea..be3f37e89fa 100644 --- a/public/app/features/plugins/PluginActionBar.test.tsx +++ b/public/app/features/plugins/PluginActionBar.test.tsx @@ -1,11 +1,12 @@ 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: 'grid', + layoutMode: LayoutModes.Grid, setLayoutMode: jest.fn(), setPluginsSearchQuery: jest.fn(), }; diff --git a/public/app/features/plugins/PluginActionBar.tsx b/public/app/features/plugins/PluginActionBar.tsx index 12b1353e9dd..301b432ff5c 100644 --- a/public/app/features/plugins/PluginActionBar.tsx +++ b/public/app/features/plugins/PluginActionBar.tsx @@ -1,12 +1,12 @@ import React, { PureComponent } from 'react'; import { connect } from 'react-redux'; -import LayoutSelector from '../../core/components/LayoutSelector/LayoutSelector'; +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: string; + layoutMode: LayoutMode; setLayoutMode: typeof setLayoutMode; setPluginsSearchQuery: typeof setPluginsSearchQuery; } @@ -32,7 +32,7 @@ export class PluginActionBar extends PureComponent { /> - setLayoutMode(mode)} /> + setLayoutMode(mode)} />
    { const props = Object.assign( { plugins: getMockPlugins(5), - layout: 'grid', + layoutMode: LayoutModes.Grid, }, propOverrides ); diff --git a/public/app/features/plugins/PluginList.tsx b/public/app/features/plugins/PluginList.tsx index 02d7dac0dce..0074839e754 100644 --- a/public/app/features/plugins/PluginList.tsx +++ b/public/app/features/plugins/PluginList.tsx @@ -1,12 +1,21 @@ -import React from 'react'; +import React, { SFC } from 'react'; import classNames from 'classnames/bind'; import PluginListItem from './PluginListItem'; +import { Plugin } from 'app/types'; +import { LayoutMode, LayoutModes } from '../../core/components/LayoutSelector/LayoutSelector'; + +interface Props { + plugins: Plugin[]; + layoutMode: LayoutMode; +} + +const PluginList: SFC = props => { + const { plugins, layoutMode } = props; -export default function PluginList({ plugins, layout }) { const listStyle = classNames({ 'card-section': true, - 'card-list-layout-grid': layout === 'grid', - 'card-list-layout-list': layout === 'list', + 'card-list-layout-grid': layoutMode === LayoutModes.Grid, + 'card-list-layout-list': layoutMode === LayoutModes.List, }); return ( @@ -18,4 +27,6 @@ export default function PluginList({ plugins, layout }) { ); -} +}; + +export default PluginList; diff --git a/public/app/features/plugins/PluginListItem.tsx b/public/app/features/plugins/PluginListItem.tsx index a143625459a..05eac614fd5 100644 --- a/public/app/features/plugins/PluginListItem.tsx +++ b/public/app/features/plugins/PluginListItem.tsx @@ -1,6 +1,13 @@ -import React from 'react'; +import React, { SFC } from 'react'; +import { Plugin } from 'app/types'; + +interface Props { + plugin: Plugin; +} + +const PluginListItem: SFC = props => { + const { plugin } = props; -export default function PluginListItem({ plugin }) { return (
  • @@ -27,4 +34,6 @@ export default function PluginListItem({ plugin }) {
  • ); -} +}; + +export default PluginListItem; diff --git a/public/app/features/plugins/PluginListPage.tsx b/public/app/features/plugins/PluginListPage.tsx index 5a467881d94..de2968b126c 100644 --- a/public/app/features/plugins/PluginListPage.tsx +++ b/public/app/features/plugins/PluginListPage.tsx @@ -8,11 +8,12 @@ import { NavModel, Plugin } from '../../types'; import { loadPlugins } from './state/actions'; import { getNavModel } from '../../core/selectors/navModel'; import { getLayoutMode, getPlugins } from './state/selectors'; +import { LayoutMode } from '../../core/components/LayoutSelector/LayoutSelector'; export interface Props { navModel: NavModel; plugins: Plugin[]; - layoutMode: string; + layoutMode: LayoutMode; loadPlugins: typeof loadPlugins; } @@ -33,7 +34,7 @@ export class PluginListPage extends PureComponent {
    - {plugins && } + {plugins && }
    ); diff --git a/public/app/features/plugins/__snapshots__/PluginListPage.test.tsx.snap b/public/app/features/plugins/__snapshots__/PluginListPage.test.tsx.snap index 9c428b54ca0..74b23d8850a 100644 --- a/public/app/features/plugins/__snapshots__/PluginListPage.test.tsx.snap +++ b/public/app/features/plugins/__snapshots__/PluginListPage.test.tsx.snap @@ -10,7 +10,7 @@ exports[`Render should render component 1`] = ` >
    diff --git a/public/app/features/plugins/state/actions.ts b/public/app/features/plugins/state/actions.ts index b842037ffc7..24774c6061c 100644 --- a/public/app/features/plugins/state/actions.ts +++ b/public/app/features/plugins/state/actions.ts @@ -1,6 +1,7 @@ import { Plugin, StoreState } from 'app/types'; import { ThunkAction } from 'redux-thunk'; import { getBackendSrv } from '../../../core/services/backend_srv'; +import { LayoutMode } from '../../../core/components/LayoutSelector/LayoutSelector'; export enum ActionTypes { LoadPlugins = 'LOAD_PLUGINS', @@ -20,10 +21,10 @@ export interface SetPluginsSearchQueryAction { export interface SetLayoutModeAction { type: ActionTypes.SetLayoutMode; - payload: string; + payload: LayoutMode; } -export const setLayoutMode = (mode: string): SetLayoutModeAction => ({ +export const setLayoutMode = (mode: LayoutMode): SetLayoutModeAction => ({ type: ActionTypes.SetLayoutMode, payload: mode, }); diff --git a/public/app/features/plugins/state/reducers.ts b/public/app/features/plugins/state/reducers.ts index aadf78afe5e..af1badb8785 100644 --- a/public/app/features/plugins/state/reducers.ts +++ b/public/app/features/plugins/state/reducers.ts @@ -1,7 +1,8 @@ import { Action, ActionTypes } from './actions'; import { Plugin, PluginsState } from 'app/types'; +import { LayoutModes } from '../../../core/components/LayoutSelector/LayoutSelector'; -export const initialState: PluginsState = { plugins: [] as Plugin[], searchQuery: '', layoutMode: 'grid' }; +export const initialState: PluginsState = { plugins: [] as Plugin[], searchQuery: '', layoutMode: LayoutModes.Grid }; export const pluginsReducer = (state = initialState, action: Action): PluginsState => { switch (action.type) { From cabc4c4bfe2edc723ae6fa1f1aa925a78ec3a480 Mon Sep 17 00:00:00 2001 From: Peter Holmberg Date: Thu, 27 Sep 2018 14:19:36 +0200 Subject: [PATCH 6/9] fixing types --- .../app/features/plugins/PluginListPage.test.tsx | 3 ++- public/app/types/index.ts | 3 +-- public/app/types/plugins.ts | 14 +++++--------- 3 files changed, 8 insertions(+), 12 deletions(-) diff --git a/public/app/features/plugins/PluginListPage.test.tsx b/public/app/features/plugins/PluginListPage.test.tsx index 830d1176eae..452a89837c7 100644 --- a/public/app/features/plugins/PluginListPage.test.tsx +++ b/public/app/features/plugins/PluginListPage.test.tsx @@ -2,12 +2,13 @@ import React from 'react'; import { shallow } from 'enzyme'; import { PluginListPage, Props } from './PluginListPage'; import { NavModel, Plugin } from '../../types'; +import { LayoutModes } from '../../core/components/LayoutSelector/LayoutSelector'; const setup = (propOverrides?: object) => { const props: Props = { navModel: {} as NavModel, plugins: [] as Plugin[], - layoutMode: 'grid', + layoutMode: LayoutModes.Grid, loadPlugins: jest.fn(), }; diff --git a/public/app/types/index.ts b/public/app/types/index.ts index 4ec5c6f02cc..1dd11d73564 100644 --- a/public/app/types/index.ts +++ b/public/app/types/index.ts @@ -6,7 +6,7 @@ import { FolderDTO, FolderState, FolderInfo } from './folders'; import { DashboardState } from './dashboard'; import { DashboardAcl, OrgRole, PermissionLevel } from './acl'; import { DataSource } from './datasources'; -import { PluginMeta, Plugin, PluginInfo, PluginsState } from './plugins'; +import { PluginMeta, Plugin, PluginsState } from './plugins'; export { Team, @@ -33,7 +33,6 @@ export { PermissionLevel, DataSource, PluginMeta, - PluginInfo, Plugin, PluginsState, }; diff --git a/public/app/types/plugins.ts b/public/app/types/plugins.ts index 25c5b13153e..92bebfef8d4 100644 --- a/public/app/types/plugins.ts +++ b/public/app/types/plugins.ts @@ -12,20 +12,16 @@ export interface PluginInclude { } export interface PluginMetaInfo { - logos: { - large: string; - small: string; - }; -} - -export interface PluginInfo { author: { name: string; url: string; }; description: string; links: string[]; - logos: { small: string; large: string }; + logos: { + large: string; + small: string; + }; screenshots: string; updated: string; version: string; @@ -36,7 +32,7 @@ export interface Plugin { enabled: boolean; hasUpdate: boolean; id: string; - info: PluginInfo; + info: PluginMetaInfo; latestVersion: string; name: string; pinned: boolean; From fede5e6c74ddb94ec29c3f3e4562b376b1881ee1 Mon Sep 17 00:00:00 2001 From: Peter Holmberg Date: Thu, 27 Sep 2018 14:23:46 +0200 Subject: [PATCH 7/9] rename to pluginlistitem --- public/app/features/plugins/PluginList.tsx | 4 ++-- public/app/features/plugins/PluginListItem.tsx | 4 ++-- public/app/features/plugins/PluginListPage.test.tsx | 4 ++-- public/app/features/plugins/PluginListPage.tsx | 4 ++-- public/app/features/plugins/__mocks__/pluginMocks.ts | 4 ++-- public/app/features/plugins/state/actions.ts | 6 +++--- public/app/features/plugins/state/reducers.ts | 8 ++++++-- public/app/types/index.ts | 4 ++-- public/app/types/plugins.ts | 4 ++-- 9 files changed, 23 insertions(+), 19 deletions(-) diff --git a/public/app/features/plugins/PluginList.tsx b/public/app/features/plugins/PluginList.tsx index 0074839e754..f080b67f78d 100644 --- a/public/app/features/plugins/PluginList.tsx +++ b/public/app/features/plugins/PluginList.tsx @@ -1,11 +1,11 @@ import React, { SFC } from 'react'; import classNames from 'classnames/bind'; import PluginListItem from './PluginListItem'; -import { Plugin } from 'app/types'; +import { PluginListItem } from 'app/types'; import { LayoutMode, LayoutModes } from '../../core/components/LayoutSelector/LayoutSelector'; interface Props { - plugins: Plugin[]; + plugins: PluginListItem[]; layoutMode: LayoutMode; } diff --git a/public/app/features/plugins/PluginListItem.tsx b/public/app/features/plugins/PluginListItem.tsx index 05eac614fd5..2bfe401d5b3 100644 --- a/public/app/features/plugins/PluginListItem.tsx +++ b/public/app/features/plugins/PluginListItem.tsx @@ -1,8 +1,8 @@ import React, { SFC } from 'react'; -import { Plugin } from 'app/types'; +import { PluginListItem } from 'app/types'; interface Props { - plugin: Plugin; + plugin: PluginListItem; } const PluginListItem: SFC = props => { diff --git a/public/app/features/plugins/PluginListPage.test.tsx b/public/app/features/plugins/PluginListPage.test.tsx index 452a89837c7..866d63c9437 100644 --- a/public/app/features/plugins/PluginListPage.test.tsx +++ b/public/app/features/plugins/PluginListPage.test.tsx @@ -1,13 +1,13 @@ import React from 'react'; import { shallow } from 'enzyme'; import { PluginListPage, Props } from './PluginListPage'; -import { NavModel, Plugin } from '../../types'; +import { NavModel, PluginListItem } from '../../types'; import { LayoutModes } from '../../core/components/LayoutSelector/LayoutSelector'; const setup = (propOverrides?: object) => { const props: Props = { navModel: {} as NavModel, - plugins: [] as Plugin[], + plugins: [] as PluginListItem[], layoutMode: LayoutModes.Grid, loadPlugins: jest.fn(), }; diff --git a/public/app/features/plugins/PluginListPage.tsx b/public/app/features/plugins/PluginListPage.tsx index de2968b126c..4a330ece7f4 100644 --- a/public/app/features/plugins/PluginListPage.tsx +++ b/public/app/features/plugins/PluginListPage.tsx @@ -4,7 +4,7 @@ import { connect } from 'react-redux'; import PageHeader from '../../core/components/PageHeader/PageHeader'; import PluginActionBar from './PluginActionBar'; import PluginList from './PluginList'; -import { NavModel, Plugin } from '../../types'; +import { NavModel, PluginListItem } from '../../types'; import { loadPlugins } from './state/actions'; import { getNavModel } from '../../core/selectors/navModel'; import { getLayoutMode, getPlugins } from './state/selectors'; @@ -12,7 +12,7 @@ import { LayoutMode } from '../../core/components/LayoutSelector/LayoutSelector' export interface Props { navModel: NavModel; - plugins: Plugin[]; + plugins: PluginListItem[]; layoutMode: LayoutMode; loadPlugins: typeof loadPlugins; } diff --git a/public/app/features/plugins/__mocks__/pluginMocks.ts b/public/app/features/plugins/__mocks__/pluginMocks.ts index d8dd67d5b61..d34997d0ffa 100644 --- a/public/app/features/plugins/__mocks__/pluginMocks.ts +++ b/public/app/features/plugins/__mocks__/pluginMocks.ts @@ -1,6 +1,6 @@ -import { Plugin } from 'app/types'; +import { PluginListItem } from 'app/types'; -export const getMockPlugins = (amount: number): Plugin[] => { +export const getMockPlugins = (amount: number): PluginListItem[] => { const plugins = []; for (let i = 0; i <= amount; i++) { diff --git a/public/app/features/plugins/state/actions.ts b/public/app/features/plugins/state/actions.ts index 24774c6061c..51c3e5241d0 100644 --- a/public/app/features/plugins/state/actions.ts +++ b/public/app/features/plugins/state/actions.ts @@ -1,4 +1,4 @@ -import { Plugin, StoreState } from 'app/types'; +import { PluginListItem, StoreState } from 'app/types'; import { ThunkAction } from 'redux-thunk'; import { getBackendSrv } from '../../../core/services/backend_srv'; import { LayoutMode } from '../../../core/components/LayoutSelector/LayoutSelector'; @@ -11,7 +11,7 @@ export enum ActionTypes { export interface LoadPluginsAction { type: ActionTypes.LoadPlugins; - payload: Plugin[]; + payload: PluginListItem[]; } export interface SetPluginsSearchQueryAction { @@ -34,7 +34,7 @@ export const setPluginsSearchQuery = (query: string): SetPluginsSearchQueryActio payload: query, }); -const pluginsLoaded = (plugins: Plugin[]): LoadPluginsAction => ({ +const pluginsLoaded = (plugins: PluginListItem[]): LoadPluginsAction => ({ type: ActionTypes.LoadPlugins, payload: plugins, }); diff --git a/public/app/features/plugins/state/reducers.ts b/public/app/features/plugins/state/reducers.ts index af1badb8785..f643a80ce54 100644 --- a/public/app/features/plugins/state/reducers.ts +++ b/public/app/features/plugins/state/reducers.ts @@ -1,8 +1,12 @@ import { Action, ActionTypes } from './actions'; -import { Plugin, PluginsState } from 'app/types'; +import { PluginListItem, PluginsState } from 'app/types'; import { LayoutModes } from '../../../core/components/LayoutSelector/LayoutSelector'; -export const initialState: PluginsState = { plugins: [] as Plugin[], searchQuery: '', layoutMode: LayoutModes.Grid }; +export const initialState: PluginsState = { + plugins: [] as PluginListItem[], + searchQuery: '', + layoutMode: LayoutModes.Grid, +}; export const pluginsReducer = (state = initialState, action: Action): PluginsState => { switch (action.type) { diff --git a/public/app/types/index.ts b/public/app/types/index.ts index 1dd11d73564..33bcffc1790 100644 --- a/public/app/types/index.ts +++ b/public/app/types/index.ts @@ -6,7 +6,7 @@ import { FolderDTO, FolderState, FolderInfo } from './folders'; import { DashboardState } from './dashboard'; import { DashboardAcl, OrgRole, PermissionLevel } from './acl'; import { DataSource } from './datasources'; -import { PluginMeta, Plugin, PluginsState } from './plugins'; +import { PluginMeta, PluginListItem, PluginsState } from './plugins'; export { Team, @@ -33,7 +33,7 @@ export { PermissionLevel, DataSource, PluginMeta, - Plugin, + PluginListItem, PluginsState, }; diff --git a/public/app/types/plugins.ts b/public/app/types/plugins.ts index 92bebfef8d4..6dcb4cefe02 100644 --- a/public/app/types/plugins.ts +++ b/public/app/types/plugins.ts @@ -27,7 +27,7 @@ export interface PluginMetaInfo { version: string; } -export interface Plugin { +export interface PluginListItem { defaultNavUrl: string; enabled: boolean; hasUpdate: boolean; @@ -41,7 +41,7 @@ export interface Plugin { } export interface PluginsState { - plugins: Plugin[]; + plugins: PluginListItem[]; searchQuery: string; layoutMode: string; } From b899a0e1c188f4ffa4d652573e533c9e66a561b0 Mon Sep 17 00:00:00 2001 From: Peter Holmberg Date: Thu, 27 Sep 2018 14:45:36 +0200 Subject: [PATCH 8/9] revert rename --- public/app/features/plugins/PluginList.tsx | 2 +- public/app/features/plugins/PluginListItem.tsx | 4 ++-- public/app/features/plugins/PluginListPage.test.tsx | 4 ++-- public/app/features/plugins/PluginListPage.tsx | 4 ++-- public/app/features/plugins/__mocks__/pluginMocks.ts | 4 ++-- public/app/features/plugins/state/actions.ts | 6 +++--- public/app/features/plugins/state/reducers.ts | 4 ++-- public/app/types/index.ts | 4 ++-- public/app/types/plugins.ts | 4 ++-- 9 files changed, 18 insertions(+), 18 deletions(-) diff --git a/public/app/features/plugins/PluginList.tsx b/public/app/features/plugins/PluginList.tsx index f080b67f78d..2c47e755de3 100644 --- a/public/app/features/plugins/PluginList.tsx +++ b/public/app/features/plugins/PluginList.tsx @@ -1,7 +1,7 @@ import React, { SFC } from 'react'; import classNames from 'classnames/bind'; import PluginListItem from './PluginListItem'; -import { PluginListItem } from 'app/types'; +import { Plugin } from 'app/types'; import { LayoutMode, LayoutModes } from '../../core/components/LayoutSelector/LayoutSelector'; interface Props { diff --git a/public/app/features/plugins/PluginListItem.tsx b/public/app/features/plugins/PluginListItem.tsx index 2bfe401d5b3..05eac614fd5 100644 --- a/public/app/features/plugins/PluginListItem.tsx +++ b/public/app/features/plugins/PluginListItem.tsx @@ -1,8 +1,8 @@ import React, { SFC } from 'react'; -import { PluginListItem } from 'app/types'; +import { Plugin } from 'app/types'; interface Props { - plugin: PluginListItem; + plugin: Plugin; } const PluginListItem: SFC = props => { diff --git a/public/app/features/plugins/PluginListPage.test.tsx b/public/app/features/plugins/PluginListPage.test.tsx index 866d63c9437..452a89837c7 100644 --- a/public/app/features/plugins/PluginListPage.test.tsx +++ b/public/app/features/plugins/PluginListPage.test.tsx @@ -1,13 +1,13 @@ import React from 'react'; import { shallow } from 'enzyme'; import { PluginListPage, Props } from './PluginListPage'; -import { NavModel, PluginListItem } from '../../types'; +import { NavModel, Plugin } from '../../types'; import { LayoutModes } from '../../core/components/LayoutSelector/LayoutSelector'; const setup = (propOverrides?: object) => { const props: Props = { navModel: {} as NavModel, - plugins: [] as PluginListItem[], + plugins: [] as Plugin[], layoutMode: LayoutModes.Grid, loadPlugins: jest.fn(), }; diff --git a/public/app/features/plugins/PluginListPage.tsx b/public/app/features/plugins/PluginListPage.tsx index 4a330ece7f4..de2968b126c 100644 --- a/public/app/features/plugins/PluginListPage.tsx +++ b/public/app/features/plugins/PluginListPage.tsx @@ -4,7 +4,7 @@ import { connect } from 'react-redux'; import PageHeader from '../../core/components/PageHeader/PageHeader'; import PluginActionBar from './PluginActionBar'; import PluginList from './PluginList'; -import { NavModel, PluginListItem } from '../../types'; +import { NavModel, Plugin } from '../../types'; import { loadPlugins } from './state/actions'; import { getNavModel } from '../../core/selectors/navModel'; import { getLayoutMode, getPlugins } from './state/selectors'; @@ -12,7 +12,7 @@ import { LayoutMode } from '../../core/components/LayoutSelector/LayoutSelector' export interface Props { navModel: NavModel; - plugins: PluginListItem[]; + plugins: Plugin[]; layoutMode: LayoutMode; loadPlugins: typeof loadPlugins; } diff --git a/public/app/features/plugins/__mocks__/pluginMocks.ts b/public/app/features/plugins/__mocks__/pluginMocks.ts index d34997d0ffa..d8dd67d5b61 100644 --- a/public/app/features/plugins/__mocks__/pluginMocks.ts +++ b/public/app/features/plugins/__mocks__/pluginMocks.ts @@ -1,6 +1,6 @@ -import { PluginListItem } from 'app/types'; +import { Plugin } from 'app/types'; -export const getMockPlugins = (amount: number): PluginListItem[] => { +export const getMockPlugins = (amount: number): Plugin[] => { const plugins = []; for (let i = 0; i <= amount; i++) { diff --git a/public/app/features/plugins/state/actions.ts b/public/app/features/plugins/state/actions.ts index 51c3e5241d0..24774c6061c 100644 --- a/public/app/features/plugins/state/actions.ts +++ b/public/app/features/plugins/state/actions.ts @@ -1,4 +1,4 @@ -import { PluginListItem, StoreState } from 'app/types'; +import { Plugin, StoreState } from 'app/types'; import { ThunkAction } from 'redux-thunk'; import { getBackendSrv } from '../../../core/services/backend_srv'; import { LayoutMode } from '../../../core/components/LayoutSelector/LayoutSelector'; @@ -11,7 +11,7 @@ export enum ActionTypes { export interface LoadPluginsAction { type: ActionTypes.LoadPlugins; - payload: PluginListItem[]; + payload: Plugin[]; } export interface SetPluginsSearchQueryAction { @@ -34,7 +34,7 @@ export const setPluginsSearchQuery = (query: string): SetPluginsSearchQueryActio payload: query, }); -const pluginsLoaded = (plugins: PluginListItem[]): LoadPluginsAction => ({ +const pluginsLoaded = (plugins: Plugin[]): LoadPluginsAction => ({ type: ActionTypes.LoadPlugins, payload: plugins, }); diff --git a/public/app/features/plugins/state/reducers.ts b/public/app/features/plugins/state/reducers.ts index f643a80ce54..1ca2880282c 100644 --- a/public/app/features/plugins/state/reducers.ts +++ b/public/app/features/plugins/state/reducers.ts @@ -1,9 +1,9 @@ import { Action, ActionTypes } from './actions'; -import { PluginListItem, PluginsState } from 'app/types'; +import { Plugin, PluginsState } from 'app/types'; import { LayoutModes } from '../../../core/components/LayoutSelector/LayoutSelector'; export const initialState: PluginsState = { - plugins: [] as PluginListItem[], + plugins: [] as Plugin[], searchQuery: '', layoutMode: LayoutModes.Grid, }; diff --git a/public/app/types/index.ts b/public/app/types/index.ts index 33bcffc1790..1dd11d73564 100644 --- a/public/app/types/index.ts +++ b/public/app/types/index.ts @@ -6,7 +6,7 @@ import { FolderDTO, FolderState, FolderInfo } from './folders'; import { DashboardState } from './dashboard'; import { DashboardAcl, OrgRole, PermissionLevel } from './acl'; import { DataSource } from './datasources'; -import { PluginMeta, PluginListItem, PluginsState } from './plugins'; +import { PluginMeta, Plugin, PluginsState } from './plugins'; export { Team, @@ -33,7 +33,7 @@ export { PermissionLevel, DataSource, PluginMeta, - PluginListItem, + Plugin, PluginsState, }; diff --git a/public/app/types/plugins.ts b/public/app/types/plugins.ts index 6dcb4cefe02..92bebfef8d4 100644 --- a/public/app/types/plugins.ts +++ b/public/app/types/plugins.ts @@ -27,7 +27,7 @@ export interface PluginMetaInfo { version: string; } -export interface PluginListItem { +export interface Plugin { defaultNavUrl: string; enabled: boolean; hasUpdate: boolean; @@ -41,7 +41,7 @@ export interface PluginListItem { } export interface PluginsState { - plugins: PluginListItem[]; + plugins: Plugin[]; searchQuery: string; layoutMode: string; } From 11ee65d35a6c9fbab094bb950598ae3a3a779b87 Mon Sep 17 00:00:00 2001 From: Peter Holmberg Date: Thu, 27 Sep 2018 14:51:00 +0200 Subject: [PATCH 9/9] deletez --- public/app/features/plugins/PluginList.tsx | 2 +- public/app/features/plugins/all.ts | 1 - .../plugins/partials/plugin_list.html | 45 ------------------- .../app/features/plugins/plugin_list_ctrl.ts | 30 ------------- 4 files changed, 1 insertion(+), 77 deletions(-) delete mode 100644 public/app/features/plugins/partials/plugin_list.html delete mode 100644 public/app/features/plugins/plugin_list_ctrl.ts diff --git a/public/app/features/plugins/PluginList.tsx b/public/app/features/plugins/PluginList.tsx index 2c47e755de3..0074839e754 100644 --- a/public/app/features/plugins/PluginList.tsx +++ b/public/app/features/plugins/PluginList.tsx @@ -5,7 +5,7 @@ import { Plugin } from 'app/types'; import { LayoutMode, LayoutModes } from '../../core/components/LayoutSelector/LayoutSelector'; interface Props { - plugins: PluginListItem[]; + plugins: Plugin[]; layoutMode: LayoutMode; } diff --git a/public/app/features/plugins/all.ts b/public/app/features/plugins/all.ts index fd19ea963b6..5be7593f68d 100644 --- a/public/app/features/plugins/all.ts +++ b/public/app/features/plugins/all.ts @@ -1,6 +1,5 @@ import './plugin_edit_ctrl'; import './plugin_page_ctrl'; -import './plugin_list_ctrl'; import './import_list/import_list'; import './ds_edit_ctrl'; import './ds_dashboards_ctrl'; diff --git a/public/app/features/plugins/partials/plugin_list.html b/public/app/features/plugins/partials/plugin_list.html deleted file mode 100644 index 04b5bf9c791..00000000000 --- a/public/app/features/plugins/partials/plugin_list.html +++ /dev/null @@ -1,45 +0,0 @@ - - - diff --git a/public/app/features/plugins/plugin_list_ctrl.ts b/public/app/features/plugins/plugin_list_ctrl.ts deleted file mode 100644 index 315252364cc..00000000000 --- a/public/app/features/plugins/plugin_list_ctrl.ts +++ /dev/null @@ -1,30 +0,0 @@ -import angular from 'angular'; -import _ from 'lodash'; - -export class PluginListCtrl { - plugins: any[]; - tabIndex: number; - navModel: any; - searchQuery: string; - allPlugins: any[]; - - /** @ngInject */ - constructor(private backendSrv: any, $location, navModelSrv) { - this.tabIndex = 0; - this.navModel = navModelSrv.getNav('cfg', 'plugins', 0); - - this.backendSrv.get('api/plugins', { embedded: 0 }).then(plugins => { - this.plugins = plugins; - this.allPlugins = plugins; - }); - } - - onQueryUpdated() { - const regex = new RegExp(this.searchQuery, 'ig'); - this.plugins = _.filter(this.allPlugins, item => { - return regex.test(item.name) || regex.test(item.type); - }); - } -} - -angular.module('grafana.controllers').controller('PluginListCtrl', PluginListCtrl);