mirror of
https://github.com/grafana/grafana.git
synced 2024-12-28 18:01:40 -06:00
Forms migration: Org users page (#23372)
* Migrate UsersActionBar * Invites table * Migrate Users page * Select version of OrgPicker * OrgRolePicker to use Select only * Fix modal issue * Move legacy Switch * Move from Forms folder * Fix failing test * Merge and fix issues * Update OrgRole issues * OrgUser type * Remove unused import * Update Snapshot
This commit is contained in:
parent
1864807b15
commit
cff70b6648
@ -23,18 +23,20 @@ const getKnobs = () => {
|
||||
'primary'
|
||||
),
|
||||
disabled: boolean('Disabled', false),
|
||||
closeOnConfirm: boolean('Close on confirm', true),
|
||||
};
|
||||
};
|
||||
|
||||
storiesOf('General/ConfirmButton', module)
|
||||
.addDecorator(withCenteredStory)
|
||||
.add('default', () => {
|
||||
const { size, buttonText, confirmText, confirmVariant, disabled } = getKnobs();
|
||||
const { size, buttonText, confirmText, confirmVariant, disabled, closeOnConfirm } = getKnobs();
|
||||
return (
|
||||
<>
|
||||
<div className="gf-form-group">
|
||||
<div className="gf-form">
|
||||
<ConfirmButton
|
||||
closeOnConfirm={closeOnConfirm}
|
||||
size={size}
|
||||
confirmText={confirmText}
|
||||
disabled={disabled}
|
||||
@ -51,12 +53,13 @@ storiesOf('General/ConfirmButton', module)
|
||||
);
|
||||
})
|
||||
.add('with custom button', () => {
|
||||
const { buttonText, confirmText, confirmVariant, disabled, size } = getKnobs();
|
||||
const { buttonText, confirmText, confirmVariant, disabled, size, closeOnConfirm } = getKnobs();
|
||||
return (
|
||||
<>
|
||||
<div className="gf-form-group">
|
||||
<div className="gf-form">
|
||||
<ConfirmButton
|
||||
closeOnConfirm={closeOnConfirm}
|
||||
size={size}
|
||||
confirmText={confirmText}
|
||||
disabled={disabled}
|
||||
|
@ -58,6 +58,7 @@ interface Props extends Themeable {
|
||||
confirmText?: string;
|
||||
disabled?: boolean;
|
||||
confirmVariant?: ButtonVariant;
|
||||
closeOnConfirm?: boolean;
|
||||
|
||||
onConfirm(): void;
|
||||
onClick?(): void;
|
||||
@ -105,6 +106,14 @@ class UnThemedConfirmButton extends PureComponent<Props, State> {
|
||||
this.props.onCancel();
|
||||
}
|
||||
};
|
||||
onConfirm = (event: SyntheticEvent) => {
|
||||
this.props.onConfirm();
|
||||
if (this.props.closeOnConfirm) {
|
||||
this.setState({
|
||||
showConfirm: false,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const {
|
||||
@ -114,7 +123,6 @@ class UnThemedConfirmButton extends PureComponent<Props, State> {
|
||||
disabled,
|
||||
confirmText,
|
||||
confirmVariant: confirmButtonVariant,
|
||||
onConfirm,
|
||||
children,
|
||||
} = this.props;
|
||||
const styles = getStyles(theme);
|
||||
@ -147,7 +155,7 @@ class UnThemedConfirmButton extends PureComponent<Props, State> {
|
||||
<Button size={size} variant="link" onClick={this.onClickCancel}>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button size={size} variant={confirmButtonVariant} onClick={onConfirm}>
|
||||
<Button size={size} variant={confirmButtonVariant} onClick={this.onConfirm}>
|
||||
{confirmText}
|
||||
</Button>
|
||||
</span>
|
||||
|
@ -143,6 +143,7 @@ export { HorizontalGroup, VerticalGroup, Container } from './Layout/Layout';
|
||||
export { RadioButtonGroup } from './Forms/RadioButtonGroup/RadioButtonGroup';
|
||||
|
||||
export { Input } from './Input/Input';
|
||||
export { FormInputSize } from './Forms/types';
|
||||
|
||||
export { Switch } from './Switch/Switch';
|
||||
export { Checkbox } from './Forms/Checkbox';
|
||||
|
@ -1,14 +1,21 @@
|
||||
import React, { FC } from 'react';
|
||||
import { OrgRole } from '@grafana/data';
|
||||
import { RadioButtonGroup } from '@grafana/ui';
|
||||
import { Select, FormInputSize } from '@grafana/ui';
|
||||
|
||||
interface Props {
|
||||
value: OrgRole;
|
||||
size?: FormInputSize;
|
||||
onChange: (role: OrgRole) => void;
|
||||
}
|
||||
|
||||
const options = Object.keys(OrgRole).map(key => ({ label: key, value: key }));
|
||||
|
||||
export const OrgRolePicker: FC<Props> = ({ value, onChange }) => (
|
||||
<RadioButtonGroup options={options} onChange={onChange} value={value} />
|
||||
export const OrgRolePicker: FC<Props> = ({ value, onChange, size }) => (
|
||||
<Select
|
||||
size={size}
|
||||
value={value}
|
||||
options={options}
|
||||
onChange={val => onChange(val.value as OrgRole)}
|
||||
placeholder="Choose role..."
|
||||
/>
|
||||
);
|
||||
|
@ -1,8 +1,8 @@
|
||||
import React, { createRef, PureComponent } from 'react';
|
||||
import React, { PureComponent } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { Invitee } from 'app/types';
|
||||
import { revokeInvite } from './state/actions';
|
||||
import { Icon } from '@grafana/ui';
|
||||
import { Button, ClipboardButton } from '@grafana/ui';
|
||||
|
||||
export interface Props {
|
||||
invitee: Invitee;
|
||||
@ -10,17 +10,6 @@ export interface Props {
|
||||
}
|
||||
|
||||
class InviteeRow extends PureComponent<Props> {
|
||||
private copyUrlRef = createRef<HTMLTextAreaElement>();
|
||||
|
||||
copyToClipboard = () => {
|
||||
const node = this.copyUrlRef.current;
|
||||
|
||||
if (node) {
|
||||
node.select();
|
||||
document.execCommand('copy');
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const { invitee, revokeInvite } = this.props;
|
||||
return (
|
||||
@ -28,21 +17,13 @@ class InviteeRow extends PureComponent<Props> {
|
||||
<td>{invitee.email}</td>
|
||||
<td>{invitee.name}</td>
|
||||
<td className="text-right">
|
||||
<button className="btn btn-inverse btn-small" onClick={this.copyToClipboard}>
|
||||
<textarea
|
||||
readOnly={true}
|
||||
value={invitee.url}
|
||||
style={{ position: 'absolute', bottom: 0, right: 0, opacity: 0, zIndex: -10 }}
|
||||
ref={this.copyUrlRef}
|
||||
/>
|
||||
<ClipboardButton variant="secondary" size="sm" getText={() => invitee.url}>
|
||||
Copy Invite
|
||||
</button>
|
||||
</ClipboardButton>
|
||||
|
||||
</td>
|
||||
<td>
|
||||
<button className="btn btn-danger btn-small" onClick={() => revokeInvite(invitee.code)}>
|
||||
<Icon name="times" style={{ marginBottom: 0 }} />
|
||||
</button>
|
||||
<Button variant="destructive" size="sm" icon="times" onClick={() => revokeInvite(invitee.code)} />
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
|
@ -1,9 +1,9 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import classNames from 'classnames';
|
||||
import { setUsersSearchQuery } from './state/reducers';
|
||||
import { getInviteesCount, getUsersSearchQuery } from './state/selectors';
|
||||
import { FilterInput } from 'app/core/components/FilterInput/FilterInput';
|
||||
import { RadioButtonGroup, LinkButton } from '@grafana/ui';
|
||||
|
||||
export interface Props {
|
||||
searchQuery: string;
|
||||
@ -28,18 +28,10 @@ export class UsersActionBar extends PureComponent<Props> {
|
||||
onShowInvites,
|
||||
showInvites,
|
||||
} = this.props;
|
||||
|
||||
const pendingInvitesButtonStyle = classNames({
|
||||
btn: true,
|
||||
'toggle-btn': true,
|
||||
active: showInvites,
|
||||
});
|
||||
|
||||
const usersButtonStyle = classNames({
|
||||
btn: true,
|
||||
'toggle-btn': true,
|
||||
active: !showInvites,
|
||||
});
|
||||
const options = [
|
||||
{ label: 'Users', value: 'users' },
|
||||
{ label: `Pending Invites (${pendingInvitesCount})`, value: 'invites' },
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="page-action-bar">
|
||||
@ -53,24 +45,15 @@ export class UsersActionBar extends PureComponent<Props> {
|
||||
/>
|
||||
{pendingInvitesCount > 0 && (
|
||||
<div style={{ marginLeft: '1rem' }}>
|
||||
<button className={usersButtonStyle} key="users" onClick={onShowInvites}>
|
||||
Users
|
||||
</button>
|
||||
<button className={pendingInvitesButtonStyle} onClick={onShowInvites} key="pending-invites">
|
||||
Pending Invites ({pendingInvitesCount})
|
||||
</button>
|
||||
<RadioButtonGroup value={showInvites ? 'invites' : 'users'} options={options} onChange={onShowInvites} />
|
||||
</div>
|
||||
)}
|
||||
<div className="page-action-bar__spacer" />
|
||||
{canInvite && (
|
||||
<a className="btn btn-primary" href="org/users/invite">
|
||||
<span>Invite</span>
|
||||
</a>
|
||||
)}
|
||||
{canInvite && <LinkButton href="org/users/invite">Invite</LinkButton>}
|
||||
{externalUserMngLinkUrl && (
|
||||
<a className="btn btn-primary" href={externalUserMngLinkUrl} target="_blank" rel="noopener">
|
||||
<LinkButton href={externalUserMngLinkUrl} target="_blank" rel="noopener">
|
||||
{externalUserMngLinkName}
|
||||
</a>
|
||||
</LinkButton>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -2,8 +2,7 @@ import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
import { Props, UsersListPage } from './UsersListPage';
|
||||
import { Invitee, OrgUser } from 'app/types';
|
||||
import { getMockUser } from './__mocks__/userMocks';
|
||||
import appEvents from '../../core/app_events';
|
||||
// import { getMockUser } from './__mocks__/userMocks';
|
||||
import { NavModel } from '@grafana/data';
|
||||
import { mockToolkitActionCreator } from 'test/core/redux/mocks';
|
||||
import { setUsersSearchQuery } from './state/reducers';
|
||||
@ -60,14 +59,3 @@ describe('Render', () => {
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Functions', () => {
|
||||
it('should emit show remove user modal', () => {
|
||||
const { instance } = setup();
|
||||
const mockUser = getMockUser();
|
||||
|
||||
instance.onRemoveUser(mockUser);
|
||||
|
||||
expect(appEvents.emit).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
@ -7,8 +7,7 @@ import Page from 'app/core/components/Page/Page';
|
||||
import UsersActionBar from './UsersActionBar';
|
||||
import UsersTable from './UsersTable';
|
||||
import InviteesTable from './InviteesTable';
|
||||
import { CoreEvents, Invitee, OrgUser } from 'app/types';
|
||||
import appEvents from 'app/core/app_events';
|
||||
import { Invitee, OrgUser, OrgRole } from 'app/types';
|
||||
import { loadInvitees, loadUsers, removeUser, updateUser } from './state/actions';
|
||||
import { getNavModel } from 'app/core/selectors/navModel';
|
||||
import { getInvitees, getUsers, getUsersSearchQuery } from './state/selectors';
|
||||
@ -60,24 +59,12 @@ export class UsersListPage extends PureComponent<Props, State> {
|
||||
return await this.props.loadInvitees();
|
||||
}
|
||||
|
||||
onRoleChange = (role: string, user: OrgUser) => {
|
||||
onRoleChange = (role: OrgRole, user: OrgUser) => {
|
||||
const updatedUser = { ...user, role: role };
|
||||
|
||||
this.props.updateUser(updatedUser);
|
||||
};
|
||||
|
||||
onRemoveUser = (user: OrgUser) => {
|
||||
appEvents.emit(CoreEvents.showConfirmModal, {
|
||||
title: 'Delete',
|
||||
text: 'Are you sure you want to delete user ' + user.login + '?',
|
||||
yesText: 'Delete',
|
||||
icon: 'exclamation-triangle',
|
||||
onConfirm: () => {
|
||||
this.props.removeUser(user.userId);
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
onShowInvites = () => {
|
||||
this.setState(prevState => ({
|
||||
showInvites: !prevState.showInvites,
|
||||
@ -94,7 +81,7 @@ export class UsersListPage extends PureComponent<Props, State> {
|
||||
<UsersTable
|
||||
users={users}
|
||||
onRoleChange={(role, user) => this.onRoleChange(role, user)}
|
||||
onRemoveUser={user => this.onRemoveUser(user)}
|
||||
onRemoveUser={user => this.props.removeUser(user.userId)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ import { shallow } from 'enzyme';
|
||||
import UsersTable, { Props } from './UsersTable';
|
||||
import { OrgUser } from 'app/types';
|
||||
import { getMockUsers } from './__mocks__/userMocks';
|
||||
import { ConfirmModal } from '@grafana/ui';
|
||||
|
||||
const setup = (propOverrides?: object) => {
|
||||
const props: Props = {
|
||||
@ -31,3 +32,12 @@ describe('Render', () => {
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Remove modal', () => {
|
||||
it('should render correct amount', () => {
|
||||
const wrapper = setup({
|
||||
users: getMockUsers(3),
|
||||
});
|
||||
expect(wrapper.find(ConfirmModal).length).toEqual(4);
|
||||
});
|
||||
});
|
||||
|
@ -1,16 +1,19 @@
|
||||
import React, { FC } from 'react';
|
||||
import React, { FC, useState } from 'react';
|
||||
import { OrgUser } from 'app/types';
|
||||
import { Icon } from '@grafana/ui';
|
||||
import { OrgRolePicker } from '../admin/OrgRolePicker';
|
||||
import { Button, ConfirmModal } from '@grafana/ui';
|
||||
import { OrgRole } from '@grafana/data';
|
||||
|
||||
export interface Props {
|
||||
users: OrgUser[];
|
||||
onRoleChange: (role: string, user: OrgUser) => void;
|
||||
onRoleChange: (role: OrgRole, user: OrgUser) => void;
|
||||
onRemoveUser: (user: OrgUser) => void;
|
||||
}
|
||||
|
||||
const UsersTable: FC<Props> = props => {
|
||||
const { users, onRoleChange, onRemoveUser } = props;
|
||||
|
||||
const [showRemoveModal, setShowRemoveModal] = useState<string | boolean>(false);
|
||||
return (
|
||||
<table className="filter-table form-inline">
|
||||
<thead>
|
||||
@ -32,32 +35,29 @@ const UsersTable: FC<Props> = props => {
|
||||
<img className="filter-table__avatar" src={user.avatarUrl} />
|
||||
</td>
|
||||
<td>{user.login}</td>
|
||||
|
||||
<td>
|
||||
<span className="ellipsis">{user.email}</span>
|
||||
</td>
|
||||
<td>{user.name}</td>
|
||||
<td>{user.lastSeenAtAge}</td>
|
||||
<td>
|
||||
<div className="gf-form-select-wrapper width-12">
|
||||
<select
|
||||
value={user.role}
|
||||
className="gf-form-input"
|
||||
onChange={event => onRoleChange(event.target.value, user)}
|
||||
>
|
||||
{['Viewer', 'Editor', 'Admin'].map((option, index) => {
|
||||
return (
|
||||
<option value={option} key={`${option}-${index}`}>
|
||||
{option}
|
||||
</option>
|
||||
);
|
||||
})}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<td className="width-8">
|
||||
<OrgRolePicker value={user.role} onChange={newRole => onRoleChange(newRole, user)} />
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<div onClick={() => onRemoveUser(user)} className="btn btn-danger btn-small">
|
||||
<Icon name="times" style={{ marginBottom: 0 }} />
|
||||
</div>
|
||||
<Button size="sm" variant="destructive" onClick={() => setShowRemoveModal(user.login)} icon="times" />
|
||||
<ConfirmModal
|
||||
body={`Are you sure you want to delete user ${user.login}?`}
|
||||
confirmText="Delete"
|
||||
title="Delete"
|
||||
onDismiss={() => setShowRemoveModal(false)}
|
||||
isOpen={user.login === showRemoveModal}
|
||||
onConfirm={() => {
|
||||
onRemoveUser(user);
|
||||
}}
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
|
@ -1,3 +1,5 @@
|
||||
import { OrgRole, OrgUser } from 'app/types';
|
||||
|
||||
export const getMockUsers = (amount: number) => {
|
||||
const users = [];
|
||||
|
||||
@ -15,7 +17,7 @@ export const getMockUsers = (amount: number) => {
|
||||
});
|
||||
}
|
||||
|
||||
return users;
|
||||
return users as OrgUser[];
|
||||
};
|
||||
|
||||
export const getMockUser = () => {
|
||||
@ -27,9 +29,9 @@ export const getMockUser = () => {
|
||||
lastSeenAtAge: '',
|
||||
login: `user`,
|
||||
orgId: 1,
|
||||
role: 'Admin',
|
||||
role: 'Admin' as OrgRole,
|
||||
userId: 2,
|
||||
};
|
||||
} as OrgUser;
|
||||
};
|
||||
|
||||
export const getMockInvitees = (amount: number) => {
|
||||
|
@ -42,22 +42,22 @@ exports[`Render should render pending invites button 1`] = `
|
||||
}
|
||||
}
|
||||
>
|
||||
<button
|
||||
className="btn toggle-btn active"
|
||||
key="users"
|
||||
onClick={[MockFunction]}
|
||||
>
|
||||
Users
|
||||
</button>
|
||||
<button
|
||||
className="btn toggle-btn"
|
||||
key="pending-invites"
|
||||
onClick={[MockFunction]}
|
||||
>
|
||||
Pending Invites (
|
||||
5
|
||||
)
|
||||
</button>
|
||||
<RadioButtonGroup
|
||||
onChange={[MockFunction]}
|
||||
options={
|
||||
Array [
|
||||
Object {
|
||||
"label": "Users",
|
||||
"value": "users",
|
||||
},
|
||||
Object {
|
||||
"label": "Pending Invites (5)",
|
||||
"value": "invites",
|
||||
},
|
||||
]
|
||||
}
|
||||
value="users"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className="page-action-bar__spacer"
|
||||
@ -83,8 +83,7 @@ exports[`Render should show external user management button 1`] = `
|
||||
<div
|
||||
className="page-action-bar__spacer"
|
||||
/>
|
||||
<a
|
||||
className="btn btn-primary"
|
||||
<LinkButton
|
||||
href="some/url"
|
||||
rel="noopener"
|
||||
target="_blank"
|
||||
@ -110,14 +109,11 @@ exports[`Render should show invite button 1`] = `
|
||||
<div
|
||||
className="page-action-bar__spacer"
|
||||
/>
|
||||
<a
|
||||
className="btn btn-primary"
|
||||
<LinkButton
|
||||
href="org/users/invite"
|
||||
>
|
||||
<span>
|
||||
Invite
|
||||
</span>
|
||||
</a>
|
||||
Invite
|
||||
</LinkButton>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
@ -92,50 +92,29 @@ exports[`Render should render users table 1`] = `
|
||||
user-0 test
|
||||
</td>
|
||||
<td />
|
||||
<td>
|
||||
<div
|
||||
className="gf-form-select-wrapper width-12"
|
||||
>
|
||||
<select
|
||||
className="gf-form-input"
|
||||
onChange={[Function]}
|
||||
value="Admin"
|
||||
>
|
||||
<option
|
||||
key="Viewer-0"
|
||||
value="Viewer"
|
||||
>
|
||||
Viewer
|
||||
</option>
|
||||
<option
|
||||
key="Editor-1"
|
||||
value="Editor"
|
||||
>
|
||||
Editor
|
||||
</option>
|
||||
<option
|
||||
key="Admin-2"
|
||||
value="Admin"
|
||||
>
|
||||
Admin
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
<td
|
||||
className="width-8"
|
||||
>
|
||||
<Component
|
||||
onChange={[Function]}
|
||||
value="Admin"
|
||||
/>
|
||||
</td>
|
||||
<td>
|
||||
<div
|
||||
className="btn btn-danger btn-small"
|
||||
<Button
|
||||
icon="times"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<Icon
|
||||
name="times"
|
||||
style={
|
||||
Object {
|
||||
"marginBottom": 0,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
size="sm"
|
||||
variant="destructive"
|
||||
/>
|
||||
<Component
|
||||
body="Are you sure you want to delete user user-0?"
|
||||
confirmText="Delete"
|
||||
isOpen={false}
|
||||
onConfirm={[Function]}
|
||||
onDismiss={[Function]}
|
||||
title="Delete"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
@ -163,50 +142,29 @@ exports[`Render should render users table 1`] = `
|
||||
user-1 test
|
||||
</td>
|
||||
<td />
|
||||
<td>
|
||||
<div
|
||||
className="gf-form-select-wrapper width-12"
|
||||
>
|
||||
<select
|
||||
className="gf-form-input"
|
||||
onChange={[Function]}
|
||||
value="Admin"
|
||||
>
|
||||
<option
|
||||
key="Viewer-0"
|
||||
value="Viewer"
|
||||
>
|
||||
Viewer
|
||||
</option>
|
||||
<option
|
||||
key="Editor-1"
|
||||
value="Editor"
|
||||
>
|
||||
Editor
|
||||
</option>
|
||||
<option
|
||||
key="Admin-2"
|
||||
value="Admin"
|
||||
>
|
||||
Admin
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
<td
|
||||
className="width-8"
|
||||
>
|
||||
<Component
|
||||
onChange={[Function]}
|
||||
value="Admin"
|
||||
/>
|
||||
</td>
|
||||
<td>
|
||||
<div
|
||||
className="btn btn-danger btn-small"
|
||||
<Button
|
||||
icon="times"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<Icon
|
||||
name="times"
|
||||
style={
|
||||
Object {
|
||||
"marginBottom": 0,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
size="sm"
|
||||
variant="destructive"
|
||||
/>
|
||||
<Component
|
||||
body="Are you sure you want to delete user user-1?"
|
||||
confirmText="Delete"
|
||||
isOpen={false}
|
||||
onConfirm={[Function]}
|
||||
onDismiss={[Function]}
|
||||
title="Delete"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
@ -234,50 +192,29 @@ exports[`Render should render users table 1`] = `
|
||||
user-2 test
|
||||
</td>
|
||||
<td />
|
||||
<td>
|
||||
<div
|
||||
className="gf-form-select-wrapper width-12"
|
||||
>
|
||||
<select
|
||||
className="gf-form-input"
|
||||
onChange={[Function]}
|
||||
value="Admin"
|
||||
>
|
||||
<option
|
||||
key="Viewer-0"
|
||||
value="Viewer"
|
||||
>
|
||||
Viewer
|
||||
</option>
|
||||
<option
|
||||
key="Editor-1"
|
||||
value="Editor"
|
||||
>
|
||||
Editor
|
||||
</option>
|
||||
<option
|
||||
key="Admin-2"
|
||||
value="Admin"
|
||||
>
|
||||
Admin
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
<td
|
||||
className="width-8"
|
||||
>
|
||||
<Component
|
||||
onChange={[Function]}
|
||||
value="Admin"
|
||||
/>
|
||||
</td>
|
||||
<td>
|
||||
<div
|
||||
className="btn btn-danger btn-small"
|
||||
<Button
|
||||
icon="times"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<Icon
|
||||
name="times"
|
||||
style={
|
||||
Object {
|
||||
"marginBottom": 0,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
size="sm"
|
||||
variant="destructive"
|
||||
/>
|
||||
<Component
|
||||
body="Are you sure you want to delete user user-2?"
|
||||
confirmText="Delete"
|
||||
isOpen={false}
|
||||
onConfirm={[Function]}
|
||||
onDismiss={[Function]}
|
||||
title="Delete"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
@ -305,50 +242,29 @@ exports[`Render should render users table 1`] = `
|
||||
user-3 test
|
||||
</td>
|
||||
<td />
|
||||
<td>
|
||||
<div
|
||||
className="gf-form-select-wrapper width-12"
|
||||
>
|
||||
<select
|
||||
className="gf-form-input"
|
||||
onChange={[Function]}
|
||||
value="Admin"
|
||||
>
|
||||
<option
|
||||
key="Viewer-0"
|
||||
value="Viewer"
|
||||
>
|
||||
Viewer
|
||||
</option>
|
||||
<option
|
||||
key="Editor-1"
|
||||
value="Editor"
|
||||
>
|
||||
Editor
|
||||
</option>
|
||||
<option
|
||||
key="Admin-2"
|
||||
value="Admin"
|
||||
>
|
||||
Admin
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
<td
|
||||
className="width-8"
|
||||
>
|
||||
<Component
|
||||
onChange={[Function]}
|
||||
value="Admin"
|
||||
/>
|
||||
</td>
|
||||
<td>
|
||||
<div
|
||||
className="btn btn-danger btn-small"
|
||||
<Button
|
||||
icon="times"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<Icon
|
||||
name="times"
|
||||
style={
|
||||
Object {
|
||||
"marginBottom": 0,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
size="sm"
|
||||
variant="destructive"
|
||||
/>
|
||||
<Component
|
||||
body="Are you sure you want to delete user user-3?"
|
||||
confirmText="Delete"
|
||||
isOpen={false}
|
||||
onConfirm={[Function]}
|
||||
onDismiss={[Function]}
|
||||
title="Delete"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
@ -376,50 +292,29 @@ exports[`Render should render users table 1`] = `
|
||||
user-4 test
|
||||
</td>
|
||||
<td />
|
||||
<td>
|
||||
<div
|
||||
className="gf-form-select-wrapper width-12"
|
||||
>
|
||||
<select
|
||||
className="gf-form-input"
|
||||
onChange={[Function]}
|
||||
value="Admin"
|
||||
>
|
||||
<option
|
||||
key="Viewer-0"
|
||||
value="Viewer"
|
||||
>
|
||||
Viewer
|
||||
</option>
|
||||
<option
|
||||
key="Editor-1"
|
||||
value="Editor"
|
||||
>
|
||||
Editor
|
||||
</option>
|
||||
<option
|
||||
key="Admin-2"
|
||||
value="Admin"
|
||||
>
|
||||
Admin
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
<td
|
||||
className="width-8"
|
||||
>
|
||||
<Component
|
||||
onChange={[Function]}
|
||||
value="Admin"
|
||||
/>
|
||||
</td>
|
||||
<td>
|
||||
<div
|
||||
className="btn btn-danger btn-small"
|
||||
<Button
|
||||
icon="times"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<Icon
|
||||
name="times"
|
||||
style={
|
||||
Object {
|
||||
"marginBottom": 0,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
size="sm"
|
||||
variant="destructive"
|
||||
/>
|
||||
<Component
|
||||
body="Are you sure you want to delete user user-4?"
|
||||
confirmText="Delete"
|
||||
isOpen={false}
|
||||
onConfirm={[Function]}
|
||||
onDismiss={[Function]}
|
||||
title="Delete"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
@ -447,50 +342,29 @@ exports[`Render should render users table 1`] = `
|
||||
user-5 test
|
||||
</td>
|
||||
<td />
|
||||
<td>
|
||||
<div
|
||||
className="gf-form-select-wrapper width-12"
|
||||
>
|
||||
<select
|
||||
className="gf-form-input"
|
||||
onChange={[Function]}
|
||||
value="Admin"
|
||||
>
|
||||
<option
|
||||
key="Viewer-0"
|
||||
value="Viewer"
|
||||
>
|
||||
Viewer
|
||||
</option>
|
||||
<option
|
||||
key="Editor-1"
|
||||
value="Editor"
|
||||
>
|
||||
Editor
|
||||
</option>
|
||||
<option
|
||||
key="Admin-2"
|
||||
value="Admin"
|
||||
>
|
||||
Admin
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
<td
|
||||
className="width-8"
|
||||
>
|
||||
<Component
|
||||
onChange={[Function]}
|
||||
value="Admin"
|
||||
/>
|
||||
</td>
|
||||
<td>
|
||||
<div
|
||||
className="btn btn-danger btn-small"
|
||||
<Button
|
||||
icon="times"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<Icon
|
||||
name="times"
|
||||
style={
|
||||
Object {
|
||||
"marginBottom": 0,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
size="sm"
|
||||
variant="destructive"
|
||||
/>
|
||||
<Component
|
||||
body="Are you sure you want to delete user user-5?"
|
||||
confirmText="Delete"
|
||||
isOpen={false}
|
||||
onConfirm={[Function]}
|
||||
onDismiss={[Function]}
|
||||
title="Delete"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
@ -9,7 +9,7 @@ export interface OrgUser {
|
||||
login: string;
|
||||
name: string;
|
||||
orgId: number;
|
||||
role: string;
|
||||
role: OrgRole;
|
||||
userId: number;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user