peopleBody.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359
  1. const usersPerPage = 25;
  2. BlazeComponent.extendComponent({
  3. mixins() {
  4. return [Mixins.InfiniteScrolling];
  5. },
  6. onCreated() {
  7. this.error = new ReactiveVar('');
  8. this.loading = new ReactiveVar(false);
  9. this.people = new ReactiveVar(true);
  10. this.findUsersOptions = new ReactiveVar({});
  11. this.number = new ReactiveVar(0);
  12. this.page = new ReactiveVar(1);
  13. this.loadNextPageLocked = false;
  14. this.callFirstWith(null, 'resetNextPeak');
  15. this.autorun(() => {
  16. const limit = this.page.get() * usersPerPage;
  17. this.subscribe('people', this.findUsersOptions.get(), limit, () => {
  18. this.loadNextPageLocked = false;
  19. const nextPeakBefore = this.callFirstWith(null, 'getNextPeak');
  20. this.calculateNextPeak();
  21. const nextPeakAfter = this.callFirstWith(null, 'getNextPeak');
  22. if (nextPeakBefore === nextPeakAfter) {
  23. this.callFirstWith(null, 'resetNextPeak');
  24. }
  25. });
  26. });
  27. },
  28. events() {
  29. return [
  30. {
  31. 'click #searchButton'() {
  32. this.filterPeople();
  33. },
  34. 'keydown #searchInput'(event) {
  35. if (event.keyCode === 13 && !event.shiftKey) {
  36. this.filterPeople();
  37. }
  38. },
  39. 'click #newUserButton'() {
  40. Popup.open('newUser');
  41. },
  42. },
  43. ];
  44. },
  45. filterPeople() {
  46. const value = $('#searchInput')
  47. .first()
  48. .val();
  49. if (value === '') {
  50. this.findUsersOptions.set({});
  51. } else {
  52. const regex = new RegExp(value, 'i');
  53. this.findUsersOptions.set({
  54. $or: [
  55. { username: regex },
  56. { 'profile.fullname': regex },
  57. { 'emails.address': regex },
  58. ],
  59. });
  60. }
  61. },
  62. loadNextPage() {
  63. if (this.loadNextPageLocked === false) {
  64. this.page.set(this.page.get() + 1);
  65. this.loadNextPageLocked = true;
  66. }
  67. },
  68. calculateNextPeak() {
  69. const element = this.find('.main-body');
  70. if (element) {
  71. const altitude = element.scrollHeight;
  72. this.callFirstWith(this, 'setNextPeak', altitude);
  73. }
  74. },
  75. reachNextPeak() {
  76. this.loadNextPage();
  77. },
  78. setError(error) {
  79. this.error.set(error);
  80. },
  81. setLoading(w) {
  82. this.loading.set(w);
  83. },
  84. peopleList() {
  85. const users = Users.find(this.findUsersOptions.get(), {
  86. fields: { _id: true },
  87. });
  88. this.number.set(users.count(false));
  89. return users;
  90. },
  91. peopleNumber() {
  92. return this.number.get();
  93. },
  94. }).register('people');
  95. Template.peopleRow.helpers({
  96. userData() {
  97. const userCollection = this.esSearch ? ESSearchResults : Users;
  98. return userCollection.findOne(this.userId);
  99. },
  100. });
  101. Template.editUserPopup.onCreated(function() {
  102. this.authenticationMethods = new ReactiveVar([]);
  103. this.errorMessage = new ReactiveVar('');
  104. Meteor.call('getAuthenticationsEnabled', (_, result) => {
  105. if (result) {
  106. // TODO : add a management of different languages
  107. // (ex {value: ldap, text: TAPi18n.__('ldap', {}, T9n.getLanguage() || 'en')})
  108. this.authenticationMethods.set([
  109. { value: 'password' },
  110. // Gets only the authentication methods availables
  111. ...Object.entries(result)
  112. .filter(e => e[1])
  113. .map(e => ({ value: e[0] })),
  114. ]);
  115. }
  116. });
  117. });
  118. Template.editUserPopup.helpers({
  119. user() {
  120. return Users.findOne(this.userId);
  121. },
  122. authentications() {
  123. return Template.instance().authenticationMethods.get();
  124. },
  125. isSelected(match) {
  126. const userId = Template.instance().data.userId;
  127. const selected = Users.findOne(userId).authenticationMethod;
  128. return selected === match;
  129. },
  130. isLdap() {
  131. const userId = Template.instance().data.userId;
  132. const selected = Users.findOne(userId).authenticationMethod;
  133. return selected === 'ldap';
  134. },
  135. errorMessage() {
  136. return Template.instance().errorMessage.get();
  137. },
  138. });
  139. Template.newUserPopup.onCreated(function() {
  140. this.authenticationMethods = new ReactiveVar([]);
  141. this.errorMessage = new ReactiveVar('');
  142. Meteor.call('getAuthenticationsEnabled', (_, result) => {
  143. if (result) {
  144. // TODO : add a management of different languages
  145. // (ex {value: ldap, text: TAPi18n.__('ldap', {}, T9n.getLanguage() || 'en')})
  146. this.authenticationMethods.set([
  147. { value: 'password' },
  148. // Gets only the authentication methods availables
  149. ...Object.entries(result)
  150. .filter(e => e[1])
  151. .map(e => ({ value: e[0] })),
  152. ]);
  153. }
  154. });
  155. });
  156. Template.newUserPopup.helpers({
  157. //user() {
  158. // return Users.findOne(this.userId);
  159. //},
  160. authentications() {
  161. return Template.instance().authenticationMethods.get();
  162. },
  163. //isSelected(match) {
  164. // const userId = Template.instance().data.userId;
  165. // const selected = Users.findOne(userId).authenticationMethod;
  166. // return selected === match;
  167. //},
  168. //isLdap() {
  169. // const userId = Template.instance().data.userId;
  170. // const selected = Users.findOne(userId).authenticationMethod;
  171. // return selected === 'ldap';
  172. //},
  173. errorMessage() {
  174. return Template.instance().errorMessage.get();
  175. },
  176. });
  177. BlazeComponent.extendComponent({
  178. onCreated() {},
  179. user() {
  180. return Users.findOne(this.userId);
  181. },
  182. events() {
  183. return [
  184. {
  185. 'click a.edit-user': Popup.open('editUser'),
  186. 'click a.more-settings-user': Popup.open('settingsUser'),
  187. },
  188. ];
  189. },
  190. }).register('peopleRow');
  191. BlazeComponent.extendComponent({
  192. events() {
  193. return [
  194. {
  195. 'click a.new-user': Popup.open('newUser'),
  196. },
  197. ];
  198. },
  199. }).register('newUserRow');
  200. Template.editUserPopup.events({
  201. submit(event, templateInstance) {
  202. event.preventDefault();
  203. const user = Users.findOne(this.userId);
  204. const fullname = templateInstance.find('.js-profile-fullname').value.trim();
  205. const username = templateInstance.find('.js-profile-username').value.trim();
  206. const password = templateInstance.find('.js-profile-password').value;
  207. const isAdmin = templateInstance.find('.js-profile-isadmin').value.trim();
  208. const isActive = templateInstance.find('.js-profile-isactive').value.trim();
  209. const email = templateInstance.find('.js-profile-email').value.trim();
  210. const authentication = templateInstance
  211. .find('.js-authenticationMethod')
  212. .value.trim();
  213. const isChangePassword = password.length > 0;
  214. const isChangeUserName = username !== user.username;
  215. const isChangeEmail =
  216. email.toLowerCase() !== user.emails[0].address.toLowerCase();
  217. Users.update(this.userId, {
  218. $set: {
  219. 'profile.fullname': fullname,
  220. isAdmin: isAdmin === 'true',
  221. loginDisabled: isActive === 'true',
  222. authenticationMethod: authentication,
  223. },
  224. });
  225. if (isChangePassword) {
  226. Meteor.call('setPassword', password, this.userId);
  227. }
  228. if (isChangeUserName && isChangeEmail) {
  229. Meteor.call(
  230. 'setUsernameAndEmail',
  231. username,
  232. email.toLowerCase(),
  233. this.userId,
  234. function(error) {
  235. const usernameMessageElement = templateInstance.$('.username-taken');
  236. const emailMessageElement = templateInstance.$('.email-taken');
  237. if (error) {
  238. const errorElement = error.error;
  239. if (errorElement === 'username-already-taken') {
  240. usernameMessageElement.show();
  241. emailMessageElement.hide();
  242. } else if (errorElement === 'email-already-taken') {
  243. usernameMessageElement.hide();
  244. emailMessageElement.show();
  245. }
  246. } else {
  247. usernameMessageElement.hide();
  248. emailMessageElement.hide();
  249. Popup.close();
  250. }
  251. },
  252. );
  253. } else if (isChangeUserName) {
  254. Meteor.call('setUsername', username, this.userId, function(error) {
  255. const usernameMessageElement = templateInstance.$('.username-taken');
  256. if (error) {
  257. const errorElement = error.error;
  258. if (errorElement === 'username-already-taken') {
  259. usernameMessageElement.show();
  260. }
  261. } else {
  262. usernameMessageElement.hide();
  263. Popup.close();
  264. }
  265. });
  266. } else if (isChangeEmail) {
  267. Meteor.call('setEmail', email.toLowerCase(), this.userId, function(
  268. error,
  269. ) {
  270. const emailMessageElement = templateInstance.$('.email-taken');
  271. if (error) {
  272. const errorElement = error.error;
  273. if (errorElement === 'email-already-taken') {
  274. emailMessageElement.show();
  275. }
  276. } else {
  277. emailMessageElement.hide();
  278. Popup.close();
  279. }
  280. });
  281. } else Popup.close();
  282. },
  283. 'click #deleteButton': Popup.afterConfirm('userDelete', function() {
  284. Users.remove(this.userId);
  285. Popup.close();
  286. }),
  287. });
  288. Template.newUserPopup.events({
  289. submit(event, templateInstance) {
  290. event.preventDefault();
  291. const fullname = templateInstance.find('.js-profile-fullname').value.trim();
  292. const username = templateInstance.find('.js-profile-username').value.trim();
  293. const password = templateInstance.find('.js-profile-password').value;
  294. const isAdmin = templateInstance.find('.js-profile-isadmin').value.trim();
  295. const isActive = templateInstance.find('.js-profile-isactive').value.trim();
  296. const email = templateInstance.find('.js-profile-email').value.trim();
  297. Meteor.call(
  298. 'setCreateUser',
  299. fullname,
  300. username,
  301. password,
  302. isAdmin,
  303. isActive,
  304. email.toLowerCase(),
  305. function(error) {
  306. const usernameMessageElement = templateInstance.$('.username-taken');
  307. const emailMessageElement = templateInstance.$('.email-taken');
  308. if (error) {
  309. const errorElement = error.error;
  310. if (errorElement === 'username-already-taken') {
  311. usernameMessageElement.show();
  312. emailMessageElement.hide();
  313. } else if (errorElement === 'email-already-taken') {
  314. usernameMessageElement.hide();
  315. emailMessageElement.show();
  316. }
  317. } else {
  318. usernameMessageElement.hide();
  319. emailMessageElement.hide();
  320. Popup.close();
  321. }
  322. },
  323. );
  324. Popup.close();
  325. },
  326. });
  327. Template.settingsUserPopup.events({
  328. 'click .impersonate-user'(event) {
  329. event.preventDefault();
  330. Meteor.call('impersonate', this.userId, err => {
  331. if (!err) {
  332. FlowRouter.go('/');
  333. Meteor.connection.setUserId(this.userId);
  334. }
  335. });
  336. },
  337. });