change-username-form.js 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. import Ember from 'ember';
  2. export default Ember.Component.extend({
  3. tagName: 'form',
  4. classNames: 'form-horizontal',
  5. isLoaded: false,
  6. isErrored: false,
  7. isSaving: false,
  8. options: null,
  9. username: '',
  10. validation: null,
  11. setValidation: function() {
  12. this.set('validation', Ember.Object.create({}));
  13. }.on('init'),
  14. apiUrl: function() {
  15. return 'users/' + this.auth.get('user.id') + '/username';
  16. }.property(),
  17. loadOptions: function() {
  18. var self = this;
  19. this.ajax.get(this.get('apiUrl')
  20. ).then(function(options) {
  21. if (self.isDestroyed) { return; }
  22. self.setProperties({
  23. 'options': Ember.Object.create(options),
  24. 'isLoaded': true
  25. });
  26. }, function(jqXHR) {
  27. if (self.isDestroyed) { return; }
  28. if (typeof jqXHR.responseJSON !== 'undefined') {
  29. self.set('isErrored', jqXHR.responseJSON);
  30. } else if (jqXHR.status === 0) {
  31. self.set('isErrored', {'detail': gettext('Lost connection with application.')});
  32. } else {
  33. self.set('isErrored', {'detail': gettext('Application has errored.')});
  34. }
  35. });
  36. }.on('init'),
  37. usernameValidation: function() {
  38. var state = true;
  39. var value = Ember.$.trim(this.get('username'));
  40. var valueLength = value.length;
  41. var limit = 0;
  42. var message = null;
  43. if (valueLength < this.get('options.length_min')) {
  44. limit = this.get('options.length_min');
  45. message = ngettext('Username must be at least %(limit)s character long.',
  46. 'Username must be at least %(limit)s characters long.',
  47. limit);
  48. state = [interpolate(message, {limit: limit}, true)];
  49. } else if (valueLength > this.get('options.length_max')) {
  50. limit = this.get('options.length_max');
  51. message = ngettext('Username cannot be longer than %(limit)s characters.',
  52. 'Username cannot be longer than %(limit)s characters.',
  53. limit);
  54. state = [interpolate(message, {limit: limit}, true)];
  55. } else if (!new RegExp('^[0-9a-z]+$', 'i').test(value)) {
  56. state = [gettext('Username can only contain latin alphabet letters and digits.')];
  57. } else if (value === this.get('auth.user.username')) {
  58. state = [gettext('New username is same as current one.')];
  59. }
  60. if (state === true) {
  61. this.set('validation.username', 'ok');
  62. } else {
  63. this.set('validation.username', state);
  64. }
  65. }.observes('username'),
  66. submit: function() {
  67. if (this.get('isLoading')) {
  68. return false;
  69. }
  70. var data = {
  71. username: Ember.$.trim(this.get('username')),
  72. };
  73. if (data.username.length === 0) {
  74. this.toast.error(gettext('Enter new username.'));
  75. return false;
  76. }
  77. if (this.$('.has-error').length) {
  78. this.toast.error(gettext('Form contains errors.'));
  79. return false;
  80. }
  81. this.set('isSaving', true);
  82. var self = this;
  83. this.ajax.post(this.get('apiUrl'), data
  84. ).then(function(response) {
  85. if (self.isDestroyed) { return; }
  86. self.success(response);
  87. }, function(jqXHR) {
  88. if (self.isDestroyed) { return; }
  89. self.error(jqXHR);
  90. }).finally(function() {
  91. if (self.isDestroyed) { return; }
  92. self.set('isSaving', false);
  93. });
  94. return false;
  95. },
  96. success: function(responseJSON) {
  97. this.set('username', '');
  98. this.set('validation', Ember.Object.create({}));
  99. this.toast.success(gettext('Your username has been changed.'));
  100. this.get('options').setProperties(responseJSON.options);
  101. var oldUsername = this.get('auth.user.username');
  102. this.get('auth.user').setProperties({
  103. 'username': responseJSON.username,
  104. 'slug': responseJSON.slug
  105. });
  106. var userPOJO = this.auth.getUserPOJO();
  107. this.store.pushPayload({
  108. 'username-changes': [
  109. {
  110. 'id': Math.floor(new Date().getTime() / 1000),
  111. 'user': userPOJO,
  112. 'changed_by': userPOJO,
  113. 'changed_by_username': this.get('auth.user.username'),
  114. 'changed_by_slug': this.get('auth.user.slug'),
  115. 'changed_on': moment(),
  116. 'new_username': this.get('auth.user.username'),
  117. 'old_username': oldUsername
  118. }
  119. ]
  120. });
  121. },
  122. error: function(jqXHR) {
  123. var rejection = jqXHR.responseJSON;
  124. if (jqXHR.status === 400) {
  125. this.toast.error(rejection.detail);
  126. this.get('options').setProperties(rejection.options);
  127. } else {
  128. this.toast.apiError(jqXHR);
  129. }
  130. },
  131. changesLeft: Ember.computed.alias('options.changes_left'),
  132. changesLeftMessage: function() {
  133. var changes = this.get('options.changes_left');
  134. var message = ngettext('You can change your username %(changes)s more time.',
  135. 'You can change your username %(changes)s more times.',
  136. changes);
  137. return interpolate(message, {changes: changes}, true);
  138. }.property('options.changes_left'),
  139. nextChange: function() {
  140. if (this.get('options.next_on')) {
  141. return moment(this.get('options.next_on'));
  142. } else {
  143. return null;
  144. }
  145. }.property('options.next_on', 'clock.tick')
  146. });