peopleBody.js 34 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126
  1. const orgsPerPage = 25;
  2. const teamsPerPage = 25;
  3. const usersPerPage = 25;
  4. let userOrgsTeamsAction = ""; //poosible actions 'addOrg', 'addTeam', 'removeOrg' or 'removeTeam' when adding or modifying a user
  5. let selectedUserChkBoxUserIds = [];
  6. BlazeComponent.extendComponent({
  7. mixins() {
  8. return [Mixins.InfiniteScrolling];
  9. },
  10. onCreated() {
  11. this.error = new ReactiveVar('');
  12. this.loading = new ReactiveVar(false);
  13. this.orgSetting = new ReactiveVar(true);
  14. this.teamSetting = new ReactiveVar(true);
  15. this.peopleSetting = new ReactiveVar(true);
  16. this.findOrgsOptions = new ReactiveVar({});
  17. this.findTeamsOptions = new ReactiveVar({});
  18. this.findUsersOptions = new ReactiveVar({});
  19. this.numberOrgs = new ReactiveVar(0);
  20. this.numberTeams = new ReactiveVar(0);
  21. this.numberPeople = new ReactiveVar(0);
  22. this.page = new ReactiveVar(1);
  23. this.loadNextPageLocked = false;
  24. this.callFirstWith(null, 'resetNextPeak');
  25. this.autorun(() => {
  26. const limitOrgs = this.page.get() * orgsPerPage;
  27. const limitTeams = this.page.get() * teamsPerPage;
  28. const limitUsers = this.page.get() * usersPerPage;
  29. this.subscribe('org', this.findOrgsOptions.get(), limitOrgs, () => {
  30. this.loadNextPageLocked = false;
  31. const nextPeakBefore = this.callFirstWith(null, 'getNextPeak');
  32. this.calculateNextPeak();
  33. const nextPeakAfter = this.callFirstWith(null, 'getNextPeak');
  34. if (nextPeakBefore === nextPeakAfter) {
  35. this.callFirstWith(null, 'resetNextPeak');
  36. }
  37. });
  38. this.subscribe('team', this.findTeamsOptions.get(), limitTeams, () => {
  39. this.loadNextPageLocked = false;
  40. const nextPeakBefore = this.callFirstWith(null, 'getNextPeak');
  41. this.calculateNextPeak();
  42. const nextPeakAfter = this.callFirstWith(null, 'getNextPeak');
  43. if (nextPeakBefore === nextPeakAfter) {
  44. this.callFirstWith(null, 'resetNextPeak');
  45. }
  46. });
  47. this.subscribe('people', this.findUsersOptions.get(), limitUsers, () => {
  48. this.loadNextPageLocked = false;
  49. const nextPeakBefore = this.callFirstWith(null, 'getNextPeak');
  50. this.calculateNextPeak();
  51. const nextPeakAfter = this.callFirstWith(null, 'getNextPeak');
  52. if (nextPeakBefore === nextPeakAfter) {
  53. this.callFirstWith(null, 'resetNextPeak');
  54. }
  55. });
  56. });
  57. },
  58. events() {
  59. return [
  60. {
  61. 'click #searchOrgButton'() {
  62. this.filterOrg();
  63. },
  64. 'keydown #searchOrgInput'(event) {
  65. if (event.keyCode === 13 && !event.shiftKey) {
  66. this.filterOrg();
  67. }
  68. },
  69. 'click #searchTeamButton'() {
  70. this.filterTeam();
  71. },
  72. 'keydown #searchTeamInput'(event) {
  73. if (event.keyCode === 13 && !event.shiftKey) {
  74. this.filterTeam();
  75. }
  76. },
  77. 'click #searchButton'() {
  78. this.filterPeople();
  79. },
  80. 'click #addOrRemoveTeam'(){
  81. document.getElementById("divAddOrRemoveTeamContainer").style.display = 'block';
  82. },
  83. 'keydown #searchInput'(event) {
  84. if (event.keyCode === 13 && !event.shiftKey) {
  85. this.filterPeople();
  86. }
  87. },
  88. 'click #newOrgButton'() {
  89. Popup.open('newOrg');
  90. },
  91. 'click #newTeamButton'() {
  92. Popup.open('newTeam');
  93. },
  94. 'click #newUserButton'() {
  95. Popup.open('newUser');
  96. },
  97. 'click a.js-org-menu': this.switchMenu,
  98. 'click a.js-team-menu': this.switchMenu,
  99. 'click a.js-people-menu': this.switchMenu,
  100. },
  101. ];
  102. },
  103. filterPeople() {
  104. const value = $('#searchInput').first().val();
  105. if (value === '') {
  106. this.findUsersOptions.set({});
  107. } else {
  108. const regex = new RegExp(value, 'i');
  109. this.findUsersOptions.set({
  110. $or: [
  111. { username: regex },
  112. { 'profile.fullname': regex },
  113. { 'emails.address': regex },
  114. ],
  115. });
  116. }
  117. },
  118. loadNextPage() {
  119. if (this.loadNextPageLocked === false) {
  120. this.page.set(this.page.get() + 1);
  121. this.loadNextPageLocked = true;
  122. }
  123. },
  124. calculateNextPeak() {
  125. const element = this.find('.main-body');
  126. if (element) {
  127. const altitude = element.scrollHeight;
  128. this.callFirstWith(this, 'setNextPeak', altitude);
  129. }
  130. },
  131. reachNextPeak() {
  132. this.loadNextPage();
  133. },
  134. setError(error) {
  135. this.error.set(error);
  136. },
  137. setLoading(w) {
  138. this.loading.set(w);
  139. },
  140. orgList() {
  141. const orgs = Org.find(this.findOrgsOptions.get(), {
  142. fields: { _id: true },
  143. });
  144. this.numberOrgs.set(orgs.count(false));
  145. return orgs;
  146. },
  147. teamList() {
  148. const teams = Team.find(this.findTeamsOptions.get(), {
  149. fields: { _id: true },
  150. });
  151. this.numberTeams.set(teams.count(false));
  152. return teams;
  153. },
  154. peopleList() {
  155. const users = Users.find(this.findUsersOptions.get(), {
  156. fields: { _id: true },
  157. });
  158. this.numberPeople.set(users.count(false));
  159. return users;
  160. },
  161. orgNumber() {
  162. return this.numberOrgs.get();
  163. },
  164. teamNumber() {
  165. return this.numberTeams.get();
  166. },
  167. peopleNumber() {
  168. return this.numberPeople.get();
  169. },
  170. switchMenu(event) {
  171. const target = $(event.target);
  172. if (!target.hasClass('active')) {
  173. $('.side-menu li.active').removeClass('active');
  174. target.parent().addClass('active');
  175. const targetID = target.data('id');
  176. this.orgSetting.set('org-setting' === targetID);
  177. this.teamSetting.set('team-setting' === targetID);
  178. this.peopleSetting.set('people-setting' === targetID);
  179. }
  180. },
  181. }).register('people');
  182. Template.orgRow.helpers({
  183. orgData() {
  184. const orgCollection = this.esSearch ? ESSearchResults : Org;
  185. return orgCollection.findOne(this.orgId);
  186. },
  187. });
  188. Template.teamRow.helpers({
  189. teamData() {
  190. const teamCollection = this.esSearch ? ESSearchResults : Team;
  191. return teamCollection.findOne(this.teamId);
  192. },
  193. });
  194. Template.peopleRow.helpers({
  195. userData() {
  196. const userCollection = this.esSearch ? ESSearchResults : Users;
  197. return userCollection.findOne(this.userId);
  198. },
  199. });
  200. Template.editUserPopup.onCreated(function () {
  201. this.authenticationMethods = new ReactiveVar([]);
  202. this.errorMessage = new ReactiveVar('');
  203. Meteor.call('getAuthenticationsEnabled', (_, result) => {
  204. if (result) {
  205. // TODO : add a management of different languages
  206. // (ex {value: ldap, text: TAPi18n.__('ldap', {}, T9n.getLanguage() || 'en')})
  207. this.authenticationMethods.set([
  208. { value: 'password' },
  209. // Gets only the authentication methods availables
  210. ...Object.entries(result)
  211. .filter((e) => e[1])
  212. .map((e) => ({ value: e[0] })),
  213. ]);
  214. }
  215. });
  216. });
  217. Template.editOrgPopup.helpers({
  218. org() {
  219. return Org.findOne(this.orgId);
  220. },
  221. errorMessage() {
  222. return Template.instance().errorMessage.get();
  223. },
  224. });
  225. Template.editTeamPopup.helpers({
  226. team() {
  227. return Team.findOne(this.teamId);
  228. },
  229. errorMessage() {
  230. return Template.instance().errorMessage.get();
  231. },
  232. });
  233. Template.editUserPopup.helpers({
  234. user() {
  235. return Users.findOne(this.userId);
  236. },
  237. authentications() {
  238. return Template.instance().authenticationMethods.get();
  239. },
  240. orgsDatas() {
  241. return Org.find({}, {sort: { createdAt: -1 }});
  242. },
  243. teamsDatas() {
  244. return Team.find({}, {sort: { createdAt: -1 }});
  245. },
  246. isSelected(match) {
  247. const userId = Template.instance().data.userId;
  248. const selected = Users.findOne(userId).authenticationMethod;
  249. return selected === match;
  250. },
  251. isLdap() {
  252. const userId = Template.instance().data.userId;
  253. const selected = Users.findOne(userId).authenticationMethod;
  254. return selected === 'ldap';
  255. },
  256. errorMessage() {
  257. return Template.instance().errorMessage.get();
  258. },
  259. });
  260. Template.newOrgPopup.onCreated(function () {
  261. this.errorMessage = new ReactiveVar('');
  262. });
  263. Template.newTeamPopup.onCreated(function () {
  264. this.errorMessage = new ReactiveVar('');
  265. });
  266. Template.newUserPopup.onCreated(function () {
  267. this.authenticationMethods = new ReactiveVar([]);
  268. this.errorMessage = new ReactiveVar('');
  269. Meteor.call('getAuthenticationsEnabled', (_, result) => {
  270. if (result) {
  271. // TODO : add a management of different languages
  272. // (ex {value: ldap, text: TAPi18n.__('ldap', {}, T9n.getLanguage() || 'en')})
  273. this.authenticationMethods.set([
  274. { value: 'password' },
  275. // Gets only the authentication methods availables
  276. ...Object.entries(result)
  277. .filter((e) => e[1])
  278. .map((e) => ({ value: e[0] })),
  279. ]);
  280. }
  281. });
  282. });
  283. Template.newOrgPopup.helpers({
  284. org() {
  285. return Org.findOne(this.orgId);
  286. },
  287. errorMessage() {
  288. return Template.instance().errorMessage.get();
  289. },
  290. });
  291. Template.newTeamPopup.helpers({
  292. team() {
  293. return Team.findOne(this.teamId);
  294. },
  295. errorMessage() {
  296. return Template.instance().errorMessage.get();
  297. },
  298. });
  299. Template.newUserPopup.helpers({
  300. user() {
  301. return Users.findOne(this.userId);
  302. },
  303. authentications() {
  304. return Template.instance().authenticationMethods.get();
  305. },
  306. orgsDatas() {
  307. return Org.find({}, {sort: { createdAt: -1 }});
  308. },
  309. teamsDatas() {
  310. return Team.find({}, {sort: { createdAt: -1 }});
  311. },
  312. isSelected(match) {
  313. const userId = Template.instance().data.userId;
  314. if(userId){
  315. const selected = Users.findOne(userId).authenticationMethod;
  316. return selected === match;
  317. }
  318. else{
  319. false;
  320. }
  321. },
  322. isLdap() {
  323. const userId = Template.instance().data.userId;
  324. const selected = Users.findOne(userId).authenticationMethod;
  325. return selected === 'ldap';
  326. },
  327. errorMessage() {
  328. return Template.instance().errorMessage.get();
  329. },
  330. });
  331. BlazeComponent.extendComponent({
  332. onCreated() {},
  333. org() {
  334. return Org.findOne(this.orgId);
  335. },
  336. events() {
  337. return [
  338. {
  339. 'click a.edit-org': Popup.open('editOrg'),
  340. 'click a.more-settings-org': Popup.open('settingsOrg'),
  341. },
  342. ];
  343. },
  344. }).register('orgRow');
  345. BlazeComponent.extendComponent({
  346. onCreated() {},
  347. team() {
  348. return Team.findOne(this.teamId);
  349. },
  350. events() {
  351. return [
  352. {
  353. 'click a.edit-team': Popup.open('editTeam'),
  354. 'click a.more-settings-team': Popup.open('settingsTeam'),
  355. },
  356. ];
  357. },
  358. }).register('teamRow');
  359. BlazeComponent.extendComponent({
  360. onCreated() {},
  361. user() {
  362. return Users.findOne(this.userId);
  363. },
  364. events() {
  365. return [
  366. {
  367. 'click a.edit-user': Popup.open('editUser'),
  368. 'click a.more-settings-user': Popup.open('settingsUser'),
  369. 'click .selectUserChkBox': function(ev){
  370. if(ev.currentTarget){
  371. if(ev.currentTarget.checked){
  372. if(!selectedUserChkBoxUserIds.includes(ev.currentTarget.id)){
  373. selectedUserChkBoxUserIds.push(ev.currentTarget.id);
  374. }
  375. }
  376. else{
  377. if(selectedUserChkBoxUserIds.includes(ev.currentTarget.id)){
  378. let index = selectedUserChkBoxUserIds.indexOf(ev.currentTarget.id);
  379. if(index > -1)
  380. selectedUserChkBoxUserIds.splice(index, 1);
  381. }
  382. }
  383. }
  384. if(selectedUserChkBoxUserIds.length > 0)
  385. document.getElementById("divAddOrRemoveTeam").style.display = 'block';
  386. else
  387. document.getElementById("divAddOrRemoveTeam").style.display = 'none';
  388. },
  389. },
  390. ];
  391. },
  392. }).register('peopleRow');
  393. BlazeComponent.extendComponent({
  394. onCreated() {},
  395. teamsDatas() {
  396. return Team.find({}, {sort: { createdAt: -1 }});
  397. },
  398. events() {
  399. return [
  400. {
  401. 'click #cancelBtn': function(){
  402. let selectedElt = document.getElementById("jsteamsUser");
  403. document.getElementById("divAddOrRemoveTeamContainer").style.display = 'none';
  404. },
  405. 'click #addTeamBtn': function(){
  406. let selectedElt;
  407. let selectedEltValue;
  408. let selectedEltValueId;
  409. let userTms = [];
  410. let currentUser;
  411. let currUserTeamIndex;
  412. selectedElt = document.getElementById("jsteamsUser");
  413. selectedEltValue = selectedElt.options[selectedElt.selectedIndex].text;
  414. selectedEltValueId = selectedElt.options[selectedElt.selectedIndex].value;
  415. if(document.getElementById('addAction').checked){
  416. for(let i = 0; i < selectedUserChkBoxUserIds.length; i++){
  417. currentUser = Users.findOne(selectedUserChkBoxUserIds[i]);
  418. userTms = currentUser.teams;
  419. if(userTms == undefined || userTms.length == 0){
  420. userTms = [];
  421. userTms.push({
  422. "teamId": selectedEltValueId,
  423. "teamDisplayName": selectedEltValue,
  424. })
  425. }
  426. else if(userTms.length > 0)
  427. {
  428. currUserTeamIndex = userTms.findIndex(function(t){ return t.teamId == selectedEltValueId});
  429. if(currUserTeamIndex == -1){
  430. userTms.push({
  431. "teamId": selectedEltValueId,
  432. "teamDisplayName": selectedEltValue,
  433. });
  434. }
  435. }
  436. Users.update(selectedUserChkBoxUserIds[i], {
  437. $set:{
  438. teams: userTms
  439. }
  440. });
  441. }
  442. }
  443. else{
  444. for(let i = 0; i < selectedUserChkBoxUserIds.length; i++){
  445. currentUser = Users.findOne(selectedUserChkBoxUserIds[i]);
  446. userTms = currentUser.teams;
  447. if(userTms !== undefined || userTms.length > 0)
  448. {
  449. currUserTeamIndex = userTms.findIndex(function(t){ return t.teamId == selectedEltValueId});
  450. if(currUserTeamIndex != -1){
  451. userTms.splice(currUserTeamIndex, 1);
  452. }
  453. }
  454. Users.update(selectedUserChkBoxUserIds[i], {
  455. $set:{
  456. teams: userTms
  457. }
  458. });
  459. }
  460. }
  461. document.getElementById("divAddOrRemoveTeamContainer").style.display = 'none';
  462. },
  463. },
  464. ];
  465. },
  466. }).register('modifyTeamsUsers');
  467. BlazeComponent.extendComponent({
  468. events() {
  469. return [
  470. {
  471. 'click a.new-org': Popup.open('newOrg'),
  472. },
  473. ];
  474. },
  475. }).register('newOrgRow');
  476. BlazeComponent.extendComponent({
  477. events() {
  478. return [
  479. {
  480. 'click a.new-team': Popup.open('newTeam'),
  481. },
  482. ];
  483. },
  484. }).register('newTeamRow');
  485. BlazeComponent.extendComponent({
  486. events() {
  487. return [
  488. {
  489. 'click a.new-user': Popup.open('newUser'),
  490. },
  491. ];
  492. },
  493. }).register('newUserRow');
  494. Template.editOrgPopup.events({
  495. submit(event, templateInstance) {
  496. event.preventDefault();
  497. const org = Org.findOne(this.orgId);
  498. const orgDisplayName = templateInstance
  499. .find('.js-orgDisplayName')
  500. .value.trim();
  501. const orgDesc = templateInstance.find('.js-orgDesc').value.trim();
  502. const orgShortName = templateInstance.find('.js-orgShortName').value.trim();
  503. const orgWebsite = templateInstance.find('.js-orgWebsite').value.trim();
  504. const orgIsActive =
  505. templateInstance.find('.js-org-isactive').value.trim() == 'true';
  506. const isChangeOrgDisplayName = orgDisplayName !== org.orgDisplayName;
  507. const isChangeOrgDesc = orgDesc !== org.orgDesc;
  508. const isChangeOrgShortName = orgShortName !== org.orgShortName;
  509. const isChangeOrgWebsite = orgWebsite !== org.orgWebsite;
  510. const isChangeOrgIsActive = orgIsActive !== org.orgIsActive;
  511. if (
  512. isChangeOrgDisplayName ||
  513. isChangeOrgDesc ||
  514. isChangeOrgShortName ||
  515. isChangeOrgWebsite ||
  516. isChangeOrgIsActive
  517. ) {
  518. Meteor.call(
  519. 'setOrgAllFields',
  520. org,
  521. orgDisplayName,
  522. orgDesc,
  523. orgShortName,
  524. orgWebsite,
  525. orgIsActive,
  526. );
  527. }
  528. Popup.close();
  529. },
  530. });
  531. Template.editTeamPopup.events({
  532. submit(event, templateInstance) {
  533. event.preventDefault();
  534. const team = Team.findOne(this.teamId);
  535. const teamDisplayName = templateInstance
  536. .find('.js-teamDisplayName')
  537. .value.trim();
  538. const teamDesc = templateInstance.find('.js-teamDesc').value.trim();
  539. const teamShortName = templateInstance
  540. .find('.js-teamShortName')
  541. .value.trim();
  542. const teamWebsite = templateInstance.find('.js-teamWebsite').value.trim();
  543. const teamIsActive =
  544. templateInstance.find('.js-team-isactive').value.trim() == 'true';
  545. const isChangeTeamDisplayName = teamDisplayName !== team.teamDisplayName;
  546. const isChangeTeamDesc = teamDesc !== team.teamDesc;
  547. const isChangeTeamShortName = teamShortName !== team.teamShortName;
  548. const isChangeTeamWebsite = teamWebsite !== team.teamWebsite;
  549. const isChangeTeamIsActive = teamIsActive !== team.teamIsActive;
  550. if (
  551. isChangeTeamDisplayName ||
  552. isChangeTeamDesc ||
  553. isChangeTeamShortName ||
  554. isChangeTeamWebsite ||
  555. isChangeTeamIsActive
  556. ) {
  557. Meteor.call(
  558. 'setTeamAllFields',
  559. team,
  560. teamDisplayName,
  561. teamDesc,
  562. teamShortName,
  563. teamWebsite,
  564. teamIsActive,
  565. );
  566. }
  567. Popup.close();
  568. },
  569. });
  570. Template.editUserPopup.events({
  571. submit(event, templateInstance) {
  572. event.preventDefault();
  573. const user = Users.findOne(this.userId);
  574. const username = templateInstance.find('.js-profile-username').value.trim();
  575. const fullname = templateInstance.find('.js-profile-fullname').value.trim();
  576. const initials = templateInstance.find('.js-profile-initials').value.trim();
  577. const password = templateInstance.find('.js-profile-password').value;
  578. const isAdmin = templateInstance.find('.js-profile-isadmin').value.trim();
  579. const isActive = templateInstance.find('.js-profile-isactive').value.trim();
  580. const email = templateInstance.find('.js-profile-email').value.trim();
  581. const verified = templateInstance.find('.js-profile-email-verified').value.trim();
  582. const authentication = templateInstance.find('.js-authenticationMethod').value.trim();
  583. const importUsernames = templateInstance.find('.js-import-usernames').value.trim();
  584. const userOrgs = templateInstance.find('.js-userOrgs').value.trim();
  585. const userOrgsIds = templateInstance.find('.js-userOrgIds').value.trim();
  586. const userTeams = templateInstance.find('.js-userteams').value.trim();
  587. const userTeamsIds = templateInstance.find('.js-userteamIds').value.trim();
  588. const isChangePassword = password.length > 0;
  589. const isChangeUserName = username !== user.username;
  590. const isChangeInitials = initials.length > 0;
  591. const isChangeEmailVerified = verified !== user.emails[0].verified;
  592. // If previously email address has not been set, it is undefined,
  593. // check for undefined, and allow adding email address.
  594. const isChangeEmail =
  595. email.toLowerCase() !==
  596. (typeof user.emails !== 'undefined'
  597. ? user.emails[0].address.toLowerCase()
  598. : false);
  599. Users.update(this.userId, {
  600. $set: {
  601. 'profile.fullname': fullname,
  602. isAdmin: isAdmin === 'true',
  603. loginDisabled: isActive === 'true',
  604. authenticationMethod: authentication,
  605. importUsernames: Users.parseImportUsernames(importUsernames),
  606. },
  607. });
  608. let userTeamsList = userTeams.split(",");
  609. let userTeamsIdsList = userTeamsIds.split(",");
  610. let userTms = [];
  611. if(userTeams != ''){
  612. for(let i = 0; i < userTeamsList.length; i++){
  613. userTms.push({
  614. "teamId": userTeamsIdsList[i],
  615. "teamDisplayName": userTeamsList[i],
  616. })
  617. }
  618. }
  619. Users.update(this.userId, {
  620. $set:{
  621. teams: userTms
  622. }
  623. });
  624. let userOrgsList = userOrgs.split(",");
  625. let userOrgsIdsList = userOrgsIds.split(",");
  626. let userOrganizations = [];
  627. if(userOrgs != ''){
  628. for(let i = 0; i < userOrgsList.length; i++){
  629. userOrganizations.push({
  630. "orgId": userOrgsIdsList[i],
  631. "orgDisplayName": userOrgsList[i],
  632. })
  633. }
  634. }
  635. Users.update(this.userId, {
  636. $set:{
  637. orgs: userOrganizations
  638. }
  639. });
  640. if (isChangePassword) {
  641. Meteor.call('setPassword', password, this.userId);
  642. }
  643. if (isChangeEmailVerified) {
  644. Meteor.call('setEmailVerified', email, verified === 'true', this.userId);
  645. }
  646. if (isChangeInitials) {
  647. Meteor.call('setInitials', initials, this.userId);
  648. }
  649. if (isChangeUserName && isChangeEmail) {
  650. Meteor.call(
  651. 'setUsernameAndEmail',
  652. username,
  653. email.toLowerCase(),
  654. this.userId,
  655. function (error) {
  656. const usernameMessageElement = templateInstance.$('.username-taken');
  657. const emailMessageElement = templateInstance.$('.email-taken');
  658. if (error) {
  659. const errorElement = error.error;
  660. if (errorElement === 'username-already-taken') {
  661. usernameMessageElement.show();
  662. emailMessageElement.hide();
  663. } else if (errorElement === 'email-already-taken') {
  664. usernameMessageElement.hide();
  665. emailMessageElement.show();
  666. }
  667. } else {
  668. usernameMessageElement.hide();
  669. emailMessageElement.hide();
  670. Popup.close();
  671. }
  672. },
  673. );
  674. } else if (isChangeUserName) {
  675. Meteor.call('setUsername', username, this.userId, function (error) {
  676. const usernameMessageElement = templateInstance.$('.username-taken');
  677. if (error) {
  678. const errorElement = error.error;
  679. if (errorElement === 'username-already-taken') {
  680. usernameMessageElement.show();
  681. }
  682. } else {
  683. usernameMessageElement.hide();
  684. Popup.close();
  685. }
  686. });
  687. } else if (isChangeEmail) {
  688. Meteor.call(
  689. 'setEmail',
  690. email.toLowerCase(),
  691. this.userId,
  692. function (error) {
  693. const emailMessageElement = templateInstance.$('.email-taken');
  694. if (error) {
  695. const errorElement = error.error;
  696. if (errorElement === 'email-already-taken') {
  697. emailMessageElement.show();
  698. }
  699. } else {
  700. emailMessageElement.hide();
  701. Popup.close();
  702. }
  703. },
  704. );
  705. } else Popup.close();
  706. },
  707. 'click #addUserOrg'(event) {
  708. event.preventDefault();
  709. userOrgsTeamsAction = "addOrg";
  710. document.getElementById("jsOrgs").style.display = 'block';
  711. document.getElementById("jsTeams").style.display = 'none';
  712. },
  713. 'click #removeUserOrg'(event) {
  714. event.preventDefault();
  715. userOrgsTeamsAction = "removeOrg";
  716. document.getElementById("jsOrgs").style.display = 'block';
  717. document.getElementById("jsTeams").style.display = 'none';
  718. },
  719. 'click #addUserTeam'(event) {
  720. event.preventDefault();
  721. userOrgsTeamsAction = "addTeam";
  722. document.getElementById("jsTeams").style.display = 'block';
  723. document.getElementById("jsOrgs").style.display = 'none';
  724. },
  725. 'click #removeUserTeam'(event) {
  726. event.preventDefault();
  727. userOrgsTeamsAction = "removeTeam";
  728. document.getElementById("jsTeams").style.display = 'block';
  729. document.getElementById("jsOrgs").style.display = 'none';
  730. },
  731. 'change #jsOrgs'(event) {
  732. event.preventDefault();
  733. UpdateUserOrgsOrTeamsElement();
  734. },
  735. 'change #jsTeams'(event) {
  736. event.preventDefault();
  737. UpdateUserOrgsOrTeamsElement();
  738. },
  739. });
  740. UpdateUserOrgsOrTeamsElement = function(isNewUser = false){
  741. let selectedElt;
  742. let selectedEltValue;
  743. let selectedEltValueId;
  744. let inputElt;
  745. let inputEltId;
  746. let lstInputValues = [];
  747. let lstInputValuesIds = [];
  748. let index;
  749. let indexId;
  750. switch(userOrgsTeamsAction)
  751. {
  752. case "addOrg":
  753. case "removeOrg":
  754. inputElt = !isNewUser ? document.getElementById("jsUserOrgsInPut") : document.getElementById("jsUserOrgsInPutNewUser");
  755. inputEltId = !isNewUser ? document.getElementById("jsUserOrgIdsInPut") : document.getElementById("jsUserOrgIdsInPutNewUser");
  756. selectedElt = !isNewUser ? document.getElementById("jsOrgs") : document.getElementById("jsOrgsNewUser");
  757. break;
  758. case "addTeam":
  759. case "removeTeam":
  760. inputElt = !isNewUser ? document.getElementById("jsUserTeamsInPut") : document.getElementById("jsUserTeamsInPutNewUser");
  761. inputEltId = !isNewUser ? document.getElementById("jsUserTeamIdsInPut") : document.getElementById("jsUserTeamIdsInPutNewUser");
  762. selectedElt = !isNewUser ? document.getElementById("jsTeams") : document.getElementById("jsTeamsNewUser");
  763. break;
  764. default:
  765. break;
  766. }
  767. selectedEltValue = selectedElt.options[selectedElt.selectedIndex].text;
  768. selectedEltValueId = selectedElt.options[selectedElt.selectedIndex].value;
  769. lstInputValues = inputElt.value.trim().split(",");
  770. if(lstInputValues.length == 1 && lstInputValues[0] == ''){
  771. lstInputValues = [];
  772. }
  773. lstInputValuesIds = inputEltId.value.trim().split(",");
  774. if(lstInputValuesIds.length == 1 && lstInputValuesIds[0] == ''){
  775. lstInputValuesIds = [];
  776. }
  777. index = lstInputValues.indexOf(selectedEltValue);
  778. indexId = lstInputValuesIds.indexOf(selectedEltValueId);
  779. if(userOrgsTeamsAction == "addOrg" || userOrgsTeamsAction == "addTeam"){
  780. if(index <= -1 && selectedEltValueId != "-1"){
  781. lstInputValues.push(selectedEltValue);
  782. }
  783. if(indexId <= -1 && selectedEltValueId != "-1"){
  784. lstInputValuesIds.push(selectedEltValueId);
  785. }
  786. }
  787. else{
  788. if(index > -1 && selectedEltValueId != "-1"){
  789. lstInputValues.splice(index, 1);
  790. }
  791. if(indexId > -1 && selectedEltValueId != "-1"){
  792. lstInputValuesIds.splice(indexId, 1);
  793. }
  794. }
  795. if(lstInputValues.length > 0){
  796. inputElt.value = lstInputValues.join(",");
  797. }
  798. else{
  799. inputElt.value = "";
  800. }
  801. if(lstInputValuesIds.length > 0){
  802. inputEltId.value = lstInputValuesIds.join(",");
  803. }
  804. else{
  805. inputEltId.value = "";
  806. }
  807. selectedElt.value = "-1";
  808. selectedElt.style.display = "none";
  809. }
  810. Template.newOrgPopup.events({
  811. submit(event, templateInstance) {
  812. event.preventDefault();
  813. const orgDisplayName = templateInstance
  814. .find('.js-orgDisplayName')
  815. .value.trim();
  816. const orgDesc = templateInstance.find('.js-orgDesc').value.trim();
  817. const orgShortName = templateInstance.find('.js-orgShortName').value.trim();
  818. const orgWebsite = templateInstance.find('.js-orgWebsite').value.trim();
  819. const orgIsActive =
  820. templateInstance.find('.js-org-isactive').value.trim() == 'true';
  821. Meteor.call(
  822. 'setCreateOrg',
  823. orgDisplayName,
  824. orgDesc,
  825. orgShortName,
  826. orgWebsite,
  827. orgIsActive,
  828. );
  829. Popup.close();
  830. },
  831. });
  832. Template.newTeamPopup.events({
  833. submit(event, templateInstance) {
  834. event.preventDefault();
  835. const teamDisplayName = templateInstance
  836. .find('.js-teamDisplayName')
  837. .value.trim();
  838. const teamDesc = templateInstance.find('.js-teamDesc').value.trim();
  839. const teamShortName = templateInstance
  840. .find('.js-teamShortName')
  841. .value.trim();
  842. const teamWebsite = templateInstance.find('.js-teamWebsite').value.trim();
  843. const teamIsActive =
  844. templateInstance.find('.js-team-isactive').value.trim() == 'true';
  845. Meteor.call(
  846. 'setCreateTeam',
  847. teamDisplayName,
  848. teamDesc,
  849. teamShortName,
  850. teamWebsite,
  851. teamIsActive,
  852. );
  853. Popup.close();
  854. },
  855. });
  856. Template.newUserPopup.events({
  857. submit(event, templateInstance) {
  858. event.preventDefault();
  859. const fullname = templateInstance.find('.js-profile-fullname').value.trim();
  860. const username = templateInstance.find('.js-profile-username').value.trim();
  861. const initials = templateInstance.find('.js-profile-initials').value.trim();
  862. const password = templateInstance.find('.js-profile-password').value;
  863. const isAdmin = templateInstance.find('.js-profile-isadmin').value.trim();
  864. const isActive = templateInstance.find('.js-profile-isactive').value.trim();
  865. const email = templateInstance.find('.js-profile-email').value.trim();
  866. const importUsernames = Users.parseImportUsernames(
  867. templateInstance.find('.js-import-usernames').value,
  868. );
  869. const userOrgs = templateInstance.find('.js-userOrgsNewUser').value.trim();
  870. const userOrgsIds = templateInstance.find('.js-userOrgIdsNewUser').value.trim();
  871. const userTeams = templateInstance.find('.js-userteamsNewUser').value.trim();
  872. const userTeamsIds = templateInstance.find('.js-userteamIdsNewUser').value.trim();
  873. let userTeamsList = userTeams.split(",");
  874. let userTeamsIdsList = userTeamsIds.split(",");
  875. let userTms = [];
  876. for(let i = 0; i < userTeamsList.length; i++){
  877. if(!!userTeamsIdsList[i] && !!userTeamsList[i]) {
  878. userTms.push({
  879. "teamId": userTeamsIdsList[i],
  880. "teamDisplayName": userTeamsList[i],
  881. })
  882. }
  883. }
  884. let userOrgsList = userOrgs.split(",");
  885. let userOrgsIdsList = userOrgsIds.split(",");
  886. let userOrganizations = [];
  887. for(let i = 0; i < userOrgsList.length; i++){
  888. if(!!userOrgsIdsList[i] && !!userOrgsList[i]) {
  889. userOrganizations.push({
  890. "orgId": userOrgsIdsList[i],
  891. "orgDisplayName": userOrgsList[i],
  892. })
  893. }
  894. }
  895. Meteor.call(
  896. 'setCreateUser',
  897. fullname,
  898. username,
  899. initials,
  900. password,
  901. isAdmin,
  902. isActive,
  903. email.toLowerCase(),
  904. importUsernames,
  905. userOrganizations,
  906. userTms,
  907. function(error) {
  908. const usernameMessageElement = templateInstance.$('.username-taken');
  909. const emailMessageElement = templateInstance.$('.email-taken');
  910. if (error) {
  911. const errorElement = error.error;
  912. if (errorElement === 'username-already-taken') {
  913. usernameMessageElement.show();
  914. emailMessageElement.hide();
  915. } else if (errorElement === 'email-already-taken') {
  916. usernameMessageElement.hide();
  917. emailMessageElement.show();
  918. }
  919. } else {
  920. usernameMessageElement.hide();
  921. emailMessageElement.hide();
  922. Popup.close();
  923. }
  924. },
  925. );
  926. Popup.close();
  927. },
  928. 'click #addUserOrgNewUser'(event) {
  929. event.preventDefault();
  930. userOrgsTeamsAction = "addOrg";
  931. document.getElementById("jsOrgsNewUser").style.display = 'block';
  932. document.getElementById("jsTeamsNewUser").style.display = 'none';
  933. },
  934. 'click #removeUserOrgNewUser'(event) {
  935. event.preventDefault();
  936. userOrgsTeamsAction = "removeOrg";
  937. document.getElementById("jsOrgsNewUser").style.display = 'block';
  938. document.getElementById("jsTeamsNewUser").style.display = 'none';
  939. },
  940. 'click #addUserTeamNewUser'(event) {
  941. event.preventDefault();
  942. userOrgsTeamsAction = "addTeam";
  943. document.getElementById("jsTeamsNewUser").style.display = 'block';
  944. document.getElementById("jsOrgsNewUser").style.display = 'none';
  945. },
  946. 'click #removeUserTeamNewUser'(event) {
  947. event.preventDefault();
  948. userOrgsTeamsAction = "removeTeam";
  949. document.getElementById("jsTeamsNewUser").style.display = 'block';
  950. document.getElementById("jsOrgsNewUser").style.display = 'none';
  951. },
  952. 'change #jsOrgsNewUser'(event) {
  953. event.preventDefault();
  954. UpdateUserOrgsOrTeamsElement(true);
  955. },
  956. 'change #jsTeamsNewUser'(event) {
  957. event.preventDefault();
  958. UpdateUserOrgsOrTeamsElement(true);
  959. },
  960. });
  961. Template.settingsOrgPopup.events({
  962. 'click #deleteButton'(event) {
  963. event.preventDefault();
  964. if(Users.find({"orgs.orgId": this.orgId}).count() > 0)
  965. {
  966. let orgClassList = document.getElementById("deleteOrgWarningMessage").classList;
  967. if(orgClassList.contains('hide'))
  968. {
  969. orgClassList.remove('hide');
  970. document.getElementById("deleteOrgWarningMessage").style.color = "red";
  971. }
  972. return;
  973. }
  974. Org.remove(this.orgId);
  975. Popup.close();
  976. }
  977. });
  978. Template.settingsTeamPopup.events({
  979. 'click #deleteButton'(event) {
  980. event.preventDefault();
  981. if(Users.find({"teams.teamId": this.teamId}).count() > 0)
  982. {
  983. let teamClassList = document.getElementById("deleteTeamWarningMessage").classList;
  984. if(teamClassList.contains('hide'))
  985. {
  986. teamClassList.remove('hide');
  987. document.getElementById("deleteTeamWarningMessage").style.color = "red";
  988. }
  989. return;
  990. }
  991. Team.remove(this.teamId);
  992. Popup.close();
  993. }
  994. });
  995. Template.settingsUserPopup.events({
  996. 'click .impersonate-user'(event) {
  997. event.preventDefault();
  998. Meteor.call('impersonate', this.userId, (err) => {
  999. if (!err) {
  1000. FlowRouter.go('/');
  1001. Meteor.connection.setUserId(this.userId);
  1002. }
  1003. });
  1004. },
  1005. 'click #deleteButton'(event) {
  1006. event.preventDefault();
  1007. Users.remove(this.userId);
  1008. /*
  1009. // Delete user is enabled, but you should remove user from all boards
  1010. // before deleting user, because there is possibility of leaving empty user avatars
  1011. // to boards. You can remove non-existing user ids manually from database,
  1012. // if that happens.
  1013. //. See:
  1014. // - wekan/client/components/settings/peopleBody.jade deleteButton
  1015. // - wekan/client/components/settings/peopleBody.js deleteButton
  1016. // - wekan/client/components/sidebar/sidebar.js Popup.afterConfirm('removeMember'
  1017. // that does now remove member from board, card members and assignees correctly,
  1018. // but that should be used to remove user from all boards similarly
  1019. // - wekan/models/users.js Delete is not enabled
  1020. //
  1021. //
  1022. */
  1023. Popup.close();
  1024. },
  1025. });
  1026. Template.settingsUserPopup.helpers({
  1027. user() {
  1028. return Users.findOne(this.userId);
  1029. },
  1030. authentications() {
  1031. return Template.instance().authenticationMethods.get();
  1032. },
  1033. isSelected(match) {
  1034. const userId = Template.instance().data.userId;
  1035. const selected = Users.findOne(userId).authenticationMethod;
  1036. return selected === match;
  1037. },
  1038. isLdap() {
  1039. const userId = Template.instance().data.userId;
  1040. const selected = Users.findOne(userId).authenticationMethod;
  1041. return selected === 'ldap';
  1042. },
  1043. errorMessage() {
  1044. return Template.instance().errorMessage.get();
  1045. },
  1046. });