custom-user-selector.js.es6 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. import { default as computed, observes } from 'ember-addons/ember-computed-decorators';
  2. import { renderAvatar } from 'discourse/helpers/user-avatar';
  3. import userSearch from '../lib/user-search';
  4. const template = function(params) {
  5. const options = params.options;
  6. let html = "<div class='autocomplete'>";
  7. if (options.users) {
  8. html += "<ul>";
  9. options.users.forEach((u) => {
  10. html += `<li><a href title="${u.name}">`;
  11. html += renderAvatar(u, { imageSize: 'tiny' });
  12. html += `<span class='username'>${u.username}</span>`;
  13. if (u.name) {
  14. html += `<span class='name'>${u.name}</span>`;
  15. }
  16. html += `</a></li>`;
  17. });
  18. html += "</ul>";
  19. };
  20. html += "</div>";
  21. return new Handlebars.SafeString(html).string;
  22. };
  23. export default Ember.TextField.extend({
  24. attributeBindings: ['autofocus', 'maxLength'],
  25. autocorrect: false,
  26. autocapitalize: false,
  27. name: 'user-selector',
  28. id: "custom-member-selector",
  29. @computed("placeholderKey")
  30. placeholder(placeholderKey) {
  31. return placeholderKey ? I18n.t(placeholderKey) : "";
  32. },
  33. @observes('usernames')
  34. _update() {
  35. if (this.get('canReceiveUpdates') === 'true')
  36. this.didInsertElement({updateData: true});
  37. },
  38. didInsertElement(opts) {
  39. this._super();
  40. var self = this,
  41. selected = [],
  42. groups = [],
  43. currentUser = this.currentUser,
  44. includeMentionableGroups = this.get('includeMentionableGroups') === 'true',
  45. includeMessageableGroups = this.get('includeMessageableGroups') === 'true',
  46. includeGroups = this.get('includeGroups') === 'true',
  47. allowedUsers = this.get('allowedUsers') === 'true';
  48. function excludedUsernames() {
  49. // hack works around some issues with allowAny eventing
  50. const usernames = self.get('single') ? [] : selected;
  51. if (currentUser && self.get('excludeCurrentUser')) {
  52. return usernames.concat([currentUser.get('username')]);
  53. }
  54. return usernames;
  55. }
  56. this.$().val(this.get('usernames')).autocomplete({
  57. template,
  58. disabled: this.get('disabled'),
  59. single: this.get('single'),
  60. allowAny: this.get('allowAny'),
  61. updateData: (opts && opts.updateData) ? opts.updateData : false,
  62. dataSource(term) {
  63. const termRegex = /[^a-zA-Z0-9_\-\.@\+]/;
  64. var results = userSearch({
  65. term: term.replace(termRegex, ''),
  66. topicId: self.get('topicId'),
  67. exclude: excludedUsernames(),
  68. includeGroups,
  69. allowedUsers,
  70. includeMentionableGroups,
  71. includeMessageableGroups,
  72. group: self.get("group")
  73. });
  74. return results;
  75. },
  76. transformComplete(v) {
  77. if (v.username || v.name) {
  78. if (!v.username) { groups.push(v.name); }
  79. return v.username || v.name;
  80. } else {
  81. var excludes = excludedUsernames();
  82. return v.usernames.filter(function(item){
  83. return excludes.indexOf(item) === -1;
  84. });
  85. }
  86. },
  87. onChangeItems(items) {
  88. var hasGroups = false;
  89. items = items.map(function(i) {
  90. if (groups.indexOf(i) > -1) { hasGroups = true; }
  91. return i.username ? i.username : i;
  92. });
  93. self.set('usernames', items.join(","));
  94. self.set('hasGroups', hasGroups);
  95. selected = items;
  96. if (self.get('onChangeCallback')) self.sendAction('onChangeCallback');
  97. },
  98. reverseTransform(i) {
  99. return { username: i };
  100. }
  101. });
  102. },
  103. willDestroyElement() {
  104. this._super();
  105. this.$().autocomplete('destroy');
  106. },
  107. // THIS IS A HUGE HACK TO SUPPORT CLEARING THE INPUT
  108. @observes('usernames')
  109. _clearInput: function() {
  110. if (arguments.length > 1) {
  111. if (Em.isEmpty(this.get("usernames"))) {
  112. this.$().parent().find("a").click();
  113. }
  114. }
  115. }
  116. });