UsersActionBar.tsx 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. import React, { PureComponent } from 'react';
  2. import { connect } from 'react-redux';
  3. import classNames from 'classnames';
  4. import { setUsersSearchQuery } from './state/actions';
  5. import { getInviteesCount, getUsersSearchQuery } from './state/selectors';
  6. export interface Props {
  7. searchQuery: string;
  8. setUsersSearchQuery: typeof setUsersSearchQuery;
  9. onShowInvites: () => void;
  10. pendingInvitesCount: number;
  11. canInvite: boolean;
  12. showInvites: boolean;
  13. externalUserMngLinkUrl: string;
  14. externalUserMngLinkName: string;
  15. }
  16. export class UsersActionBar extends PureComponent<Props> {
  17. render() {
  18. const {
  19. canInvite,
  20. externalUserMngLinkName,
  21. externalUserMngLinkUrl,
  22. searchQuery,
  23. pendingInvitesCount,
  24. setUsersSearchQuery,
  25. onShowInvites,
  26. showInvites,
  27. } = this.props;
  28. const pendingInvitesButtonStyle = classNames({
  29. btn: true,
  30. 'toggle-btn': true,
  31. active: showInvites,
  32. });
  33. const usersButtonStyle = classNames({
  34. btn: true,
  35. 'toggle-btn': true,
  36. active: !showInvites,
  37. });
  38. return (
  39. <div className="page-action-bar">
  40. <div className="gf-form gf-form--grow">
  41. <label className="gf-form--has-input-icon">
  42. <input
  43. type="text"
  44. className="gf-form-input width-20"
  45. value={searchQuery}
  46. onChange={event => setUsersSearchQuery(event.target.value)}
  47. placeholder="Filter by name or type"
  48. />
  49. <i className="gf-form-input-icon fa fa-search" />
  50. </label>
  51. {pendingInvitesCount > 0 && (
  52. <div style={{ marginLeft: '1rem' }}>
  53. <button className={usersButtonStyle} key="users" onClick={onShowInvites}>
  54. Users
  55. </button>
  56. <button className={pendingInvitesButtonStyle} onClick={onShowInvites} key="pending-invites">
  57. Pending Invites ({pendingInvitesCount})
  58. </button>
  59. </div>
  60. )}
  61. <div className="page-action-bar__spacer" />
  62. {canInvite && (
  63. <a className="btn btn-primary" href="org/users/invite">
  64. <span>Invite</span>
  65. </a>
  66. )}
  67. {externalUserMngLinkUrl && (
  68. <a className="btn btn-primary" href={externalUserMngLinkUrl} target="_blank">
  69. <i className="fa fa-external-link-square" /> {externalUserMngLinkName}
  70. </a>
  71. )}
  72. </div>
  73. </div>
  74. );
  75. }
  76. }
  77. function mapStateToProps(state) {
  78. return {
  79. searchQuery: getUsersSearchQuery(state.users),
  80. pendingInvitesCount: getInviteesCount(state.users),
  81. externalUserMngLinkName: state.users.externalUserMngLinkName,
  82. externalUserMngLinkUrl: state.users.externalUserMngLinkUrl,
  83. canInvite: state.users.canInvite,
  84. };
  85. }
  86. const mapDispatchToProps = {
  87. setUsersSearchQuery,
  88. };
  89. export default connect(mapStateToProps, mapDispatchToProps)(UsersActionBar);