mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
renders angular component
This commit is contained in:
34
public/app/features/datasources/settings/BasicSettings.tsx
Normal file
34
public/app/features/datasources/settings/BasicSettings.tsx
Normal file
@@ -0,0 +1,34 @@
|
||||
import React, { SFC } from 'react';
|
||||
import { Label } from '../../../core/components/Forms/Forms';
|
||||
|
||||
export interface Props {
|
||||
dataSourceName: string;
|
||||
onChange: (name: string) => void;
|
||||
}
|
||||
|
||||
const BasicSettings: SFC<Props> = ({ dataSourceName, onChange }) => {
|
||||
return (
|
||||
<div className="gf-form-group">
|
||||
<div className="gf-form max-width-30">
|
||||
<Label
|
||||
tooltip={
|
||||
'The name is used when you select the data source in panels. The Default data source is' +
|
||||
'preselected in new panels.'
|
||||
}
|
||||
>
|
||||
Name
|
||||
</Label>
|
||||
<input
|
||||
className="gf-form-input max-width-23"
|
||||
type="text"
|
||||
value={dataSourceName}
|
||||
placeholder="Name"
|
||||
onChange={event => onChange(event.target.value)}
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default BasicSettings;
|
||||
25
public/app/features/datasources/settings/ButtonRow.tsx
Normal file
25
public/app/features/datasources/settings/ButtonRow.tsx
Normal file
@@ -0,0 +1,25 @@
|
||||
import React, { SFC } from 'react';
|
||||
|
||||
export interface Props {
|
||||
isReadOnly: boolean;
|
||||
onDelete: (event) => void;
|
||||
onSubmit: (event) => void;
|
||||
}
|
||||
|
||||
const ButtonRow: SFC<Props> = ({ isReadOnly, onDelete, onSubmit }) => {
|
||||
return (
|
||||
<div className="gf-form-button-row">
|
||||
<button type="submit" className="btn btn-success" disabled={isReadOnly} onClick={event => onSubmit(event)}>
|
||||
Save & Test
|
||||
</button>
|
||||
<button type="submit" className="btn btn-danger" disabled={isReadOnly} onClick={event => onDelete(event)}>
|
||||
Delete
|
||||
</button>
|
||||
<a className="btn btn-inverse" href="/datasources">
|
||||
Back
|
||||
</a>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ButtonRow;
|
||||
@@ -1,15 +1,16 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import { hot } from 'react-hot-loader';
|
||||
import { connect } from 'react-redux';
|
||||
import { DataSource, NavModel, Plugin } from 'app/types';
|
||||
import PageHeader from '../../core/components/PageHeader/PageHeader';
|
||||
import DataSourcePluginSettings from './DataSourcePluginSettings';
|
||||
import { loadDataSource, setDataSourceName } from './state/actions';
|
||||
import { getNavModel } from '../../core/selectors/navModel';
|
||||
import { getRouteParamsId } from '../../core/selectors/location';
|
||||
import { Label } from '../../core/components/Forms/Forms';
|
||||
import PageLoader from '../../core/components/PageLoader/PageLoader';
|
||||
import { getDataSource } from './state/selectors';
|
||||
import { DataSource, NavModel, Plugin } from 'app/types/';
|
||||
import PageHeader from '../../../core/components/PageHeader/PageHeader';
|
||||
import PageLoader from '../../../core/components/PageLoader/PageLoader';
|
||||
import PluginSettings from './PluginSettings';
|
||||
import BasicSettings from './BasicSettings';
|
||||
import ButtonRow from './ButtonRow';
|
||||
import { loadDataSource, setDataSourceName } from '../state/actions';
|
||||
import { getNavModel } from '../../../core/selectors/navModel';
|
||||
import { getRouteParamsId } from '../../../core/selectors/location';
|
||||
import { getDataSource, getDataSourceMeta } from '../state/selectors';
|
||||
|
||||
export interface Props {
|
||||
navModel: NavModel;
|
||||
@@ -45,7 +46,7 @@ export class DataSourceSettings extends PureComponent<Props, State> {
|
||||
console.log(event);
|
||||
};
|
||||
|
||||
isReadyOnly() {
|
||||
isReadOnly() {
|
||||
return this.props.dataSource.readOnly === true;
|
||||
}
|
||||
|
||||
@@ -87,59 +88,27 @@ export class DataSourceSettings extends PureComponent<Props, State> {
|
||||
<div className="page-container page-body">
|
||||
<div>
|
||||
<form onSubmit={this.onSubmit}>
|
||||
<div className="gf-form-group">
|
||||
<div className="gf-form max-width-30">
|
||||
<Label
|
||||
tooltip={
|
||||
'The name is used when you select the data source in panels. The Default data source is' +
|
||||
'preselected in new panels.'
|
||||
}
|
||||
>
|
||||
Name
|
||||
</Label>
|
||||
<input
|
||||
className="gf-form-input max-width-23"
|
||||
type="text"
|
||||
value={this.props.dataSource.name}
|
||||
placeholder="Name"
|
||||
onChange={event => this.props.setDataSourceName(event.target.value)}
|
||||
required
|
||||
<BasicSettings
|
||||
dataSourceName={this.props.dataSource.name}
|
||||
onChange={name => this.props.setDataSourceName(name)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{this.shouldRenderInfoBox() && <div className="grafana-info-box">{this.getInfoText()}</div>}
|
||||
|
||||
{this.isReadyOnly() ? (
|
||||
{this.isReadOnly() ? (
|
||||
<div className="grafana-info-box span8">
|
||||
This datasource was added by config and cannot be modified using the UI. Please contact your server
|
||||
admin to update this datasource.
|
||||
</div>
|
||||
) : (
|
||||
<DataSourcePluginSettings dataSource={dataSource} dataSourceMeta={dataSourceMeta} />
|
||||
dataSourceMeta.module && <PluginSettings dataSource={dataSource} dataSourceMeta={dataSourceMeta} />
|
||||
)}
|
||||
|
||||
<div className="gf-form-button-row">
|
||||
<button
|
||||
type="submit"
|
||||
className="btn btn-success"
|
||||
disabled={this.isReadyOnly()}
|
||||
onClick={this.onSubmit}
|
||||
>
|
||||
Save & Test
|
||||
</button>
|
||||
<button
|
||||
type="submit"
|
||||
className="btn btn-danger"
|
||||
disabled={this.isReadyOnly()}
|
||||
onClick={this.onDelete}
|
||||
>
|
||||
Delete
|
||||
</button>
|
||||
<a className="btn btn-inverse" href="/datasources">
|
||||
Back
|
||||
</a>
|
||||
</div>
|
||||
<ButtonRow
|
||||
onSubmit={event => this.onSubmit(event)}
|
||||
isReadOnly={this.isReadOnly()}
|
||||
onDelete={event => this.onDelete(event)}
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@@ -151,11 +120,12 @@ export class DataSourceSettings extends PureComponent<Props, State> {
|
||||
|
||||
function mapStateToProps(state) {
|
||||
const pageId = getRouteParamsId(state.location);
|
||||
const dataSource = getDataSource(state.dataSources, pageId);
|
||||
|
||||
return {
|
||||
navModel: getNavModel(state.navIndex, `datasource-settings-${pageId}`),
|
||||
dataSource: getDataSource(state.dataSources, pageId),
|
||||
dataSourceMeta: state.dataSources.dataSourceMeta,
|
||||
dataSourceMeta: getDataSourceMeta(state.dataSources, dataSource.type),
|
||||
pageId: pageId,
|
||||
};
|
||||
}
|
||||
@@ -1,31 +1,29 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import { DataSource, Plugin } from 'app/types';
|
||||
import { DataSource, Plugin } from 'app/types/';
|
||||
import { getAngularLoader, AngularComponent } from 'app/core/services/AngularLoader';
|
||||
import { importPluginModule } from '../plugins/plugin_loader';
|
||||
|
||||
interface Props {
|
||||
dataSource: DataSource;
|
||||
dataSourceMeta: Plugin;
|
||||
}
|
||||
|
||||
export class DataSourcePluginSettings extends PureComponent<Props> {
|
||||
export class PluginSettings extends PureComponent<Props> {
|
||||
element: any;
|
||||
component: AngularComponent;
|
||||
|
||||
componentDidMount() {
|
||||
const { dataSource, dataSourceMeta } = this.props;
|
||||
|
||||
if (!this.element) {
|
||||
return;
|
||||
}
|
||||
|
||||
importPluginModule(this.props.dataSourceMeta.module).then(pluginExports => {
|
||||
console.log(pluginExports);
|
||||
});
|
||||
|
||||
const loader = getAngularLoader();
|
||||
const template = '<plugin-component type="datasource-config-ctrl" />';
|
||||
const scopeProps = {
|
||||
ctrl: {
|
||||
dataSourceMeta: this.props.dataSourceMeta,
|
||||
current: this.props.dataSource,
|
||||
datasourceMeta: dataSourceMeta,
|
||||
current: dataSource,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -37,4 +35,4 @@ export class DataSourcePluginSettings extends PureComponent<Props> {
|
||||
}
|
||||
}
|
||||
|
||||
export default DataSourcePluginSettings;
|
||||
export default PluginSettings;
|
||||
@@ -23,6 +23,14 @@ export const getDataSource = (state, dataSourceId): DataSource | null => {
|
||||
return {} as DataSource;
|
||||
};
|
||||
|
||||
export const getDataSourceMeta = (state, type): Plugin => {
|
||||
if (state.dataSourceMeta.id === type) {
|
||||
return state.dataSourceMeta;
|
||||
}
|
||||
|
||||
return {} as Plugin;
|
||||
};
|
||||
|
||||
export const getDataSourcesSearchQuery = state => state.searchQuery;
|
||||
export const getDataSourcesLayoutMode = state => state.layoutMode;
|
||||
export const getDataSourcesCount = state => state.dataSourcesCount;
|
||||
|
||||
@@ -14,7 +14,7 @@ import DataSourcesListPage from 'app/features/datasources/DataSourcesListPage';
|
||||
import NewDataSourcePage from '../features/datasources/NewDataSourcePage';
|
||||
import UsersListPage from 'app/features/users/UsersListPage';
|
||||
import DataSourceDashboards from 'app/features/datasources/DataSourceDashboards';
|
||||
import DataSourceSettings from '../features/datasources/DataSourceSettings';
|
||||
import DataSourceSettings from '../features/datasources/settings/DataSourceSettings';
|
||||
|
||||
/** @ngInject */
|
||||
export function setupAngularRoutes($routeProvider, $locationProvider) {
|
||||
|
||||
@@ -4,22 +4,19 @@ const merge = require('webpack-merge');
|
||||
const common = require('./webpack.common.js');
|
||||
const path = require('path');
|
||||
const webpack = require('webpack');
|
||||
const HtmlWebpackPlugin = require("html-webpack-plugin");
|
||||
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
||||
const HtmlWebpackHarddiskPlugin = require('html-webpack-harddisk-plugin');
|
||||
const CleanWebpackPlugin = require('clean-webpack-plugin');
|
||||
|
||||
module.exports = merge(common, {
|
||||
entry: {
|
||||
app: [
|
||||
'webpack-dev-server/client?http://localhost:3333',
|
||||
'./public/app/dev.ts',
|
||||
],
|
||||
app: ['webpack-dev-server/client?http://localhost:3333', './public/app/dev.ts'],
|
||||
},
|
||||
|
||||
output: {
|
||||
path: path.resolve(__dirname, '../../public/build'),
|
||||
filename: '[name].[hash].js',
|
||||
publicPath: "/public/build/",
|
||||
publicPath: '/public/build/',
|
||||
pathinfo: false,
|
||||
},
|
||||
|
||||
@@ -34,8 +31,8 @@ module.exports = merge(common, {
|
||||
hot: true,
|
||||
port: 3333,
|
||||
proxy: {
|
||||
'!/public/build': 'http://localhost:3000'
|
||||
}
|
||||
'!/public/build': 'http://localhost:3000',
|
||||
},
|
||||
},
|
||||
|
||||
optimization: {
|
||||
@@ -47,40 +44,39 @@ module.exports = merge(common, {
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /(?!.*\.test)\.tsx$/,
|
||||
test: /(?!.*\.test)\.(ts|tsx)$/,
|
||||
exclude: /node_modules/,
|
||||
use: [{
|
||||
use: [
|
||||
{
|
||||
loader: 'babel-loader',
|
||||
options: {
|
||||
cacheDirectory: true,
|
||||
babelrc: false,
|
||||
plugins: [
|
||||
'syntax-dynamic-import',
|
||||
'react-hot-loader/babel'
|
||||
]
|
||||
}
|
||||
plugins: ['syntax-dynamic-import', 'react-hot-loader/babel'],
|
||||
},
|
||||
},
|
||||
{
|
||||
loader: 'ts-loader',
|
||||
options: {
|
||||
transpileOnly: true,
|
||||
experimentalWatchApi: true
|
||||
experimentalWatchApi: true,
|
||||
},
|
||||
}],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
test: /\.scss$/,
|
||||
use: [
|
||||
"style-loader", // creates style nodes from JS strings
|
||||
"css-loader", // translates CSS into CommonJS
|
||||
"sass-loader" // compiles Sass to CSS
|
||||
]
|
||||
'style-loader', // creates style nodes from JS strings
|
||||
'css-loader', // translates CSS into CommonJS
|
||||
'sass-loader', // compiles Sass to CSS
|
||||
],
|
||||
},
|
||||
{
|
||||
test: /\.(png|jpg|gif|ttf|eot|svg|woff(2)?)(\?[a-z0-9=&.]+)?$/,
|
||||
loader: 'file-loader'
|
||||
loader: 'file-loader',
|
||||
},
|
||||
]
|
||||
],
|
||||
},
|
||||
|
||||
plugins: [
|
||||
@@ -89,16 +85,16 @@ module.exports = merge(common, {
|
||||
filename: path.resolve(__dirname, '../../public/views/index.html'),
|
||||
template: path.resolve(__dirname, '../../public/views/index.template.html'),
|
||||
inject: 'body',
|
||||
alwaysWriteToDisk: true
|
||||
alwaysWriteToDisk: true,
|
||||
}),
|
||||
new HtmlWebpackHarddiskPlugin(),
|
||||
new webpack.NamedModulesPlugin(),
|
||||
new webpack.HotModuleReplacementPlugin(),
|
||||
new webpack.DefinePlugin({
|
||||
'GRAFANA_THEME': JSON.stringify(process.env.GRAFANA_THEME || 'dark'),
|
||||
GRAFANA_THEME: JSON.stringify(process.env.GRAFANA_THEME || 'dark'),
|
||||
'process.env': {
|
||||
'NODE_ENV': JSON.stringify('development')
|
||||
}
|
||||
NODE_ENV: JSON.stringify('development'),
|
||||
},
|
||||
}),
|
||||
]
|
||||
],
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user