UsersToolbar.js 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. /*
  2. * Copyright (C) 2015 - present Instructure, Inc.
  3. *
  4. * This file is part of Canvas.
  5. *
  6. * Canvas is free software: you can redistribute it and/or modify it under
  7. * the terms of the GNU Affero General Public License as published by the Free
  8. * Software Foundation, version 3 of the License.
  9. *
  10. * Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
  11. * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  12. * A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
  13. * details.
  14. *
  15. * You should have received a copy of the GNU Affero General Public License along
  16. * with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. import React from 'react'
  19. import PropTypes from 'prop-types'
  20. import I18n from 'i18n!account_course_user_search'
  21. import NewUserModal from './NewUserModal'
  22. import IcInput from './IcInput'
  23. import IcSelect from './IcSelect'
  24. const { string, bool, func, shape, object } = PropTypes
  25. class UsersToolbar extends React.Component {
  26. static propTypes = {
  27. onUpdateFilters: func.isRequired,
  28. onApplyFilters: func.isRequired,
  29. isLoading: bool,
  30. search_term: string,
  31. role_filter_id: string,
  32. errors: shape({ search_term: string }),
  33. accountId: string,
  34. handlers: shape({ handleAddNewUser: func, handleAddNewUserFormErrors: func }),
  35. userList: object.isRequired,
  36. roles: PropTypes.arrayOf(object),
  37. }
  38. static defaultProps = {
  39. isLoading: false,
  40. search_term: '',
  41. role_filter_id: '',
  42. errors: {},
  43. accountId: '',
  44. handlers: {},
  45. roles: [],
  46. }
  47. applyFilters = (e) => {
  48. e.preventDefault();
  49. this.props.onApplyFilters();
  50. }
  51. addUser = () => {
  52. this.addUserModal.openModal();
  53. }
  54. renderRoles = () => {
  55. const roles = this.props.roles
  56. if (roles) {
  57. return [
  58. <option key="all" value="">
  59. {I18n.t('All Roles')}
  60. </option>
  61. ].concat(roles.map(role => (
  62. <option key={role.id} value={role.id}>
  63. {role.label}
  64. </option>
  65. )))
  66. }
  67. return <option value="">{I18n.t('Loading...')}</option>
  68. }
  69. render () {
  70. const { onUpdateFilters, isLoading, errors } = this.props
  71. let addUserButton;
  72. if (window.ENV.PERMISSIONS.can_create_users) {
  73. addUserButton = (
  74. <button className="Button add_user" type="button" onClick={this.addUser}>
  75. <i className="icon-plus" />
  76. {' '}
  77. {I18n.t('People')}
  78. </button>
  79. )
  80. }
  81. return (
  82. <div>
  83. <form
  84. className="user_search_bar"
  85. style={{opacity: isLoading ? 0.5 : 1}}
  86. onSubmit={this.applyFilters}
  87. disabled={isLoading}
  88. >
  89. <div className="grid-row">
  90. <div className="col-xs-12 col-md-9">
  91. <div className="users-list-toolbar-form">
  92. <IcSelect
  93. value={this.props.role_filter_id}
  94. onChange={e => onUpdateFilters({role_filter_id: e.target.value})}
  95. >
  96. {this.renderRoles()}
  97. </IcSelect>
  98. <IcInput
  99. value={this.props.search_term}
  100. placeholder={I18n.t('Search people...')}
  101. onChange={e => onUpdateFilters({ search_term: e.target.value })}
  102. error={errors.search_term}
  103. type="search"
  104. />
  105. </div>
  106. </div>
  107. <div className="col-xs-12 col-md-3">
  108. <div className="users-list-toolbar-actions">
  109. <div className="users-list-toolbar-actions__layout">
  110. {addUserButton}
  111. &nbsp;
  112. <div className="al-dropdown__container">
  113. <button id="peopleOptionsBtn" className="al-trigger Button" type="button">
  114. <i className="icon-more" />
  115. <span className="screenreader-only">{I18n.t('People Options')}</span>
  116. </button>
  117. <ul className="al-options" role="menu" aria-hidden="true">
  118. <li>
  119. <a
  120. href={`/accounts/${this.props.accountId}/avatars`}
  121. className="icon-student-view" id="manageStudentsLink"
  122. role="menuitem"
  123. >
  124. {I18n.t('Manage profile pictures')}
  125. </a>
  126. </li>
  127. <li>
  128. <a
  129. href={`/accounts/${this.props.accountId}/groups`}
  130. className="icon-group"
  131. id="viewUserGroupLink"
  132. role="menuitem"
  133. >
  134. {I18n.t('View user groups')}
  135. </a>
  136. </li>
  137. </ul>
  138. </div>
  139. </div>
  140. </div>
  141. </div>
  142. </div>
  143. </form>
  144. <NewUserModal ref={(c) => { this.addUserModal = c }} userList={this.props.userList} handlers={this.props.handlers} />
  145. </div>
  146. );
  147. }
  148. }
  149. export default UsersToolbar