mirror of
https://github.com/grafana/grafana.git
synced 2025-01-08 15:13:30 -06:00
new grid layout add data source
This commit is contained in:
parent
44f2041cf3
commit
262fee0a42
@ -1,114 +1,51 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { hot } from 'react-hot-loader';
|
||||
import Select from 'react-select';
|
||||
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 { updateLocation } from '../../core/actions';
|
||||
import { getNavModel } from 'app/core/selectors/navModel';
|
||||
|
||||
export interface Props {
|
||||
navModel: NavModel;
|
||||
dataSourceTypes: DataSourceType[];
|
||||
dataSourceTypes: Plugin[];
|
||||
addDataSource: typeof addDataSource;
|
||||
loadDataSourceTypes: typeof loadDataSourceTypes;
|
||||
updateLocation: typeof updateLocation;
|
||||
}
|
||||
|
||||
export interface State {
|
||||
name: string;
|
||||
type: { value: string; label: string };
|
||||
}
|
||||
|
||||
class NewDataSourcePage extends PureComponent<Props, State> {
|
||||
state = {
|
||||
name: '',
|
||||
type: null,
|
||||
};
|
||||
|
||||
class NewDataSourcePage extends PureComponent<Props> {
|
||||
componentDidMount() {
|
||||
this.props.loadDataSourceTypes();
|
||||
}
|
||||
|
||||
onChangeName = event => {
|
||||
this.setState({
|
||||
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);
|
||||
}
|
||||
onDataSourceTypeClicked = type => {
|
||||
this.props.addDataSource(type.name, type.value);
|
||||
};
|
||||
|
||||
render() {
|
||||
const { navModel, dataSourceTypes } = this.props;
|
||||
const { name, type } = this.state;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<PageHeader model={navModel} />
|
||||
<div className="page-container page-body">
|
||||
<h3 className="page-sub-heading">New Data source</h3>
|
||||
<form onSubmit={this.submitForm}>
|
||||
<div className="gf-form max-width-30">
|
||||
<span className="gf-form-label width-7">Name</span>
|
||||
<input
|
||||
className="gf-form-input max-width-23"
|
||||
type="text"
|
||||
value={name}
|
||||
onChange={this.onChangeName}
|
||||
placeholder="Name"
|
||||
/>
|
||||
</div>
|
||||
<div className="gf-form max-width-30">
|
||||
<span className="gf-form-label width-7">Type</span>
|
||||
<Select
|
||||
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>
|
||||
<h3 className="add-data-source-header">Choose data source type</h3>
|
||||
<div className="add-data-source-grid">
|
||||
{dataSourceTypes.map((type, index) => {
|
||||
return (
|
||||
<div
|
||||
onClick={() => this.onDataSourceTypeClicked(type)}
|
||||
className="add-data-source-grid-item"
|
||||
key={`${type.id}-${index}`}
|
||||
>
|
||||
<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>
|
||||
</div>
|
||||
);
|
||||
|
@ -1,5 +1,5 @@
|
||||
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 { LayoutMode } from '../../../core/components/LayoutSelector/LayoutSelector';
|
||||
import { updateLocation } from '../../../core/actions';
|
||||
@ -29,7 +29,7 @@ export interface SetDataSourcesLayoutModeAction {
|
||||
|
||||
export interface LoadDataSourceTypesAction {
|
||||
type: ActionTypes.LoadDataSourceTypes;
|
||||
payload: DataSourceType[];
|
||||
payload: Plugin[];
|
||||
}
|
||||
|
||||
const dataSourcesLoaded = (dataSources: DataSource[]): LoadDataSourcesAction => ({
|
||||
@ -37,7 +37,7 @@ const dataSourcesLoaded = (dataSources: DataSource[]): LoadDataSourcesAction =>
|
||||
payload: dataSources,
|
||||
});
|
||||
|
||||
const dataSourceTypesLoaded = (dataSourceTypes: DataSourceType[]): LoadDataSourceTypesAction => ({
|
||||
const dataSourceTypesLoaded = (dataSourceTypes: Plugin[]): LoadDataSourceTypesAction => ({
|
||||
type: ActionTypes.LoadDataSourceTypes,
|
||||
payload: dataSourceTypes,
|
||||
});
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { DataSource, DataSourcesState, DataSourceType } from 'app/types';
|
||||
import { DataSource, DataSourcesState, Plugin } from 'app/types';
|
||||
import { Action, ActionTypes } from './actions';
|
||||
import { LayoutModes } from '../../../core/components/LayoutSelector/LayoutSelector';
|
||||
|
||||
@ -7,7 +7,7 @@ const initialState: DataSourcesState = {
|
||||
layoutMode: LayoutModes.Grid,
|
||||
searchQuery: '',
|
||||
dataSourcesCount: 0,
|
||||
dataSourceTypes: [] as DataSourceType[],
|
||||
dataSourceTypes: [] as Plugin[],
|
||||
};
|
||||
|
||||
export const dataSourcesReducer = (state = initialState, action: Action): DataSourcesState => {
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { LayoutMode } from '../core/components/LayoutSelector/LayoutSelector';
|
||||
import { Plugin } from './plugins';
|
||||
|
||||
export interface DataSource {
|
||||
id: number;
|
||||
@ -17,15 +18,10 @@ export interface DataSource {
|
||||
readOnly: false;
|
||||
}
|
||||
|
||||
export interface DataSourceType {
|
||||
name: string;
|
||||
type: string;
|
||||
}
|
||||
|
||||
export interface DataSourcesState {
|
||||
dataSources: DataSource[];
|
||||
searchQuery: string;
|
||||
layoutMode: LayoutMode;
|
||||
dataSourcesCount: number;
|
||||
dataSourceTypes: DataSourceType[];
|
||||
dataSourceTypes: Plugin[];
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ import { DashboardState } from './dashboard';
|
||||
import { DashboardAcl, OrgRole, PermissionLevel } from './acl';
|
||||
import { ApiKey, ApiKeysState, NewApiKey } from './apiKeys';
|
||||
import { User } from './user';
|
||||
import { DataSource, DataSourcesState, DataSourceType } from './datasources';
|
||||
import { DataSource, DataSourcesState } from './datasources';
|
||||
import { PluginMeta, Plugin, PluginsState } from './plugins';
|
||||
|
||||
export {
|
||||
@ -42,7 +42,6 @@ export {
|
||||
Plugin,
|
||||
PluginsState,
|
||||
DataSourcesState,
|
||||
DataSourceType,
|
||||
};
|
||||
|
||||
export interface StoreState {
|
||||
|
@ -95,6 +95,7 @@
|
||||
@import 'components/user-picker';
|
||||
@import 'components/description-picker';
|
||||
@import 'components/delete_button';
|
||||
@import 'components/_add_data_source.scss';
|
||||
|
||||
// PAGES
|
||||
@import 'pages/login';
|
||||
|
35
public/sass/components/_add_data_source.scss
Normal file
35
public/sass/components/_add_data_source.scss
Normal file
@ -0,0 +1,35 @@
|
||||
.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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user