mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
tests
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
import { AddDataSourcePermissions, Props } from './AddDataSourcePermissions';
|
||||
import { AclTarget } from '../../types/acl';
|
||||
|
||||
const setup = () => {
|
||||
const props: Props = {
|
||||
onAddPermission: jest.fn(),
|
||||
onCancel: jest.fn(),
|
||||
};
|
||||
|
||||
return shallow(<AddDataSourcePermissions {...props} />);
|
||||
};
|
||||
|
||||
describe('Render', () => {
|
||||
it('should render component', () => {
|
||||
const wrapper = setup();
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should render user picker', () => {
|
||||
const wrapper = setup();
|
||||
|
||||
wrapper.instance().setState({ type: AclTarget.User });
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,77 @@
|
||||
import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
import { DataSourcePermissions, Props } from './DataSourcePermissions';
|
||||
import { DataSourcePermission, DataSourcePermissionDTO } from 'app/types';
|
||||
import { AclTarget, dashboardPermissionLevels } from '../../types/acl';
|
||||
|
||||
const setup = (propOverrides?: object) => {
|
||||
const props: Props = {
|
||||
dataSourcePermission: {} as DataSourcePermissionDTO,
|
||||
pageId: 1,
|
||||
addDataSourcePermission: jest.fn(),
|
||||
enableDataSourcePermissions: jest.fn(),
|
||||
disableDataSourcePermissions: jest.fn(),
|
||||
loadDataSourcePermissions: jest.fn(),
|
||||
removeDataSourcePermission: jest.fn(),
|
||||
};
|
||||
|
||||
Object.assign(props, propOverrides);
|
||||
|
||||
const wrapper = shallow(<DataSourcePermissions {...props} />);
|
||||
const instance = wrapper.instance() as DataSourcePermissions;
|
||||
|
||||
return {
|
||||
wrapper,
|
||||
instance,
|
||||
};
|
||||
};
|
||||
|
||||
describe('Render', () => {
|
||||
it('should render component', () => {
|
||||
const { wrapper } = setup();
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should render permissions enabled', () => {
|
||||
const { wrapper } = setup({
|
||||
dataSourcePermission: {
|
||||
enabled: true,
|
||||
datasourceId: 1,
|
||||
permissions: [] as DataSourcePermission[],
|
||||
},
|
||||
});
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Functions', () => {
|
||||
describe('on add permissions', () => {
|
||||
const { instance } = setup();
|
||||
|
||||
it('should add permissions for team', () => {
|
||||
const mockState = {
|
||||
permission: dashboardPermissionLevels[0].value,
|
||||
teamId: 1,
|
||||
type: AclTarget.Team,
|
||||
};
|
||||
|
||||
instance.onAddPermission(mockState);
|
||||
|
||||
expect(instance.props.addDataSourcePermission).toHaveBeenCalledWith(1, { teamId: 1, permission: 1 });
|
||||
});
|
||||
|
||||
it('should add permissions for user', () => {
|
||||
const mockState = {
|
||||
permission: dashboardPermissionLevels[0].value,
|
||||
userId: 1,
|
||||
type: AclTarget.User,
|
||||
};
|
||||
|
||||
instance.onAddPermission(mockState);
|
||||
|
||||
expect(instance.props.addDataSourcePermission).toHaveBeenCalledWith(1, { userId: 1, permission: 1 });
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -11,11 +11,11 @@ import {
|
||||
loadDataSourcePermissions,
|
||||
removeDataSourcePermission,
|
||||
} from './state/actions';
|
||||
import { DataSourcePermission } from 'app/types';
|
||||
import { DataSourcePermissionDTO } from 'app/types';
|
||||
import { getRouteParamsId } from '../../core/selectors/location';
|
||||
|
||||
export interface Props {
|
||||
dataSourcePermission: { enabled: boolean; datasouceId: number; permissions: DataSourcePermission[] };
|
||||
dataSourcePermission: DataSourcePermissionDTO;
|
||||
pageId: number;
|
||||
addDataSourcePermission: typeof addDataSourcePermission;
|
||||
enableDataSourcePermissions: typeof enableDataSourcePermissions;
|
||||
@@ -64,17 +64,13 @@ export class DataSourcePermissions extends PureComponent<Props, State> {
|
||||
const { pageId, addDataSourcePermission } = this.props;
|
||||
const data = {
|
||||
permission: state.permission,
|
||||
userId: 0,
|
||||
teamId: 0,
|
||||
};
|
||||
|
||||
if (state.type === AclTarget.Team) {
|
||||
data.teamId = state.teamId;
|
||||
addDataSourcePermission(pageId, Object.assign(data, { teamId: state.teamId }));
|
||||
} else if (state.type === AclTarget.User) {
|
||||
data.userId = state.userId;
|
||||
addDataSourcePermission(pageId, Object.assign(data, { userId: state.userId }));
|
||||
}
|
||||
|
||||
addDataSourcePermission(pageId, data);
|
||||
};
|
||||
|
||||
onRemovePermission = item => {
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
import { DataSourcePermissionsList, Props } from './DataSourcePermissionsList';
|
||||
import { DataSourcePermission } from '../../types';
|
||||
import { getMockDataSourcePermissionsTeam, getMockDataSourcePermissionsUser } from './__mocks__/dataSourcesMocks';
|
||||
|
||||
const setup = (propOverrides?: object) => {
|
||||
const props: Props = {
|
||||
items: [] as DataSourcePermission[],
|
||||
onRemoveItem: jest.fn(),
|
||||
};
|
||||
|
||||
Object.assign(props, propOverrides);
|
||||
|
||||
return shallow(<DataSourcePermissionsList {...props} />);
|
||||
};
|
||||
|
||||
describe('Render', () => {
|
||||
it('should render component', () => {
|
||||
const wrapper = setup();
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should render items', () => {
|
||||
const wrapper = setup({
|
||||
items: [getMockDataSourcePermissionsUser(), getMockDataSourcePermissionsTeam()],
|
||||
});
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
@@ -3,7 +3,7 @@ import { DataSourcePermission } from '../../types';
|
||||
import { dataSourceAclLevels, DataSourcePermissionLevel } from '../../types/acl';
|
||||
import DescriptionPicker from '../../core/components/Picker/DescriptionPicker';
|
||||
|
||||
interface Props {
|
||||
export interface Props {
|
||||
items: DataSourcePermission[];
|
||||
onRemoveItem: (item) => void;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { DataSource } from 'app/types';
|
||||
import { DataSource, DataSourcePermission } from 'app/types';
|
||||
|
||||
export const getMockDataSources = (amount: number): DataSource[] => {
|
||||
const dataSources = [];
|
||||
@@ -43,3 +43,32 @@ export const getMockDataSource = (): DataSource => {
|
||||
user: '',
|
||||
};
|
||||
};
|
||||
|
||||
export const getMockDataSourcePermissionsUser = (): DataSourcePermission => {
|
||||
return {
|
||||
created: '2018-10-10T16:50:45+02:00',
|
||||
datasourceId: 1,
|
||||
id: 2,
|
||||
permission: 1,
|
||||
permissionName: 'Query',
|
||||
updated: '2018-10-10T16:50:45+02:00',
|
||||
userAvatarUrl: '/avatar/926aa85c6bcefa0b4deca3223f337ae1',
|
||||
userEmail: 'test@test.com',
|
||||
userId: 3,
|
||||
userLogin: 'testUser',
|
||||
};
|
||||
};
|
||||
|
||||
export const getMockDataSourcePermissionsTeam = (): DataSourcePermission => {
|
||||
return {
|
||||
created: '2018-10-10T16:57:09+02:00',
|
||||
datasourceId: 1,
|
||||
id: 6,
|
||||
permission: 1,
|
||||
permissionName: 'Query',
|
||||
team: 'A-team',
|
||||
teamAvatarUrl: '/avatar/93c0801b955cbd443a8cfa91a401d7bc',
|
||||
teamId: 1,
|
||||
updated: '2018-10-10T16:57:09+02:00',
|
||||
};
|
||||
};
|
||||
|
||||
@@ -0,0 +1,179 @@
|
||||
// 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]}
|
||||
value="0"
|
||||
/>
|
||||
</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]}
|
||||
value="0"
|
||||
/>
|
||||
</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>
|
||||
`;
|
||||
@@ -0,0 +1,92 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Render should render component 1`] = `
|
||||
<div>
|
||||
<div
|
||||
className="page-action-bar"
|
||||
>
|
||||
<h3
|
||||
className="page-sub-heading"
|
||||
>
|
||||
Permissions
|
||||
</h3>
|
||||
<div
|
||||
className="page-action-bar__spacer"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className="empty-list-cta"
|
||||
>
|
||||
<div
|
||||
className="empty-list-cta__title"
|
||||
>
|
||||
Permissions not enabled for this data source.
|
||||
</div>
|
||||
<button
|
||||
className="empty-list-cta__button btn btn-xlarge btn-success"
|
||||
onClick={[Function]}
|
||||
>
|
||||
Enable
|
||||
</button>
|
||||
<div
|
||||
className="empty-list-cta__pro-tip"
|
||||
>
|
||||
<i
|
||||
className="fa fa-rocket"
|
||||
/>
|
||||
ProTip:
|
||||
|
||||
Only admins will be able to query the data source after you enable permissions.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`Render should render permissions enabled 1`] = `
|
||||
<div>
|
||||
<div
|
||||
className="page-action-bar"
|
||||
>
|
||||
<h3
|
||||
className="page-sub-heading"
|
||||
>
|
||||
Permissions
|
||||
</h3>
|
||||
<div
|
||||
className="page-action-bar__spacer"
|
||||
/>
|
||||
<button
|
||||
className="btn btn-success pull-right"
|
||||
disabled={false}
|
||||
key="add-permission"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<i
|
||||
className="fa fa-plus"
|
||||
/>
|
||||
Add Permission
|
||||
</button>
|
||||
<button
|
||||
className="btn btn-danger pull-right"
|
||||
key="disable-permissions"
|
||||
onClick={[Function]}
|
||||
>
|
||||
Disable Permissions
|
||||
</button>
|
||||
</div>
|
||||
<div>
|
||||
<Component
|
||||
in={false}
|
||||
>
|
||||
<AddDataSourcePermissions
|
||||
onAddPermission={[Function]}
|
||||
onCancel={[Function]}
|
||||
/>
|
||||
</Component>
|
||||
<DataSourcePermissionsList
|
||||
items={Array []}
|
||||
onRemoveItem={[Function]}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
@@ -0,0 +1,342 @@
|
||||
// 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,
|
||||
},
|
||||
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,
|
||||
},
|
||||
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,
|
||||
},
|
||||
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>
|
||||
`;
|
||||
Reference in New Issue
Block a user