Commit 4ecd33c7 by Peter Holmberg

Fixed nav model

parent ed349075
import React, { PureComponent } from 'react';
import { hot } from 'react-hot-loader';
import { connect } from 'react-redux';
import PageHeader from '../../core/components/PageHeader/PageHeader';
import { DataSource, NavModel } from 'app/types';
import { loadDataSource } from './state/actions';
import { getNavModel } from '../../core/selectors/navModel';
import { getRouteParamsId, getRouteParamsPage } from '../../core/selectors/location';
import { getDataSourceLoadingNav } from './state/navModel';
import { getDataSource } from './state/selectors';
export interface Props {
navModel: NavModel;
dataSource: DataSource;
dataSourceId: number;
pageName: string;
loadDataSource: typeof loadDataSource;
}
enum PageTypes {
Settings = 'settings',
Permissions = 'permissions',
Dashboards = 'dashboards',
}
export class EditDataSourcePage extends PureComponent<Props> {
componentDidMount() {
this.fetchDataSource();
}
async fetchDataSource() {
await this.props.loadDataSource(this.props.dataSourceId);
}
isValidPage(currentPage) {
return (Object as any).values(PageTypes).includes(currentPage);
}
getCurrentPage() {
const currentPage = this.props.pageName;
return this.isValidPage(currentPage) ? currentPage : PageTypes.Settings;
}
renderPage() {
switch (this.getCurrentPage()) {
case PageTypes.Settings:
return <div>Settings</div>;
case PageTypes.Permissions:
return <div>Permissions</div>;
case PageTypes.Dashboards:
return <div>Dashboards</div>;
}
return null;
}
render() {
const { navModel } = this.props;
return (
<div>
<PageHeader model={navModel} />
<div className="page-container page-body" />
{this.renderPage()}
</div>
);
}
}
function mapStateToProps(state) {
const pageName = getRouteParamsPage(state.location) || 'settings';
const dataSourceId = getRouteParamsId(state.location);
const dataSourceLoadingNav = getDataSourceLoadingNav(pageName);
return {
navModel: getNavModel(state.navIndex, `datasource-${pageName}-${dataSourceId}`, dataSourceLoadingNav),
dataSourceId: dataSourceId,
dataSource: getDataSource(state.dataSources, dataSourceId),
pageName: pageName,
};
}
const mapDispatchToProps = {
loadDataSource,
};
export default hot(module)(connect(mapStateToProps, mapDispatchToProps)(EditDataSourcePage));
......@@ -2,12 +2,14 @@ import { ThunkAction } from 'redux-thunk';
import { DataSource, Plugin, StoreState } from 'app/types';
import { getBackendSrv } from '../../../core/services/backend_srv';
import { LayoutMode } from '../../../core/components/LayoutSelector/LayoutSelector';
import { updateLocation } from '../../../core/actions';
import { updateLocation, updateNavIndex, UpdateNavIndexAction } from '../../../core/actions';
import { UpdateLocationAction } from '../../../core/actions/location';
import { buildNavModel } from './navModel';
export enum ActionTypes {
LoadDataSources = 'LOAD_DATA_SOURCES',
LoadDataSourceTypes = 'LOAD_DATA_SOURCE_TYPES',
LoadDataSource = 'LOAD_DATA_SOURCE',
SetDataSourcesSearchQuery = 'SET_DATA_SOURCES_SEARCH_QUERY',
SetDataSourcesLayoutMode = 'SET_DATA_SOURCES_LAYOUT_MODE',
SetDataSourceTypeSearchQuery = 'SET_DATA_SOURCE_TYPE_SEARCH_QUERY',
......@@ -38,11 +40,21 @@ export interface SetDataSourceTypeSearchQueryAction {
payload: string;
}
export interface LoadDataSourceAction {
type: ActionTypes.LoadDataSource;
payload: DataSource;
}
const dataSourcesLoaded = (dataSources: DataSource[]): LoadDataSourcesAction => ({
type: ActionTypes.LoadDataSources,
payload: dataSources,
});
const dataSourceLoaded = (dataSource: DataSource): LoadDataSourceAction => ({
type: ActionTypes.LoadDataSource,
payload: dataSource,
});
const dataSourceTypesLoaded = (dataSourceTypes: Plugin[]): LoadDataSourceTypesAction => ({
type: ActionTypes.LoadDataSourceTypes,
payload: dataSourceTypes,
......@@ -69,7 +81,9 @@ export type Action =
| SetDataSourcesLayoutModeAction
| UpdateLocationAction
| LoadDataSourceTypesAction
| SetDataSourceTypeSearchQueryAction;
| SetDataSourceTypeSearchQueryAction
| LoadDataSourceAction
| UpdateNavIndexAction;
type ThunkResult<R> = ThunkAction<R, StoreState, undefined, Action>;
......@@ -80,6 +94,15 @@ export function loadDataSources(): ThunkResult<void> {
};
}
export function loadDataSource(id: number): ThunkResult<void> {
return async dispatch => {
const dataSource = await getBackendSrv().get(`/api/datasources/${id}`);
const pluginInfo = await getBackendSrv().get(`/api/plugins/${dataSource.type}/settings`);
dispatch(dataSourceLoaded(dataSource));
dispatch(updateNavIndex(buildNavModel(dataSource, pluginInfo)));
};
}
export function addDataSource(plugin: Plugin): ThunkResult<void> {
return async (dispatch, getStore) => {
await dispatch(loadDataSources());
......
import { DataSource, NavModel, NavModelItem, PluginMeta } from 'app/types';
export function buildNavModel(dataSource: DataSource, pluginMeta: PluginMeta): NavModelItem {
const navModel = {
img: pluginMeta.info.logos.large,
id: 'datasource-' + dataSource.id,
subTitle: `Type: ${pluginMeta.name}`,
url: '',
text: dataSource.name,
breadcrumbs: [{ title: 'Data Sources', url: 'datasources' }],
children: [
{
active: false,
icon: 'fa fa-fw fa-sliders',
id: `datasource-settings-${dataSource.id}`,
text: 'Settings',
url: `datasources/edit/${dataSource.id}/settings`,
},
{
active: false,
icon: 'fa fa-fw fa-sliders',
id: `datasource-permissions-${dataSource.id}`,
text: 'Permissions',
url: `datasources/edit/${dataSource.id}/permissions`,
},
],
};
if (pluginMeta.includes && pluginMeta.includes.length > 0) {
navModel.children.push({
active: false,
icon: 'gicon gicon-dashboard',
id: `datasource-dashboards-${dataSource.id}`,
text: 'Dashboards',
url: `datasources/edit/${dataSource.id}/dashboards`,
});
}
return navModel;
}
export function getDataSourceLoadingNav(pageName: string): NavModel {
const main = buildNavModel(
{
access: '',
basicAuth: false,
database: '',
id: 1,
isDefault: false,
jsonData: { authType: 'credentials', defaultRegion: 'eu-west-2' },
name: 'Loading',
orgId: 1,
password: '',
readOnly: false,
type: 'Loading',
typeLogoUrl: 'public/img/icn-datasource.svg',
url: '',
user: '',
},
{
id: '1',
name: '',
info: {
author: {
name: '',
url: '',
},
description: '',
links: [''],
logos: {
large: '',
small: '',
},
screenshots: '',
updated: '',
version: '',
},
includes: [{ type: '', name: '', path: '' }],
}
);
let node: NavModelItem;
// find active page
for (const child of main.children) {
if (child.id.indexOf(pageName) > 0) {
child.active = true;
node = child;
break;
}
}
return {
main: main,
node: node,
};
}
......@@ -4,6 +4,7 @@ import { LayoutModes } from '../../../core/components/LayoutSelector/LayoutSelec
const initialState: DataSourcesState = {
dataSources: [] as DataSource[],
dataSource: {} as DataSource,
layoutMode: LayoutModes.Grid,
searchQuery: '',
dataSourcesCount: 0,
......@@ -16,6 +17,9 @@ export const dataSourcesReducer = (state = initialState, action: Action): DataSo
case ActionTypes.LoadDataSources:
return { ...state, dataSources: action.payload, dataSourcesCount: action.payload.length };
case ActionTypes.LoadDataSource:
return { ...state, dataSource: action.payload };
case ActionTypes.SetDataSourcesSearchQuery:
return { ...state, searchQuery: action.payload };
......
import { DataSource } from '../../../types';
export const getDataSources = state => {
const regex = new RegExp(state.searchQuery, 'i');
......@@ -14,6 +16,13 @@ export const getDataSourceTypes = state => {
});
};
export const getDataSource = (state, dataSourceId): DataSource | null => {
if (state.dataSource.id === parseInt(dataSourceId, 10)) {
return state.dataSource;
}
return null;
};
export const getDataSourcesSearchQuery = state => state.searchQuery;
export const getDataSourcesLayoutMode = state => state.layoutMode;
export const getDataSourcesCount = state => state.dataSourcesCount;
......@@ -12,6 +12,7 @@ import FolderPermissions from 'app/features/folders/FolderPermissions';
import DataSourcesListPage from 'app/features/datasources/DataSourcesListPage';
import NewDataSourcePage from '../features/datasources/NewDataSourcePage';
import UsersListPage from 'app/features/users/UsersListPage';
import EditDataSourcePage from 'app/features/datasources/EditDataSourcePage';
/** @ngInject */
export function setupAngularRoutes($routeProvider, $locationProvider) {
......@@ -71,15 +72,11 @@ export function setupAngularRoutes($routeProvider, $locationProvider) {
component: () => DataSourcesListPage,
},
})
.when('/datasources/edit/:id', {
templateUrl: 'public/app/features/plugins/partials/ds_edit.html',
controller: 'DataSourceEditCtrl',
controllerAs: 'ctrl',
})
.when('/datasources/edit/:id/dashboards', {
templateUrl: 'public/app/features/plugins/partials/ds_dashboards.html',
controller: 'DataSourceDashboardsCtrl',
controllerAs: 'ctrl',
.when('/datasources/edit/:id/:page?', {
template: '<react-container />',
resolve: {
component: () => EditDataSourcePage,
},
})
.when('/datasources/new', {
template: '<react-container />',
......
......@@ -25,4 +25,5 @@ export interface DataSourcesState {
layoutMode: LayoutMode;
dataSourcesCount: number;
dataSourceTypes: Plugin[];
dataSource: DataSource;
}
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