Commit 262fee0a by Peter Holmberg

new grid layout add data source

parent 44f2041c
import React, { PureComponent } from 'react'; import React, { PureComponent } from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { hot } from 'react-hot-loader'; import { hot } from 'react-hot-loader';
import Select from 'react-select';
import PageHeader from 'app/core/components/PageHeader/PageHeader'; import PageHeader from 'app/core/components/PageHeader/PageHeader';
import { DataSourceType, NavModel } from 'app/types'; import { NavModel, Plugin } from 'app/types';
import { addDataSource, loadDataSourceTypes } from './state/actions'; import { addDataSource, loadDataSourceTypes } from './state/actions';
import { updateLocation } from '../../core/actions'; import { updateLocation } from '../../core/actions';
import { getNavModel } from 'app/core/selectors/navModel'; import { getNavModel } from 'app/core/selectors/navModel';
export interface Props { export interface Props {
navModel: NavModel; navModel: NavModel;
dataSourceTypes: DataSourceType[]; dataSourceTypes: Plugin[];
addDataSource: typeof addDataSource; addDataSource: typeof addDataSource;
loadDataSourceTypes: typeof loadDataSourceTypes; loadDataSourceTypes: typeof loadDataSourceTypes;
updateLocation: typeof updateLocation; updateLocation: typeof updateLocation;
} }
export interface State { class NewDataSourcePage extends PureComponent<Props> {
name: string;
type: { value: string; label: string };
}
class NewDataSourcePage extends PureComponent<Props, State> {
state = {
name: '',
type: null,
};
componentDidMount() { componentDidMount() {
this.props.loadDataSourceTypes(); this.props.loadDataSourceTypes();
} }
onChangeName = event => { onDataSourceTypeClicked = type => {
this.setState({ this.props.addDataSource(type.name, type.value);
name: event.target.value,
});
};
onTypeChanged = type => {
this.setState({
type: type,
});
};
submitForm = event => {
event.preventDefault();
if (!this.isFieldsEmpty()) {
this.props.addDataSource(this.state.name, this.state.type.value);
}
};
goBack = () => {
this.props.updateLocation({ path: '/datasources' });
};
isFieldsEmpty = () => {
const { name, type } = this.state;
if (name === '' && !type) {
return true;
} else if (name !== '' && !type) {
return true;
} else {
return !!(name === '' && type);
}
}; };
render() { render() {
const { navModel, dataSourceTypes } = this.props; const { navModel, dataSourceTypes } = this.props;
const { name, type } = this.state;
return ( return (
<div> <div>
<PageHeader model={navModel} /> <PageHeader model={navModel} />
<div className="page-container page-body"> <div className="page-container page-body">
<h3 className="page-sub-heading">New Data source</h3> <h3 className="add-data-source-header">Choose data source type</h3>
<form onSubmit={this.submitForm}> <div className="add-data-source-grid">
<div className="gf-form max-width-30"> {dataSourceTypes.map((type, index) => {
<span className="gf-form-label width-7">Name</span> return (
<input <div
className="gf-form-input max-width-23" onClick={() => this.onDataSourceTypeClicked(type)}
type="text" className="add-data-source-grid-item"
value={name} key={`${type.id}-${index}`}
onChange={this.onChangeName} >
placeholder="Name" <img className="add-data-source-grid-item-logo" src={type.info.logos.small} />
/> <span className="add-data-source-grid-item-text">{type.name}</span>
</div> </div>
<div className="gf-form max-width-30"> );
<span className="gf-form-label width-7">Type</span> })}
<Select </div>
valueKey="type"
labelKey="name"
options={dataSourceTypes}
value={type}
onChange={this.onTypeChanged}
autoSize={true}
className="width-23"
/>
</div>
<div className="gf-form-button-row">
<button type="submit" className="btn btn-success width-7" disabled={this.isFieldsEmpty()}>
<i className="fa fa-save" />
{` Create`}
</button>
<button className="btn btn-danger" onClick={this.goBack}>
Cancel
</button>
</div>
</form>
</div> </div>
</div> </div>
); );
......
import { ThunkAction } from 'redux-thunk'; import { ThunkAction } from 'redux-thunk';
import { DataSource, DataSourceType, StoreState } from 'app/types'; import { DataSource, Plugin, StoreState } from 'app/types';
import { getBackendSrv } from '../../../core/services/backend_srv'; import { getBackendSrv } from '../../../core/services/backend_srv';
import { LayoutMode } from '../../../core/components/LayoutSelector/LayoutSelector'; import { LayoutMode } from '../../../core/components/LayoutSelector/LayoutSelector';
import { updateLocation } from '../../../core/actions'; import { updateLocation } from '../../../core/actions';
...@@ -29,7 +29,7 @@ export interface SetDataSourcesLayoutModeAction { ...@@ -29,7 +29,7 @@ export interface SetDataSourcesLayoutModeAction {
export interface LoadDataSourceTypesAction { export interface LoadDataSourceTypesAction {
type: ActionTypes.LoadDataSourceTypes; type: ActionTypes.LoadDataSourceTypes;
payload: DataSourceType[]; payload: Plugin[];
} }
const dataSourcesLoaded = (dataSources: DataSource[]): LoadDataSourcesAction => ({ const dataSourcesLoaded = (dataSources: DataSource[]): LoadDataSourcesAction => ({
...@@ -37,7 +37,7 @@ const dataSourcesLoaded = (dataSources: DataSource[]): LoadDataSourcesAction => ...@@ -37,7 +37,7 @@ const dataSourcesLoaded = (dataSources: DataSource[]): LoadDataSourcesAction =>
payload: dataSources, payload: dataSources,
}); });
const dataSourceTypesLoaded = (dataSourceTypes: DataSourceType[]): LoadDataSourceTypesAction => ({ const dataSourceTypesLoaded = (dataSourceTypes: Plugin[]): LoadDataSourceTypesAction => ({
type: ActionTypes.LoadDataSourceTypes, type: ActionTypes.LoadDataSourceTypes,
payload: dataSourceTypes, payload: dataSourceTypes,
}); });
......
import { DataSource, DataSourcesState, DataSourceType } from 'app/types'; import { DataSource, DataSourcesState, Plugin } from 'app/types';
import { Action, ActionTypes } from './actions'; import { Action, ActionTypes } from './actions';
import { LayoutModes } from '../../../core/components/LayoutSelector/LayoutSelector'; import { LayoutModes } from '../../../core/components/LayoutSelector/LayoutSelector';
...@@ -7,7 +7,7 @@ const initialState: DataSourcesState = { ...@@ -7,7 +7,7 @@ const initialState: DataSourcesState = {
layoutMode: LayoutModes.Grid, layoutMode: LayoutModes.Grid,
searchQuery: '', searchQuery: '',
dataSourcesCount: 0, dataSourcesCount: 0,
dataSourceTypes: [] as DataSourceType[], dataSourceTypes: [] as Plugin[],
}; };
export const dataSourcesReducer = (state = initialState, action: Action): DataSourcesState => { export const dataSourcesReducer = (state = initialState, action: Action): DataSourcesState => {
......
import { LayoutMode } from '../core/components/LayoutSelector/LayoutSelector'; import { LayoutMode } from '../core/components/LayoutSelector/LayoutSelector';
import { Plugin } from './plugins';
export interface DataSource { export interface DataSource {
id: number; id: number;
...@@ -17,15 +18,10 @@ export interface DataSource { ...@@ -17,15 +18,10 @@ export interface DataSource {
readOnly: false; readOnly: false;
} }
export interface DataSourceType {
name: string;
type: string;
}
export interface DataSourcesState { export interface DataSourcesState {
dataSources: DataSource[]; dataSources: DataSource[];
searchQuery: string; searchQuery: string;
layoutMode: LayoutMode; layoutMode: LayoutMode;
dataSourcesCount: number; dataSourcesCount: number;
dataSourceTypes: DataSourceType[]; dataSourceTypes: Plugin[];
} }
...@@ -7,7 +7,7 @@ import { DashboardState } from './dashboard'; ...@@ -7,7 +7,7 @@ import { DashboardState } from './dashboard';
import { DashboardAcl, OrgRole, PermissionLevel } from './acl'; import { DashboardAcl, OrgRole, PermissionLevel } from './acl';
import { ApiKey, ApiKeysState, NewApiKey } from './apiKeys'; import { ApiKey, ApiKeysState, NewApiKey } from './apiKeys';
import { User } from './user'; import { User } from './user';
import { DataSource, DataSourcesState, DataSourceType } from './datasources'; import { DataSource, DataSourcesState } from './datasources';
import { PluginMeta, Plugin, PluginsState } from './plugins'; import { PluginMeta, Plugin, PluginsState } from './plugins';
export { export {
...@@ -42,7 +42,6 @@ export { ...@@ -42,7 +42,6 @@ export {
Plugin, Plugin,
PluginsState, PluginsState,
DataSourcesState, DataSourcesState,
DataSourceType,
}; };
export interface StoreState { export interface StoreState {
......
...@@ -95,6 +95,7 @@ ...@@ -95,6 +95,7 @@
@import 'components/user-picker'; @import 'components/user-picker';
@import 'components/description-picker'; @import 'components/description-picker';
@import 'components/delete_button'; @import 'components/delete_button';
@import 'components/_add_data_source.scss';
// PAGES // PAGES
@import 'pages/login'; @import 'pages/login';
......
.add-data-source-header {
margin-bottom: 20px;
text-align: center;
}
.add-data-source-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-row-gap: 10px;
grid-column-gap: 10px;
}
.add-data-source-grid-item {
padding: 10px;
display: flex;
align-items: center;
cursor: pointer;
background: $card-background;
box-shadow: $card-shadow;
color: $headings-color;
&:hover {
background: $card-background-hover;
}
}
.add-data-source-grid-item-text {
font-size: $font-size-h5;
margin-left: 10px;
}
.add-data-source-grid-item-logo {
width: 55px;
height: 55px;
}
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