Merge remote-tracking branch 'origin/data-source-instance-to-react' into permissions-code-to-enterprise

This commit is contained in:
Peter Holmberg 2018-10-17 10:00:18 +02:00
commit 776f9aa288
4 changed files with 625 additions and 1 deletions

View File

@ -22,7 +22,7 @@ func GetDataSources(c *m.ReqContext) Response {
Datasources: query.Result,
}
datasources := []*m.DataSource{}
var datasources []*m.DataSource
if err := bus.Dispatch(&dsFilterQuery); err != nil {
if err != bus.ErrHandlerNotFound {
return Error(500, "Could not get datasources", err)

View File

@ -0,0 +1,122 @@
import React, { PureComponent } from 'react';
import { UserPicker } from 'app/core/components/Picker/UserPicker';
import { Team, TeamPicker } from 'app/core/components/Picker/TeamPicker';
import DescriptionPicker, { OptionWithDescription } from 'app/core/components/Picker/DescriptionPicker';
import { dataSourceAclLevels, AclTarget, DataSourcePermissionLevel } from 'app/types/acl';
import { User } from 'app/types';
export interface Props {
onAddPermission: (state) => void;
onCancel: () => void;
}
interface State {
userId: number;
teamId: number;
type: AclTarget;
permission: DataSourcePermissionLevel;
}
export class AddDataSourcePermissions extends PureComponent<Props, State> {
cleanState = () => ({
userId: 0,
teamId: 0,
type: AclTarget.Team,
permission: DataSourcePermissionLevel.Query,
});
state = this.cleanState();
isValid() {
switch (this.state.type) {
case AclTarget.Team:
return this.state.teamId > 0;
case AclTarget.User:
return this.state.userId > 0;
}
return true;
}
onTeamSelected = (team: Team) => {
this.setState({ teamId: team ? team.id : 0 });
};
onUserSelected = (user: User) => {
this.setState({ userId: user ? user.id : 0 });
};
onPermissionChanged = (permission: OptionWithDescription) => {
this.setState({ permission: permission.value });
};
onTypeChanged = event => {
const type = event.target.value as AclTarget;
this.setState({ type: type, userId: 0, teamId: 0 });
};
onSubmit = async event => {
event.preventDefault();
await this.props.onAddPermission(this.state);
this.setState(this.cleanState());
};
render() {
const { onCancel } = this.props;
const { type } = this.state;
const pickerClassName = 'width-20';
const aclTargets = [{ value: AclTarget.Team, text: 'Team' }, { value: AclTarget.User, text: 'User' }];
return (
<div className="gf-form-inline cta-form">
<button className="cta-form__close btn btn-transparent" onClick={onCancel}>
<i className="fa fa-close" />
</button>
<form name="addPermission" onSubmit={this.onSubmit}>
<h5>Add Permission For</h5>
<div className="gf-form-inline">
<div className="gf-form">
<select className="gf-form-input gf-size-auto" value={type} onChange={this.onTypeChanged}>
{aclTargets.map((option, idx) => {
return (
<option key={idx} value={option.value}>
{option.text}
</option>
);
})}
</select>
</div>
{type === AclTarget.User && (
<div className="gf-form">
<UserPicker onSelected={this.onUserSelected} className={pickerClassName} />
</div>
)}
{type === AclTarget.Team && (
<div className="gf-form">
<TeamPicker onSelected={this.onTeamSelected} className={pickerClassName} />
</div>
)}
<div className="gf-form">
<DescriptionPicker
optionsWithDesc={dataSourceAclLevels}
onSelected={this.onPermissionChanged}
disabled={false}
className={'gf-form-input--form-dropdown-right'}
/>
</div>
<div className="gf-form">
<button data-save-permission className="btn btn-success" type="submit" disabled={!this.isValid()}>
Save
</button>
</div>
</div>
</form>
</div>
);
}
}
export default AddDataSourcePermissions;

View File

@ -0,0 +1,175 @@
// 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,
},
]
}
/>
</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,
},
]
}
/>
</div>
<div
className="gf-form"
>
<button
className="btn btn-success"
data-save-permission={true}
disabled={true}
type="submit"
>
Save
</button>
</div>
</div>
</form>
</div>
`;

View File

@ -0,0 +1,327 @@
// 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>
`;