فهرست منبع

fixing issue with copy invite link

Peter Holmberg 7 سال پیش
والد
کامیت
d37dae34f2

+ 57 - 0
public/app/features/users/InviteeRow.tsx

@@ -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>
+          &nbsp;
+        </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);

+ 0 - 1
public/app/features/users/InviteesTable.test.tsx

@@ -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);

+ 4 - 37
public/app/features/users/InviteesTable.tsx

@@ -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>
-                  &nbsp;
-                </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>

+ 0 - 1
public/app/features/users/UsersListPage.test.tsx

@@ -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(),

+ 2 - 8
public/app/features/users/UsersListPage.tsx

@@ -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));

+ 1 - 1
public/app/features/users/__mocks__/userMocks.ts

@@ -48,7 +48,7 @@ export const getMockInvitees = (amount: number) => {
       orgId: 1,
       role: 'viewer',
       status: 'not accepted',
-      url: `localhost/invite/$${i}`,
+      url: `localhost/invite/${i}`,
     });
   }
 

+ 120 - 258
public/app/features/users/__snapshots__/InviteesTable.test.tsx.snap

@@ -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>
 `;