move.js 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. // jshint ignore:start
  2. import React from 'react';
  3. import Button from 'misago/components/button';
  4. import Form from 'misago/components/form';
  5. import FormGroup from 'misago/components/form-group';
  6. import * as post from 'misago/reducers/post';
  7. import ajax from 'misago/services/ajax';
  8. import modal from 'misago/services/modal';
  9. import snackbar from 'misago/services/snackbar';
  10. import store from 'misago/services/store';
  11. export default class extends Form {
  12. constructor(props) {
  13. super(props);
  14. this.state = {
  15. isLoading: false,
  16. url: '',
  17. validators: {
  18. url: []
  19. },
  20. errors: {}
  21. };
  22. }
  23. clean() {
  24. if (!this.state.url.trim().length) {
  25. snackbar.error(gettext("You have to enter link to the other thread."));
  26. return false;
  27. }
  28. return true;
  29. }
  30. send() {
  31. return ajax.post(this.props.thread.api.posts.move, {
  32. thread_url: this.state.url,
  33. posts: this.props.selection.map((post) => post.id)
  34. });
  35. }
  36. handleSuccess(success) {
  37. this.props.selection.forEach((selection) => {
  38. store.dispatch(post.patch(selection, {
  39. isDeleted: true
  40. }));
  41. });
  42. modal.hide();
  43. snackbar.success(gettext("Selected posts were moved to the other thread."));
  44. }
  45. handleError(rejection) {
  46. if (rejection.status === 400) {
  47. snackbar.error(rejection.detail);
  48. } else {
  49. snackbar.apiError(rejection);
  50. }
  51. }
  52. onUrlChange = (event) => {
  53. this.changeValue('url', event.target.value);
  54. };
  55. render() {
  56. return (
  57. <div className="modal-dialog" role="document">
  58. <form onSubmit={this.handleSubmit}>
  59. <div className="modal-content">
  60. <ModalHeader />
  61. <div className="modal-body">
  62. <FormGroup
  63. for="id_url"
  64. label={gettext("Link to thread you want to move posts to")}
  65. >
  66. <input
  67. className="form-control"
  68. disabled={this.state.isLoading}
  69. id="id_url"
  70. onChange={this.onUrlChange}
  71. value={this.state.url}
  72. />
  73. </FormGroup>
  74. </div>
  75. <div className="modal-footer">
  76. <button
  77. className="btn btn-default"
  78. data-dismiss="modal"
  79. disabled={this.state.isLoading}
  80. type="button"
  81. >
  82. {gettext("Cancel")}
  83. </button>
  84. <button className="btn btn-primary" loading={this.state.isLoading}>
  85. {gettext("Move posts")}
  86. </button>
  87. </div>
  88. </div>
  89. </form>
  90. </div>
  91. );
  92. }
  93. }
  94. export function ModalHeader(props) {
  95. return (
  96. <div className="modal-header">
  97. <button
  98. aria-label={gettext("Close")}
  99. className="close"
  100. data-dismiss="modal"
  101. type="button"
  102. >
  103. <span aria-hidden="true">&times;</span>
  104. </button>
  105. <h4 className="modal-title">{gettext("Move posts")}</h4>
  106. </div>
  107. );
  108. }