mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
updated view to use angular loader
This commit is contained in:
parent
596a83407e
commit
a7bd944098
@ -1,331 +0,0 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { DataSource } from 'app/types';
|
||||
import FormSwitch from '../../core/components/FormSwitch/FormSwitch';
|
||||
|
||||
interface Props {
|
||||
dataSource: DataSource;
|
||||
showAccessOption: any;
|
||||
tlsAuth: any;
|
||||
tlsAuthWithCACert: any;
|
||||
tlsCACert: any;
|
||||
tlsClientCert: any;
|
||||
tlsClientKey: any;
|
||||
}
|
||||
|
||||
interface State {
|
||||
basicAuthUser: string;
|
||||
basicAuthPassword: string;
|
||||
showAccessHelp: boolean;
|
||||
url: string;
|
||||
access: string;
|
||||
}
|
||||
|
||||
export class DataSourceHttpSettings extends PureComponent<Props, State> {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
url: '',
|
||||
basicAuthUser: props.dataSource.basicAuthUser,
|
||||
basicAuthPassword: props.dataSource.basicAuthPassword,
|
||||
showAccessHelp: false,
|
||||
access: '',
|
||||
};
|
||||
}
|
||||
|
||||
onToggleAccessHelp = () => {
|
||||
this.setState(prevState => ({
|
||||
showAccessHelp: !prevState.showAccessHelp,
|
||||
}));
|
||||
};
|
||||
|
||||
onUrlChange = event => {
|
||||
this.setState({
|
||||
url: event.target.value,
|
||||
});
|
||||
};
|
||||
|
||||
onAccessChange = event => {
|
||||
this.setState({
|
||||
access: event.target.value,
|
||||
});
|
||||
};
|
||||
|
||||
onBasicAuthChange = event => {
|
||||
console.log(event);
|
||||
};
|
||||
|
||||
onWithCredentialsChange = event => {
|
||||
console.log(event);
|
||||
};
|
||||
|
||||
onTlsAuthChange = event => {
|
||||
console.log(event);
|
||||
};
|
||||
|
||||
onTlsAuthWithCACertChange = event => {
|
||||
console.log(event);
|
||||
};
|
||||
|
||||
onTlsSkipVerifyChange = event => {
|
||||
console.log(event);
|
||||
};
|
||||
|
||||
render() {
|
||||
const {
|
||||
dataSource,
|
||||
showAccessOption,
|
||||
tlsAuth,
|
||||
tlsAuthWithCACert,
|
||||
tlsCACert,
|
||||
tlsClientCert,
|
||||
tlsClientKey,
|
||||
} = this.props;
|
||||
|
||||
const { access, showAccessHelp, basicAuthUser, basicAuthPassword, url } = this.state;
|
||||
|
||||
const accessOptions = [{ key: 'proxy', value: 'Server (Default)' }, { key: 'direct', value: 'Browser' }];
|
||||
|
||||
return (
|
||||
<div className="gf-form-group">
|
||||
<h3 className="page-heading">HTTP</h3>
|
||||
<div className="gf-form-group">
|
||||
<div className="gf-form-inline">
|
||||
<div className="gf-form max-width-30">
|
||||
<span className="gf-form-label width-10">URL</span>
|
||||
<input
|
||||
className="gf-form-input"
|
||||
type="text"
|
||||
value={url}
|
||||
onChange={this.onUrlChange}
|
||||
placeholder="https://localhost:9090"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
{showAccessOption && (
|
||||
<div className="gf-form-inline">
|
||||
<div className="gf-form max-width-30">
|
||||
<span className="gf-form-label width-10">Access</span>
|
||||
<select className="width-20" value={access} onChange={this.onAccessChange}>
|
||||
{accessOptions.map(option => {
|
||||
return (
|
||||
<option key={option.key} value={option.key}>
|
||||
{option.value}
|
||||
</option>
|
||||
);
|
||||
})}
|
||||
</select>
|
||||
</div>
|
||||
<div className="gf-form">
|
||||
<label className="gf-form-label query-keyword pointer" onClick={this.onToggleAccessHelp}>
|
||||
Help
|
||||
{showAccessHelp ? <i className="fa fa-caret-down" /> : <i className="fa fa-caret-right"> </i>}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{showAccessHelp && (
|
||||
<div className="grafana-info-box m-t-2">
|
||||
<p>
|
||||
Access mode controls how requests to the data source will be handled.
|
||||
<strong>
|
||||
<i>Server</i>
|
||||
</strong>{' '}
|
||||
should be the preferred way if nothing else stated.
|
||||
</p>
|
||||
<div className="alert-title">Server access mode (Default):</div>
|
||||
<p>
|
||||
All requests will be made from the browser to Grafana backend/server which in turn will forward the
|
||||
requests to the data source and by that circumvent possible Cross-Origin Resource Sharing (CORS)
|
||||
requirements. The URL needs to be accessible from the grafana backend/server if you select this access
|
||||
mode.
|
||||
</p>
|
||||
<div className="alert-title">Browser access mode:</div>
|
||||
<p>
|
||||
All requests will be made from the browser directly to the data source and may be subject to Cross-Origin
|
||||
Resource Sharing (CORS) requirements. The URL needs to be accessible from the browser if you select this
|
||||
access mode.
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
{access === 'proxy' && (
|
||||
<div className="gf-form-inline">
|
||||
<div className="gf-form">
|
||||
<span className="gf-form-label width-10">Whitelisted Cookies</span>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<h3 className="page-heading">Auth</h3>
|
||||
<div className="gf-form-group">
|
||||
<div className="gf-form-inline">
|
||||
<FormSwitch
|
||||
onChange={this.onBasicAuthChange}
|
||||
label="Basic auth"
|
||||
checked={dataSource.basicAuth}
|
||||
labelClass="width-10"
|
||||
switchClass="max-width-6"
|
||||
/>
|
||||
<FormSwitch
|
||||
label="With credentials"
|
||||
checked={dataSource.withCredentials}
|
||||
onChange={this.onWithCredentialsChange}
|
||||
labelClass="width-10"
|
||||
switchClass="max-width-6"
|
||||
/>
|
||||
</div>
|
||||
<div className="gf-form-inline">
|
||||
{dataSource.jsonData && [
|
||||
<FormSwitch
|
||||
key="TLS CLient Auth"
|
||||
label="TLS CLient Auth"
|
||||
checked={dataSource.jsonData.authType === 'tlsAuth'}
|
||||
onChange={this.onTlsAuthChange}
|
||||
labelClass="width-10"
|
||||
switchClass="max-width-6"
|
||||
/>,
|
||||
<FormSwitch
|
||||
key="With CA Cert"
|
||||
label="With CA Cert"
|
||||
checked={dataSource.jsonData.authType === 'tlsAuthWithCACert'}
|
||||
onChange={this.onTlsAuthWithCACertChange}
|
||||
labelClass="width-10"
|
||||
switchClass="max-width-6"
|
||||
/>,
|
||||
]}
|
||||
</div>
|
||||
</div>
|
||||
<div className="gf-form-inline">
|
||||
{dataSource.jsonData && (
|
||||
<FormSwitch
|
||||
label="Skip TLS Verify"
|
||||
checked={dataSource.jsonData.authType === 'tlsSkipVerify'}
|
||||
onChange={this.onTlsSkipVerifyChange}
|
||||
labelClass="width-10"
|
||||
switchClass="max-width-6"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{dataSource.basicAuth && (
|
||||
<div className="gf-form-group">
|
||||
<h6>Basic Auth Details</h6>
|
||||
<div className="gf-form">
|
||||
<span className="gf-form-label width-10">User</span>
|
||||
<input className="gf-form-input max-width-21" type="text" value={basicAuthUser} placeholder="User" />
|
||||
</div>
|
||||
<div className="gf-form">
|
||||
<span className="gf-form-label width-10">Password</span>
|
||||
<input
|
||||
className="gf-form-input max-width-21"
|
||||
type="password"
|
||||
value={basicAuthPassword}
|
||||
placeholder="Password"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{(tlsAuth || tlsAuthWithCACert) &&
|
||||
access === 'proxy' && (
|
||||
<div className="gf-form-group">
|
||||
<div className="gf-form">
|
||||
<h6>TLS Auth Details</h6>
|
||||
</div>
|
||||
{tlsAuthWithCACert && (
|
||||
<div>
|
||||
<div className="gf-form-inline">
|
||||
<div className="gf-form gf-form--v-stretch">
|
||||
<label className="gf-form-label width-7">CA Cert</label>
|
||||
</div>
|
||||
{!tlsCACert && (
|
||||
<div className="gf-form gf-form--grow">
|
||||
<textarea
|
||||
rows={7}
|
||||
className="gf-form-input gf-form-textarea"
|
||||
value={tlsCACert}
|
||||
placeholder="Begins with -----BEGIN CERTIFICATE-----"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
{tlsCACert && (
|
||||
<div className="gf-form">
|
||||
<input type="text" className="gf-form-input max-width-12" value="configured" />
|
||||
<a className="btn btn-secondary gf-form-btn" href="#" onClick={() => {}}>
|
||||
reset
|
||||
</a>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{tlsAuth && (
|
||||
<div>
|
||||
<div className="gf-form-inline">
|
||||
<div className="gf-form gf-form--v-stretch">
|
||||
<label className="gf-form-label width-7">Client Cert</label>
|
||||
</div>
|
||||
{!tlsClientCert && (
|
||||
<div className="gf-form gf-form--grow">
|
||||
<textarea
|
||||
rows={7}
|
||||
className="gf-form-input gf-form-textarea"
|
||||
value={tlsClientCert}
|
||||
placeholder="Begins with -----BEGIN CERTIFICATE-----"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
{tlsClientCert && (
|
||||
<div className="gf-form">
|
||||
<input type="text" className="gf-form-input max-width-12" value="configured" />
|
||||
<a className="btn btn-secondary gf-form-btn" href="#" onClick={() => {}}>
|
||||
reset
|
||||
</a>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="gf-form-inline">
|
||||
<div className="gf-form gf-form--v-stretch">
|
||||
<label className="gf-form-label width-7">Client Key</label>
|
||||
</div>
|
||||
{tlsClientKey && (
|
||||
<div className="gf-form gf-form--grow">
|
||||
<textarea
|
||||
rows={7}
|
||||
className="gf-form-input gf-form-textarea"
|
||||
value={tlsClientKey}
|
||||
placeholder="Begins with -----BEGIN RSA PRIVATE KEY-----"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
{tlsClientKey && (
|
||||
<div className="gf-form">
|
||||
<input type="text" className="gf-form-input max-width-12" value="configured" />
|
||||
<a className="btn btn-secondary gf-form-btn" href="#" onClick={() => {}}>
|
||||
reset
|
||||
</a>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function mapStateToProps(state) {
|
||||
return {
|
||||
dataSource: state.dataSources.dataSource,
|
||||
};
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps)(DataSourceHttpSettings);
|
40
public/app/features/datasources/DataSourcePluginSettings.tsx
Normal file
40
public/app/features/datasources/DataSourcePluginSettings.tsx
Normal file
@ -0,0 +1,40 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
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> {
|
||||
element: any;
|
||||
component: AngularComponent;
|
||||
|
||||
componentDidMount() {
|
||||
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,
|
||||
},
|
||||
};
|
||||
|
||||
this.component = loader.load(this.element, scopeProps, template);
|
||||
}
|
||||
|
||||
render() {
|
||||
return <div ref={element => (this.element = element)} />;
|
||||
}
|
||||
}
|
||||
|
||||
export default DataSourcePluginSettings;
|
@ -1,11 +1,15 @@
|
||||
import React, { createRef, PureComponent } from 'react';
|
||||
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 { importPluginModule } from '../plugins/plugin_loader';
|
||||
import { loadDataSource } from './state/actions';
|
||||
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';
|
||||
|
||||
export interface Props {
|
||||
navModel: NavModel;
|
||||
@ -13,6 +17,7 @@ export interface Props {
|
||||
dataSourceMeta: Plugin;
|
||||
pageId: number;
|
||||
loadDataSource: typeof loadDataSource;
|
||||
setDataSourceName: typeof setDataSourceName;
|
||||
}
|
||||
interface State {
|
||||
name: string;
|
||||
@ -25,28 +30,12 @@ enum DataSourceStates {
|
||||
}
|
||||
|
||||
export class DataSourceSettings extends PureComponent<Props, State> {
|
||||
settingsElement = createRef<HTMLDivElement>();
|
||||
|
||||
state = {
|
||||
name: this.props.dataSource.name,
|
||||
showNamePopover: false,
|
||||
};
|
||||
|
||||
async componentDidMount() {
|
||||
const { loadDataSource, pageId } = this.props;
|
||||
|
||||
await loadDataSource(pageId);
|
||||
importPluginModule(this.props.dataSourceMeta.module).then(pluginExports => {
|
||||
console.log(pluginExports);
|
||||
});
|
||||
}
|
||||
|
||||
onNameChange = event => {
|
||||
this.setState({
|
||||
name: event.target.value,
|
||||
});
|
||||
};
|
||||
|
||||
onSubmit = event => {
|
||||
event.preventDefault();
|
||||
console.log(event);
|
||||
@ -56,12 +45,6 @@ export class DataSourceSettings extends PureComponent<Props, State> {
|
||||
console.log(event);
|
||||
};
|
||||
|
||||
onTogglePopover = () => {
|
||||
this.setState(prevState => ({
|
||||
showNamePopover: !prevState.showNamePopover,
|
||||
}));
|
||||
};
|
||||
|
||||
isReadyOnly() {
|
||||
return this.props.dataSource.readOnly === true;
|
||||
}
|
||||
@ -93,74 +76,74 @@ export class DataSourceSettings extends PureComponent<Props, State> {
|
||||
}
|
||||
|
||||
render() {
|
||||
const { name, showNamePopover } = this.state;
|
||||
|
||||
console.log(this.props);
|
||||
const { dataSource, dataSourceMeta, navModel } = this.props;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<PageHeader model={this.props.navModel} />
|
||||
<div className="page-container page-body">
|
||||
<div>
|
||||
<form onSubmit={this.onSubmit}>
|
||||
<div className="gf-form-group">
|
||||
<div className="gf-form-inline">
|
||||
<PageHeader model={navModel} />
|
||||
{Object.keys(dataSource).length === 0 && Object.keys(dataSourceMeta).length === 0 ? (
|
||||
<PageLoader pageName="Data source settings" />
|
||||
) : (
|
||||
<div className="page-container page-body">
|
||||
<div>
|
||||
<form onSubmit={this.onSubmit}>
|
||||
<div className="gf-form-group">
|
||||
<div className="gf-form max-width-30">
|
||||
<span className="gf-form-label width-10">Name</span>
|
||||
<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={name}
|
||||
value={this.props.dataSource.name}
|
||||
placeholder="Name"
|
||||
onChange={this.onNameChange}
|
||||
onChange={event => this.props.setDataSourceName(event.target.value)}
|
||||
required
|
||||
/>
|
||||
<div onClick={this.onTogglePopover}>
|
||||
<i className="fa fa-info-circle" />
|
||||
</div>
|
||||
{showNamePopover && (
|
||||
<div
|
||||
style={{
|
||||
position: 'absolute',
|
||||
left: '450px',
|
||||
top: '-20px',
|
||||
padding: '10px',
|
||||
backgroundColor: 'black',
|
||||
zIndex: 2,
|
||||
width: '300px',
|
||||
border: '1px solid gray',
|
||||
borderRadius: '3px',
|
||||
}}
|
||||
>
|
||||
The name is used when you select the data source in panels. The <em>Default</em> data source is
|
||||
preselected in new panels.
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{this.shouldRenderInfoBox() && <div className="grafana-info-box">{this.getInfoText()}</div>}
|
||||
{this.isReadyOnly() && (
|
||||
<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.
|
||||
|
||||
{this.shouldRenderInfoBox() && <div className="grafana-info-box">{this.getInfoText()}</div>}
|
||||
|
||||
{this.isReadyOnly() ? (
|
||||
<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} />
|
||||
)}
|
||||
|
||||
<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>
|
||||
)}
|
||||
<div ref={this.settingsElement} />
|
||||
<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>
|
||||
</form>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@ -171,7 +154,7 @@ function mapStateToProps(state) {
|
||||
|
||||
return {
|
||||
navModel: getNavModel(state.navIndex, `datasource-settings-${pageId}`),
|
||||
dataSource: state.dataSources.dataSource,
|
||||
dataSource: getDataSource(state.dataSources, pageId),
|
||||
dataSourceMeta: state.dataSources.dataSourceMeta,
|
||||
pageId: pageId,
|
||||
};
|
||||
@ -179,6 +162,7 @@ function mapStateToProps(state) {
|
||||
|
||||
const mapDispatchToProps = {
|
||||
loadDataSource,
|
||||
setDataSourceName,
|
||||
};
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(DataSourceSettings);
|
||||
export default hot(module)(connect(mapStateToProps, mapDispatchToProps)(DataSourceSettings));
|
||||
|
@ -1,177 +0,0 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Render should render component 1`] = `
|
||||
<div
|
||||
className="gf-form-inline cta-form"
|
||||
>
|
||||
<button
|
||||
className="cta-form__close btn btn-transparent"
|
||||
onClick={[MockFunction]}
|
||||
>
|
||||
<i
|
||||
className="fa fa-close"
|
||||
/>
|
||||
</button>
|
||||
<form
|
||||
name="addPermission"
|
||||
onSubmit={[Function]}
|
||||
>
|
||||
<h5>
|
||||
Add Permission For
|
||||
</h5>
|
||||
<div
|
||||
className="gf-form-inline"
|
||||
>
|
||||
<div
|
||||
className="gf-form"
|
||||
>
|
||||
<select
|
||||
className="gf-form-input gf-size-auto"
|
||||
onChange={[Function]}
|
||||
value="Team"
|
||||
>
|
||||
<option
|
||||
key="0"
|
||||
value="Team"
|
||||
>
|
||||
Team
|
||||
</option>
|
||||
<option
|
||||
key="1"
|
||||
value="User"
|
||||
>
|
||||
User
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
<div
|
||||
className="gf-form"
|
||||
>
|
||||
<TeamPicker
|
||||
className="width-20"
|
||||
onSelected={[Function]}
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className="gf-form"
|
||||
>
|
||||
<DescriptionPicker
|
||||
className="gf-form-input--form-dropdown-right"
|
||||
disabled={false}
|
||||
onSelected={[Function]}
|
||||
optionsWithDesc={
|
||||
Array [
|
||||
Object {
|
||||
"description": "Can query data source.",
|
||||
"label": "Query",
|
||||
"value": 1,
|
||||
},
|
||||
]
|
||||
}
|
||||
value={1}
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className="gf-form"
|
||||
>
|
||||
<button
|
||||
className="btn btn-success"
|
||||
data-save-permission={true}
|
||||
disabled={true}
|
||||
type="submit"
|
||||
>
|
||||
Save
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`Render should render user picker 1`] = `
|
||||
<div
|
||||
className="gf-form-inline cta-form"
|
||||
>
|
||||
<button
|
||||
className="cta-form__close btn btn-transparent"
|
||||
onClick={[MockFunction]}
|
||||
>
|
||||
<i
|
||||
className="fa fa-close"
|
||||
/>
|
||||
</button>
|
||||
<form
|
||||
name="addPermission"
|
||||
onSubmit={[Function]}
|
||||
>
|
||||
<h5>
|
||||
Add Permission For
|
||||
</h5>
|
||||
<div
|
||||
className="gf-form-inline"
|
||||
>
|
||||
<div
|
||||
className="gf-form"
|
||||
>
|
||||
<select
|
||||
className="gf-form-input gf-size-auto"
|
||||
onChange={[Function]}
|
||||
value="User"
|
||||
>
|
||||
<option
|
||||
key="0"
|
||||
value="Team"
|
||||
>
|
||||
Team
|
||||
</option>
|
||||
<option
|
||||
key="1"
|
||||
value="User"
|
||||
>
|
||||
User
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
<div
|
||||
className="gf-form"
|
||||
>
|
||||
<UserPicker
|
||||
className="width-20"
|
||||
onSelected={[Function]}
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className="gf-form"
|
||||
>
|
||||
<DescriptionPicker
|
||||
className="gf-form-input--form-dropdown-right"
|
||||
disabled={false}
|
||||
onSelected={[Function]}
|
||||
optionsWithDesc={
|
||||
Array [
|
||||
Object {
|
||||
"description": "Can query data source.",
|
||||
"label": "Query",
|
||||
"value": 1,
|
||||
},
|
||||
]
|
||||
}
|
||||
value={1}
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className="gf-form"
|
||||
>
|
||||
<button
|
||||
className="btn btn-success"
|
||||
data-save-permission={true}
|
||||
disabled={true}
|
||||
type="submit"
|
||||
>
|
||||
Save
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
`;
|
@ -1,327 +0,0 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Render should render component 1`] = `
|
||||
<table
|
||||
className="filter-table gf-form-group"
|
||||
>
|
||||
<tbody>
|
||||
<tr
|
||||
className="gf-form-disabled"
|
||||
>
|
||||
<td
|
||||
style={
|
||||
Object {
|
||||
"width": "1%",
|
||||
}
|
||||
}
|
||||
>
|
||||
<i
|
||||
className="gicon gicon-shield"
|
||||
style={
|
||||
Object {
|
||||
"height": "25px",
|
||||
"width": "25px",
|
||||
}
|
||||
}
|
||||
/>
|
||||
</td>
|
||||
<td
|
||||
style={
|
||||
Object {
|
||||
"width": "90%",
|
||||
}
|
||||
}
|
||||
>
|
||||
Admin
|
||||
<span
|
||||
className="filter-table__weak-italic"
|
||||
>
|
||||
(Role)
|
||||
</span>
|
||||
</td>
|
||||
<td />
|
||||
<td
|
||||
className="query-keyword"
|
||||
>
|
||||
Can
|
||||
</td>
|
||||
<td>
|
||||
<div
|
||||
className="gf-form"
|
||||
>
|
||||
<DescriptionPicker
|
||||
className="gf-form-input--form-dropdown-right"
|
||||
disabled={true}
|
||||
onSelected={[Function]}
|
||||
optionsWithDesc={
|
||||
Array [
|
||||
Object {
|
||||
"description": "Can query data source.",
|
||||
"label": "Query",
|
||||
"value": 1,
|
||||
},
|
||||
Object {
|
||||
"description": "",
|
||||
"label": "Admin",
|
||||
"value": 2,
|
||||
},
|
||||
]
|
||||
}
|
||||
value={2}
|
||||
/>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<button
|
||||
className="btn btn-inverse btn-small"
|
||||
>
|
||||
<i
|
||||
className="fa fa-lock"
|
||||
/>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
`;
|
||||
|
||||
exports[`Render should render items 1`] = `
|
||||
<table
|
||||
className="filter-table gf-form-group"
|
||||
>
|
||||
<tbody>
|
||||
<tr
|
||||
className="gf-form-disabled"
|
||||
>
|
||||
<td
|
||||
style={
|
||||
Object {
|
||||
"width": "1%",
|
||||
}
|
||||
}
|
||||
>
|
||||
<i
|
||||
className="gicon gicon-shield"
|
||||
style={
|
||||
Object {
|
||||
"height": "25px",
|
||||
"width": "25px",
|
||||
}
|
||||
}
|
||||
/>
|
||||
</td>
|
||||
<td
|
||||
style={
|
||||
Object {
|
||||
"width": "90%",
|
||||
}
|
||||
}
|
||||
>
|
||||
Admin
|
||||
<span
|
||||
className="filter-table__weak-italic"
|
||||
>
|
||||
(Role)
|
||||
</span>
|
||||
</td>
|
||||
<td />
|
||||
<td
|
||||
className="query-keyword"
|
||||
>
|
||||
Can
|
||||
</td>
|
||||
<td>
|
||||
<div
|
||||
className="gf-form"
|
||||
>
|
||||
<DescriptionPicker
|
||||
className="gf-form-input--form-dropdown-right"
|
||||
disabled={true}
|
||||
onSelected={[Function]}
|
||||
optionsWithDesc={
|
||||
Array [
|
||||
Object {
|
||||
"description": "Can query data source.",
|
||||
"label": "Query",
|
||||
"value": 1,
|
||||
},
|
||||
Object {
|
||||
"description": "",
|
||||
"label": "Admin",
|
||||
"value": 2,
|
||||
},
|
||||
]
|
||||
}
|
||||
value={2}
|
||||
/>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<button
|
||||
className="btn btn-inverse btn-small"
|
||||
>
|
||||
<i
|
||||
className="fa fa-lock"
|
||||
/>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
key="2-0"
|
||||
>
|
||||
<td
|
||||
style={
|
||||
Object {
|
||||
"width": "1%",
|
||||
}
|
||||
}
|
||||
>
|
||||
<img
|
||||
className="filter-table__avatar"
|
||||
src="/avatar/926aa85c6bcefa0b4deca3223f337ae1"
|
||||
/>
|
||||
</td>
|
||||
<td
|
||||
style={
|
||||
Object {
|
||||
"width": "90%",
|
||||
}
|
||||
}
|
||||
>
|
||||
<span
|
||||
key="name"
|
||||
>
|
||||
testUser
|
||||
|
||||
</span>
|
||||
<span
|
||||
className="filter-table__weak-italic"
|
||||
key="description"
|
||||
>
|
||||
(User)
|
||||
</span>
|
||||
</td>
|
||||
<td />
|
||||
<td
|
||||
className="query-keyword"
|
||||
>
|
||||
Can
|
||||
</td>
|
||||
<td>
|
||||
<div
|
||||
className="gf-form"
|
||||
>
|
||||
<DescriptionPicker
|
||||
className="gf-form-input--form-dropdown-right"
|
||||
disabled={true}
|
||||
onSelected={[Function]}
|
||||
optionsWithDesc={
|
||||
Array [
|
||||
Object {
|
||||
"description": "Can query data source.",
|
||||
"label": "Query",
|
||||
"value": 1,
|
||||
},
|
||||
Object {
|
||||
"description": "",
|
||||
"label": "Admin",
|
||||
"value": 2,
|
||||
},
|
||||
]
|
||||
}
|
||||
value={1}
|
||||
/>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<button
|
||||
className="btn btn-danger btn-small"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<i
|
||||
className="fa fa-remove"
|
||||
/>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
key="6-1"
|
||||
>
|
||||
<td
|
||||
style={
|
||||
Object {
|
||||
"width": "1%",
|
||||
}
|
||||
}
|
||||
>
|
||||
<img
|
||||
className="filter-table__avatar"
|
||||
src="/avatar/93c0801b955cbd443a8cfa91a401d7bc"
|
||||
/>
|
||||
</td>
|
||||
<td
|
||||
style={
|
||||
Object {
|
||||
"width": "90%",
|
||||
}
|
||||
}
|
||||
>
|
||||
<span
|
||||
key="name"
|
||||
>
|
||||
A-team
|
||||
|
||||
</span>
|
||||
<span
|
||||
className="filter-table__weak-italic"
|
||||
key="description"
|
||||
>
|
||||
(Team)
|
||||
</span>
|
||||
</td>
|
||||
<td />
|
||||
<td
|
||||
className="query-keyword"
|
||||
>
|
||||
Can
|
||||
</td>
|
||||
<td>
|
||||
<div
|
||||
className="gf-form"
|
||||
>
|
||||
<DescriptionPicker
|
||||
className="gf-form-input--form-dropdown-right"
|
||||
disabled={true}
|
||||
onSelected={[Function]}
|
||||
optionsWithDesc={
|
||||
Array [
|
||||
Object {
|
||||
"description": "Can query data source.",
|
||||
"label": "Query",
|
||||
"value": 1,
|
||||
},
|
||||
Object {
|
||||
"description": "",
|
||||
"label": "Admin",
|
||||
"value": 2,
|
||||
},
|
||||
]
|
||||
}
|
||||
value={1}
|
||||
/>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<button
|
||||
className="btn btn-danger btn-small"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<i
|
||||
className="fa fa-remove"
|
||||
/>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
`;
|
@ -1,27 +0,0 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Render should render component 1`] = `
|
||||
<div>
|
||||
<PageHeader
|
||||
model={Object {}}
|
||||
/>
|
||||
<div
|
||||
className="page-container page-body"
|
||||
>
|
||||
<Connect(DataSourceSettings) />
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`Render should render permissions page 1`] = `
|
||||
<div>
|
||||
<PageHeader
|
||||
model={Object {}}
|
||||
/>
|
||||
<div
|
||||
className="page-container page-body"
|
||||
>
|
||||
<Connect(DataSourcePermissions) />
|
||||
</div>
|
||||
</div>
|
||||
`;
|
@ -14,43 +14,49 @@ export enum ActionTypes {
|
||||
SetDataSourcesSearchQuery = 'SET_DATA_SOURCES_SEARCH_QUERY',
|
||||
SetDataSourcesLayoutMode = 'SET_DATA_SOURCES_LAYOUT_MODE',
|
||||
SetDataSourceTypeSearchQuery = 'SET_DATA_SOURCE_TYPE_SEARCH_QUERY',
|
||||
SetDataSourceName = 'SET_DATA_SOURCE_NAME',
|
||||
}
|
||||
|
||||
export interface LoadDataSourcesAction {
|
||||
interface LoadDataSourcesAction {
|
||||
type: ActionTypes.LoadDataSources;
|
||||
payload: DataSource[];
|
||||
}
|
||||
|
||||
export interface SetDataSourcesSearchQueryAction {
|
||||
interface SetDataSourcesSearchQueryAction {
|
||||
type: ActionTypes.SetDataSourcesSearchQuery;
|
||||
payload: string;
|
||||
}
|
||||
|
||||
export interface SetDataSourcesLayoutModeAction {
|
||||
interface SetDataSourcesLayoutModeAction {
|
||||
type: ActionTypes.SetDataSourcesLayoutMode;
|
||||
payload: LayoutMode;
|
||||
}
|
||||
|
||||
export interface LoadDataSourceTypesAction {
|
||||
interface LoadDataSourceTypesAction {
|
||||
type: ActionTypes.LoadDataSourceTypes;
|
||||
payload: Plugin[];
|
||||
}
|
||||
|
||||
export interface SetDataSourceTypeSearchQueryAction {
|
||||
interface SetDataSourceTypeSearchQueryAction {
|
||||
type: ActionTypes.SetDataSourceTypeSearchQuery;
|
||||
payload: string;
|
||||
}
|
||||
|
||||
export interface LoadDataSourceAction {
|
||||
interface LoadDataSourceAction {
|
||||
type: ActionTypes.LoadDataSource;
|
||||
payload: DataSource;
|
||||
}
|
||||
|
||||
export interface LoadDataSourceMetaAction {
|
||||
interface LoadDataSourceMetaAction {
|
||||
type: ActionTypes.LoadDataSourceMeta;
|
||||
payload: Plugin;
|
||||
}
|
||||
|
||||
interface SetDataSourceNameAction {
|
||||
type: ActionTypes.SetDataSourceName;
|
||||
payload: string;
|
||||
}
|
||||
|
||||
const dataSourcesLoaded = (dataSources: DataSource[]): LoadDataSourcesAction => ({
|
||||
type: ActionTypes.LoadDataSources,
|
||||
payload: dataSources,
|
||||
@ -86,6 +92,11 @@ export const setDataSourceTypeSearchQuery = (query: string): SetDataSourceTypeSe
|
||||
payload: query,
|
||||
});
|
||||
|
||||
export const setDataSourceName = (name: string) => ({
|
||||
type: ActionTypes.SetDataSourceName,
|
||||
payload: name,
|
||||
});
|
||||
|
||||
export type Action =
|
||||
| LoadDataSourcesAction
|
||||
| SetDataSourcesSearchQueryAction
|
||||
@ -95,7 +106,8 @@ export type Action =
|
||||
| SetDataSourceTypeSearchQueryAction
|
||||
| LoadDataSourceAction
|
||||
| UpdateNavIndexAction
|
||||
| LoadDataSourceMetaAction;
|
||||
| LoadDataSourceMetaAction
|
||||
| SetDataSourceNameAction;
|
||||
|
||||
type ThunkResult<R> = ThunkAction<R, StoreState, undefined, Action>;
|
||||
|
||||
|
@ -20,7 +20,7 @@ export const getDataSource = (state, dataSourceId): DataSource | null => {
|
||||
if (state.dataSource.id === parseInt(dataSourceId, 10)) {
|
||||
return state.dataSource;
|
||||
}
|
||||
return null;
|
||||
return {} as DataSource;
|
||||
};
|
||||
|
||||
export const getDataSourcesSearchQuery = state => state.searchQuery;
|
||||
|
@ -47,7 +47,7 @@ module.exports = merge(common, {
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.tsx?$/,
|
||||
test: /(?!.*\.test)\.tsx$/,
|
||||
exclude: /node_modules/,
|
||||
use: [{
|
||||
loader: 'babel-loader',
|
||||
|
Loading…
Reference in New Issue
Block a user