Home Reference Source

application/components/tag.js

  1. import React from 'react';
  2. import Immutable from 'immutable';
  3. import {connect} from 'react-redux';
  4.  
  5. import {browserHistory, Link} from 'react-router';
  6. import RaisedButton from 'material-ui/RaisedButton';
  7. import FontIcon from 'material-ui/FontIcon';
  8. import IconAdd from 'material-ui/svg-icons/content/add';
  9. import {Toolbar, ToolbarGroup, ToolbarSeparator, ToolbarTitle} from 'material-ui/Toolbar';
  10. import Paper from 'material-ui/Paper';
  11.  
  12. import {
  13. tagsFetch,
  14. tagsRemove
  15. } from './../redux/actions/tag-actions';
  16.  
  17. import {
  18. snackbarShowMessage
  19. } from './../redux/actions/snackbar-actions';
  20.  
  21. import {
  22. alertShowMessage
  23. } from './../redux/actions/alert-actions';
  24.  
  25. import TagTable from './tag/tag-table';
  26.  
  27. import LoadingIndicator from './common/loading-indicator';
  28. import ReduxPaginator from './common/redux-paginator';
  29. import DeleteButton from './common/delete-button';
  30.  
  31. import {parameterize} from './../util/strings';
  32.  
  33. import {Row, Col} from './flexbox';
  34.  
  35. import CurrentUser from './../current-user';
  36.  
  37. import request from './../util/request';
  38. import {ENTER_KEY} from './../util/key-codes';
  39.  
  40. class Tag extends React.Component {
  41. constructor(props) {
  42. super(props);
  43.  
  44. this.state = {
  45. selectedItems: []
  46. };
  47. }
  48.  
  49. componentWillMount() {
  50. const page = (this.props.location && this.props.location.query.page)
  51. ? this.props.location.query.page
  52. : 1;
  53.  
  54. const keyword = (this.props.location && this.props.location.query.keyword)
  55. ? decodeURIComponent(this.props.location.query.keyword)
  56. : null;
  57.  
  58. let params = {page: page, limit: 40};
  59. if (keyword) {
  60. params['keyword'] = keyword;
  61. }
  62.  
  63. const {dispatch} = this.props;
  64. dispatch(tagsFetch(params));
  65. }
  66.  
  67. handlePagination(page) {
  68. if (this.props.tags.pagination.current == page) {
  69. return;
  70. }
  71.  
  72. const keyword = (this.props.location && this.props.location.query.keyword)
  73. ? decodeURIComponent(this.props.location.query.keyword)
  74. : null;
  75.  
  76. let params = {page: page, limit: 40};
  77. if (keyword) {
  78. params['keyword'] = keyword;
  79. }
  80.  
  81. const {dispatch} = this.props;
  82. dispatch(tagsFetch(params));
  83. }
  84.  
  85. handleKeyDown(e) {
  86. const val = e.target.value;
  87. if (e.keyCode !== ENTER_KEY) {
  88. return;
  89. }
  90.  
  91. const {dispatch} = this.props;
  92.  
  93. const q = request.setQuery({
  94. 'keyword': encodeURIComponent(val),
  95. 'page': 1
  96. });
  97. const this_url = request.getPath() + '?' + q;
  98. browserHistory.push(this_url);
  99.  
  100. dispatch(tagsFetch({page: 1, limit: 40, keyword: val}));
  101. }
  102.  
  103. handleSearchReset() {
  104. const {dispatch} = this.props;
  105. const q = request.setQuery({
  106. 'keyword': '',
  107. 'page': 1
  108. });
  109. const this_url = request.getPath() + '?' + q;
  110. browserHistory.push(this_url);
  111.  
  112. dispatch(tagsFetch({page: 1}));
  113. }
  114.  
  115. handleDelete() {
  116. const {dispatch} = this.props;
  117. dispatch(tagsRemove(this.state.selectedItems.join(',')))
  118. .then(() => {
  119. this.setState({'selectedItems': []});
  120. dispatch(snackbarShowMessage('Tags updated'));
  121. })
  122. .then(() => {
  123. const page = (this.props.location && this.props.location.query.page)
  124. ? this.props.location.query.page
  125. : 1;
  126.  
  127. const keyword = (this.props.location && this.props.location.query.keyword)
  128. ? decodeURIComponent(this.props.location.query.keyword)
  129. : null;
  130.  
  131. let params = {page: page, limit: 40};
  132. if (keyword) {
  133. params['keyword'] = keyword;
  134. }
  135.  
  136. const {dispatch} = this.props;
  137. dispatch(tagsFetch(params));
  138. })
  139. .catch(() => {
  140. this.setState({'selectedItems': []});
  141. dispatch(alertShowMessage({
  142. title: 'Oops',
  143. message: (
  144. <p>Unable to remove tags, you may not have delete permission.</p>
  145. )
  146. }));
  147. });
  148. }
  149.  
  150. handleRowSelection(selected) {
  151. let selectedItems = [];
  152.  
  153. if (!selected || selected == 'none') {
  154. this.setState({'selectedItems': []});
  155. return;
  156. }
  157.  
  158. if (selected == 'all') {
  159. selectedItems = this.props.tags.items
  160. .map((tag) => tag.get('uuid'))
  161. .toList()
  162. .toJS();
  163. } else {
  164. selectedItems = selected.map((i) => this.props.tags.items.toList().get(i).get('uuid'));
  165. }
  166.  
  167. this.setState({'selectedItems': selectedItems});
  168. }
  169.  
  170. render() {
  171.  
  172. if (this.props.tags.isFetching) {
  173. return <LoadingIndicator />;
  174. }
  175.  
  176. return (
  177. <div className="tag-root">
  178. <Row>
  179. <Col xs={12}>
  180. <Paper className='toolbar'>
  181. <Row middle='xs'>
  182. <Col xs={3} autoBox={false}>
  183. <div className="box toolbar-search-wrap">
  184. <FontIcon className='mui-icons'>search</FontIcon>
  185. <input
  186. className="search"
  187. type="text"
  188. placeholder="Search Tags"
  189. onKeyDown={this.handleKeyDown.bind(this)}
  190. defaultValue={this.props.location.query.keyword ? decodeURIComponent(this.props.location.query.keyword) : ''}
  191. />
  192. <FontIcon className='mui-icons clear-search' onClick={this.handleSearchReset.bind(this)}>close</FontIcon>
  193. </div>
  194. </Col>
  195. <Col xs={4}>
  196. <DeleteButton
  197. disabled={this.state.selectedItems && this.state.selectedItems.length ? false : true}
  198. onDelete={this.handleDelete.bind(this)}
  199. />
  200. <RaisedButton
  201. containerElement={<Link to='/ceo/settings/tag/new' />}
  202. primary={true}
  203. icon={<IconAdd />}
  204. />
  205. </Col>
  206. <Col xs={5} end='xs'>
  207. <ReduxPaginator
  208. pagination={this.props.tags.pagination}
  209. onPaginate={this.handlePagination.bind(this)}
  210. />
  211. </Col>
  212. </Row>
  213. </Paper>
  214.  
  215. <Paper className='padded clear-bottom'>
  216. <TagTable
  217. tags={this.props.tags}
  218. onRowSelection={this.handleRowSelection.bind(this)}
  219. />
  220. </Paper>
  221. </Col>
  222. </Row>
  223. </div>
  224. );
  225. }
  226. }
  227.  
  228. const mapStateToProps = (state) => {
  229. return {
  230. tags: state.tags
  231. };
  232. }
  233.  
  234. export default connect(mapStateToProps)(Tag);