peopleBody.js 35 KB

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