mirror of
https://github.com/grafana/grafana.git
synced 2024-11-26 02:40:26 -06:00
fixing issue with copy invite link
This commit is contained in:
parent
82adf5393e
commit
d37dae34f2
57
public/app/features/users/InviteeRow.tsx
Normal file
57
public/app/features/users/InviteeRow.tsx
Normal file
@ -0,0 +1,57 @@
|
||||
import React, { createRef, PureComponent } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { Invitee } from 'app/types';
|
||||
import { revokeInvite } from './state/actions';
|
||||
|
||||
export interface Props {
|
||||
invitee: Invitee;
|
||||
revokeInvite: typeof revokeInvite;
|
||||
}
|
||||
|
||||
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 (
|
||||
<tr>
|
||||
<td>{invitee.email}</td>
|
||||
<td>{invitee.name}</td>
|
||||
<td className="text-right">
|
||||
<button className="btn btn-inverse btn-mini" onClick={this.copyToClipboard}>
|
||||
<textarea
|
||||
readOnly={true}
|
||||
value={invitee.url}
|
||||
style={{ position: 'absolute', right: -1000 }}
|
||||
ref={this.copyUrlRef}
|
||||
/>
|
||||
<i className="fa fa-clipboard" /> Copy Invite
|
||||
</button>
|
||||
|
||||
</td>
|
||||
<td>
|
||||
<button className="btn btn-danger btn-mini" onClick={() => revokeInvite(invitee.code)}>
|
||||
<i className="fa fa-remove" />
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const mapDispatchToProps = {
|
||||
revokeInvite,
|
||||
};
|
||||
|
||||
export default connect(() => {
|
||||
return {};
|
||||
}, mapDispatchToProps)(InviteeRow);
|
@ -7,7 +7,6 @@ import { getMockInvitees } from './__mocks__/userMocks';
|
||||
const setup = (propOverrides?: object) => {
|
||||
const props: Props = {
|
||||
invitees: [] as Invitee[],
|
||||
onRevokeInvite: jest.fn(),
|
||||
};
|
||||
|
||||
Object.assign(props, propOverrides);
|
||||
|
@ -1,25 +1,14 @@
|
||||
import React, { createRef, PureComponent } from 'react';
|
||||
import React, { PureComponent } from 'react';
|
||||
import { Invitee } from 'app/types';
|
||||
import InviteeRow from './InviteeRow';
|
||||
|
||||
export interface Props {
|
||||
invitees: Invitee[];
|
||||
onRevokeInvite: (code: string) => void;
|
||||
}
|
||||
|
||||
export default class InviteesTable extends PureComponent<Props> {
|
||||
private copyUrlRef = createRef<HTMLTextAreaElement>();
|
||||
|
||||
copyToClipboard = () => {
|
||||
const node = this.copyUrlRef.current;
|
||||
|
||||
if (node) {
|
||||
node.select();
|
||||
document.execCommand('copy');
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const { invitees, onRevokeInvite } = this.props;
|
||||
const { invitees } = this.props;
|
||||
|
||||
return (
|
||||
<table className="filter-table form-inline">
|
||||
@ -33,29 +22,7 @@ export default class InviteesTable extends PureComponent<Props> {
|
||||
</thead>
|
||||
<tbody>
|
||||
{invitees.map((invitee, index) => {
|
||||
return (
|
||||
<tr key={`${invitee.id}-${index}`}>
|
||||
<td>{invitee.email}</td>
|
||||
<td>{invitee.name}</td>
|
||||
<td className="text-right">
|
||||
<button className="btn btn-inverse btn-mini" onClick={this.copyToClipboard}>
|
||||
<textarea
|
||||
readOnly={true}
|
||||
value={invitee.url}
|
||||
style={{ position: 'absolute', right: -1000 }}
|
||||
ref={this.copyUrlRef}
|
||||
/>
|
||||
<i className="fa fa-clipboard" /> Copy Invite
|
||||
</button>
|
||||
|
||||
</td>
|
||||
<td>
|
||||
<button className="btn btn-danger btn-mini" onClick={() => onRevokeInvite(invitee.code)}>
|
||||
<i className="fa fa-remove" />
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
return <InviteeRow key={`${invitee.id}-${index}`} invitee={invitee} />;
|
||||
})}
|
||||
</tbody>
|
||||
</table>
|
||||
|
@ -16,7 +16,6 @@ const setup = (propOverrides?: object) => {
|
||||
invitees: [] as Invitee[],
|
||||
searchQuery: '',
|
||||
externalUserMngInfo: '',
|
||||
revokeInvite: jest.fn(),
|
||||
loadInvitees: jest.fn(),
|
||||
loadUsers: jest.fn(),
|
||||
updateUser: jest.fn(),
|
||||
|
@ -9,7 +9,7 @@ import UsersTable from './UsersTable';
|
||||
import InviteesTable from './InviteesTable';
|
||||
import { Invitee, NavModel, OrgUser } from 'app/types';
|
||||
import appEvents from 'app/core/app_events';
|
||||
import { loadUsers, loadInvitees, revokeInvite, setUsersSearchQuery, updateUser, removeUser } from './state/actions';
|
||||
import { loadUsers, loadInvitees, setUsersSearchQuery, updateUser, removeUser } from './state/actions';
|
||||
import { getNavModel } from '../../core/selectors/navModel';
|
||||
import { getInvitees, getUsers, getUsersSearchQuery } from './state/selectors';
|
||||
|
||||
@ -25,7 +25,6 @@ export interface Props {
|
||||
setUsersSearchQuery: typeof setUsersSearchQuery;
|
||||
updateUser: typeof updateUser;
|
||||
removeUser: typeof removeUser;
|
||||
revokeInvite: typeof revokeInvite;
|
||||
}
|
||||
|
||||
export interface State {
|
||||
@ -79,10 +78,6 @@ export class UsersListPage extends PureComponent<Props, State> {
|
||||
});
|
||||
};
|
||||
|
||||
onRevokeInvite = code => {
|
||||
this.props.revokeInvite(code);
|
||||
};
|
||||
|
||||
onShowInvites = () => {
|
||||
this.setState(prevState => ({
|
||||
showInvites: !prevState.showInvites,
|
||||
@ -93,7 +88,7 @@ export class UsersListPage extends PureComponent<Props, State> {
|
||||
const { invitees, users } = this.props;
|
||||
|
||||
if (this.state.showInvites) {
|
||||
return <InviteesTable invitees={invitees} onRevokeInvite={code => this.onRevokeInvite(code)} />;
|
||||
return <InviteesTable invitees={invitees} />;
|
||||
} else {
|
||||
return (
|
||||
<UsersTable
|
||||
@ -141,7 +136,6 @@ const mapDispatchToProps = {
|
||||
setUsersSearchQuery,
|
||||
updateUser,
|
||||
removeUser,
|
||||
revokeInvite,
|
||||
};
|
||||
|
||||
export default hot(module)(connect(mapStateToProps, mapDispatchToProps)(UsersListPage));
|
||||
|
@ -48,7 +48,7 @@ export const getMockInvitees = (amount: number) => {
|
||||
orgId: 1,
|
||||
role: 'viewer',
|
||||
status: 'not accepted',
|
||||
url: `localhost/invite/$${i}`,
|
||||
url: `localhost/invite/${i}`,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -49,270 +49,132 @@ exports[`Render should render invitees 1`] = `
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr
|
||||
<Connect(InviteeRow)
|
||||
invitee={
|
||||
Object {
|
||||
"code": "asdfasdfsadf-0",
|
||||
"createdOn": "2018-10-02",
|
||||
"email": "invitee-0@test.com",
|
||||
"emailSent": true,
|
||||
"emailSentOn": "2018-10-02",
|
||||
"id": 0,
|
||||
"invitedByEmail": "admin@grafana.com",
|
||||
"invitedByLogin": "admin",
|
||||
"invitedByName": "admin",
|
||||
"name": "invitee-0",
|
||||
"orgId": 1,
|
||||
"role": "viewer",
|
||||
"status": "not accepted",
|
||||
"url": "localhost/invite/0",
|
||||
}
|
||||
}
|
||||
key="0-0"
|
||||
>
|
||||
<td>
|
||||
invitee-0@test.com
|
||||
</td>
|
||||
<td>
|
||||
invitee-0
|
||||
</td>
|
||||
<td
|
||||
className="text-right"
|
||||
>
|
||||
<button
|
||||
className="btn btn-inverse btn-mini"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<textarea
|
||||
readOnly={true}
|
||||
style={
|
||||
Object {
|
||||
"position": "absolute",
|
||||
"right": -1000,
|
||||
}
|
||||
}
|
||||
value="localhost/invite/$0"
|
||||
/>
|
||||
<i
|
||||
className="fa fa-clipboard"
|
||||
/>
|
||||
Copy Invite
|
||||
</button>
|
||||
|
||||
</td>
|
||||
<td>
|
||||
<button
|
||||
className="btn btn-danger btn-mini"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<i
|
||||
className="fa fa-remove"
|
||||
/>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
/>
|
||||
<Connect(InviteeRow)
|
||||
invitee={
|
||||
Object {
|
||||
"code": "asdfasdfsadf-1",
|
||||
"createdOn": "2018-10-02",
|
||||
"email": "invitee-1@test.com",
|
||||
"emailSent": true,
|
||||
"emailSentOn": "2018-10-02",
|
||||
"id": 1,
|
||||
"invitedByEmail": "admin@grafana.com",
|
||||
"invitedByLogin": "admin",
|
||||
"invitedByName": "admin",
|
||||
"name": "invitee-1",
|
||||
"orgId": 1,
|
||||
"role": "viewer",
|
||||
"status": "not accepted",
|
||||
"url": "localhost/invite/1",
|
||||
}
|
||||
}
|
||||
key="1-1"
|
||||
>
|
||||
<td>
|
||||
invitee-1@test.com
|
||||
</td>
|
||||
<td>
|
||||
invitee-1
|
||||
</td>
|
||||
<td
|
||||
className="text-right"
|
||||
>
|
||||
<button
|
||||
className="btn btn-inverse btn-mini"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<textarea
|
||||
readOnly={true}
|
||||
style={
|
||||
Object {
|
||||
"position": "absolute",
|
||||
"right": -1000,
|
||||
}
|
||||
}
|
||||
value="localhost/invite/$1"
|
||||
/>
|
||||
<i
|
||||
className="fa fa-clipboard"
|
||||
/>
|
||||
Copy Invite
|
||||
</button>
|
||||
|
||||
</td>
|
||||
<td>
|
||||
<button
|
||||
className="btn btn-danger btn-mini"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<i
|
||||
className="fa fa-remove"
|
||||
/>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
/>
|
||||
<Connect(InviteeRow)
|
||||
invitee={
|
||||
Object {
|
||||
"code": "asdfasdfsadf-2",
|
||||
"createdOn": "2018-10-02",
|
||||
"email": "invitee-2@test.com",
|
||||
"emailSent": true,
|
||||
"emailSentOn": "2018-10-02",
|
||||
"id": 2,
|
||||
"invitedByEmail": "admin@grafana.com",
|
||||
"invitedByLogin": "admin",
|
||||
"invitedByName": "admin",
|
||||
"name": "invitee-2",
|
||||
"orgId": 1,
|
||||
"role": "viewer",
|
||||
"status": "not accepted",
|
||||
"url": "localhost/invite/2",
|
||||
}
|
||||
}
|
||||
key="2-2"
|
||||
>
|
||||
<td>
|
||||
invitee-2@test.com
|
||||
</td>
|
||||
<td>
|
||||
invitee-2
|
||||
</td>
|
||||
<td
|
||||
className="text-right"
|
||||
>
|
||||
<button
|
||||
className="btn btn-inverse btn-mini"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<textarea
|
||||
readOnly={true}
|
||||
style={
|
||||
Object {
|
||||
"position": "absolute",
|
||||
"right": -1000,
|
||||
}
|
||||
}
|
||||
value="localhost/invite/$2"
|
||||
/>
|
||||
<i
|
||||
className="fa fa-clipboard"
|
||||
/>
|
||||
Copy Invite
|
||||
</button>
|
||||
|
||||
</td>
|
||||
<td>
|
||||
<button
|
||||
className="btn btn-danger btn-mini"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<i
|
||||
className="fa fa-remove"
|
||||
/>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
/>
|
||||
<Connect(InviteeRow)
|
||||
invitee={
|
||||
Object {
|
||||
"code": "asdfasdfsadf-3",
|
||||
"createdOn": "2018-10-02",
|
||||
"email": "invitee-3@test.com",
|
||||
"emailSent": true,
|
||||
"emailSentOn": "2018-10-02",
|
||||
"id": 3,
|
||||
"invitedByEmail": "admin@grafana.com",
|
||||
"invitedByLogin": "admin",
|
||||
"invitedByName": "admin",
|
||||
"name": "invitee-3",
|
||||
"orgId": 1,
|
||||
"role": "viewer",
|
||||
"status": "not accepted",
|
||||
"url": "localhost/invite/3",
|
||||
}
|
||||
}
|
||||
key="3-3"
|
||||
>
|
||||
<td>
|
||||
invitee-3@test.com
|
||||
</td>
|
||||
<td>
|
||||
invitee-3
|
||||
</td>
|
||||
<td
|
||||
className="text-right"
|
||||
>
|
||||
<button
|
||||
className="btn btn-inverse btn-mini"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<textarea
|
||||
readOnly={true}
|
||||
style={
|
||||
Object {
|
||||
"position": "absolute",
|
||||
"right": -1000,
|
||||
}
|
||||
}
|
||||
value="localhost/invite/$3"
|
||||
/>
|
||||
<i
|
||||
className="fa fa-clipboard"
|
||||
/>
|
||||
Copy Invite
|
||||
</button>
|
||||
|
||||
</td>
|
||||
<td>
|
||||
<button
|
||||
className="btn btn-danger btn-mini"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<i
|
||||
className="fa fa-remove"
|
||||
/>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
/>
|
||||
<Connect(InviteeRow)
|
||||
invitee={
|
||||
Object {
|
||||
"code": "asdfasdfsadf-4",
|
||||
"createdOn": "2018-10-02",
|
||||
"email": "invitee-4@test.com",
|
||||
"emailSent": true,
|
||||
"emailSentOn": "2018-10-02",
|
||||
"id": 4,
|
||||
"invitedByEmail": "admin@grafana.com",
|
||||
"invitedByLogin": "admin",
|
||||
"invitedByName": "admin",
|
||||
"name": "invitee-4",
|
||||
"orgId": 1,
|
||||
"role": "viewer",
|
||||
"status": "not accepted",
|
||||
"url": "localhost/invite/4",
|
||||
}
|
||||
}
|
||||
key="4-4"
|
||||
>
|
||||
<td>
|
||||
invitee-4@test.com
|
||||
</td>
|
||||
<td>
|
||||
invitee-4
|
||||
</td>
|
||||
<td
|
||||
className="text-right"
|
||||
>
|
||||
<button
|
||||
className="btn btn-inverse btn-mini"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<textarea
|
||||
readOnly={true}
|
||||
style={
|
||||
Object {
|
||||
"position": "absolute",
|
||||
"right": -1000,
|
||||
}
|
||||
}
|
||||
value="localhost/invite/$4"
|
||||
/>
|
||||
<i
|
||||
className="fa fa-clipboard"
|
||||
/>
|
||||
Copy Invite
|
||||
</button>
|
||||
|
||||
</td>
|
||||
<td>
|
||||
<button
|
||||
className="btn btn-danger btn-mini"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<i
|
||||
className="fa fa-remove"
|
||||
/>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
/>
|
||||
<Connect(InviteeRow)
|
||||
invitee={
|
||||
Object {
|
||||
"code": "asdfasdfsadf-5",
|
||||
"createdOn": "2018-10-02",
|
||||
"email": "invitee-5@test.com",
|
||||
"emailSent": true,
|
||||
"emailSentOn": "2018-10-02",
|
||||
"id": 5,
|
||||
"invitedByEmail": "admin@grafana.com",
|
||||
"invitedByLogin": "admin",
|
||||
"invitedByName": "admin",
|
||||
"name": "invitee-5",
|
||||
"orgId": 1,
|
||||
"role": "viewer",
|
||||
"status": "not accepted",
|
||||
"url": "localhost/invite/5",
|
||||
}
|
||||
}
|
||||
key="5-5"
|
||||
>
|
||||
<td>
|
||||
invitee-5@test.com
|
||||
</td>
|
||||
<td>
|
||||
invitee-5
|
||||
</td>
|
||||
<td
|
||||
className="text-right"
|
||||
>
|
||||
<button
|
||||
className="btn btn-inverse btn-mini"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<textarea
|
||||
readOnly={true}
|
||||
style={
|
||||
Object {
|
||||
"position": "absolute",
|
||||
"right": -1000,
|
||||
}
|
||||
}
|
||||
value="localhost/invite/$5"
|
||||
/>
|
||||
<i
|
||||
className="fa fa-clipboard"
|
||||
/>
|
||||
Copy Invite
|
||||
</button>
|
||||
|
||||
</td>
|
||||
<td>
|
||||
<button
|
||||
className="btn btn-danger btn-mini"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<i
|
||||
className="fa fa-remove"
|
||||
/>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
/>
|
||||
</tbody>
|
||||
</table>
|
||||
`;
|
||||
|
Loading…
Reference in New Issue
Block a user