peopleBody.js 36 KB

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