userHeader.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477
  1. Template.headerUserBar.events({
  2. 'click .js-open-header-member-menu': Popup.open('memberMenu'),
  3. 'click .js-change-avatar': Popup.open('changeAvatar'),
  4. });
  5. BlazeComponent.extendComponent({
  6. onCreated() {
  7. Meteor.subscribe('setting');
  8. },
  9. }).register('memberMenuPopup');
  10. Template.memberMenuPopup.helpers({
  11. templatesBoardId() {
  12. currentUser = Meteor.user();
  13. if (currentUser) {
  14. return Meteor.user().getTemplatesBoardId();
  15. } else {
  16. // No need to getTemplatesBoardId on public board
  17. return false;
  18. }
  19. },
  20. templatesBoardSlug() {
  21. currentUser = Meteor.user();
  22. if (currentUser) {
  23. return Meteor.user().getTemplatesBoardSlug();
  24. } else {
  25. // No need to getTemplatesBoardSlug() on public board
  26. return false;
  27. }
  28. },
  29. isSameDomainNameSettingValue(){
  30. const currSett = Settings.findOne();
  31. if(currSett && currSett != undefined && currSett.disableRegistration && currSett.mailDomainName !== undefined && currSett.mailDomainName != ""){
  32. currentUser = Meteor.user();
  33. if (currentUser) {
  34. let found = false;
  35. for(let i = 0; i < currentUser.emails.length; i++) {
  36. if(currentUser.emails[i].address.endsWith(currSett.mailDomainName)){
  37. found = true;
  38. break;
  39. }
  40. }
  41. return found;
  42. } else {
  43. return true;
  44. }
  45. }
  46. else
  47. return false;
  48. },
  49. isNotOAuth2AuthenticationMethod(){
  50. currentUser = Meteor.user();
  51. if (currentUser) {
  52. return currentUser.authenticationMethod.toLowerCase() != 'oauth2';
  53. } else {
  54. return true;
  55. }
  56. }
  57. });
  58. Template.memberMenuPopup.events({
  59. 'click .js-my-cards'() {
  60. Popup.back();
  61. },
  62. 'click .js-due-cards'() {
  63. Popup.back();
  64. },
  65. 'click .js-open-archived-board'() {
  66. Modal.open('archivedBoards');
  67. },
  68. 'click .js-invite-people': Popup.open('invitePeople'),
  69. 'click .js-edit-profile': Popup.open('editProfile'),
  70. 'click .js-change-settings': Popup.open('changeSettings'),
  71. 'click .js-change-avatar': Popup.open('changeAvatar'),
  72. 'click .js-change-password': Popup.open('changePassword'),
  73. 'click .js-change-language': Popup.open('changeLanguage'),
  74. 'click .js-logout'(event) {
  75. event.preventDefault();
  76. AccountsTemplates.logout();
  77. },
  78. 'click .js-go-setting'() {
  79. Popup.back();
  80. },
  81. });
  82. BlazeComponent.extendComponent({
  83. onCreated() {
  84. Meteor.subscribe('setting');
  85. },
  86. }).register('editProfilePopup');
  87. Template.invitePeoplePopup.events({
  88. 'click a.js-toggle-board-choose'(event){
  89. let target = $(event.target);
  90. if (!target.hasClass('js-toggle-board-choose')) {
  91. target = target.parent();
  92. }
  93. const checkboxId = target.attr('id');
  94. $(`#${checkboxId} .materialCheckBox`).toggleClass('is-checked');
  95. $(`#${checkboxId}`).toggleClass('is-checked');
  96. },
  97. 'click button.js-email-invite'(event){
  98. const emails = $('#email-to-invite')
  99. .val()
  100. .toLowerCase()
  101. .trim()
  102. .split('\n')
  103. .join(',')
  104. .split(',');
  105. const boardsToInvite = [];
  106. $('.js-toggle-board-choose .materialCheckBox.is-checked').each(function() {
  107. boardsToInvite.push($(this).data('id'));
  108. });
  109. const validEmails = [];
  110. emails.forEach(email => {
  111. if (email && SimpleSchema.RegEx.Email.test(email.trim())) {
  112. validEmails.push(email.trim());
  113. }
  114. });
  115. if (validEmails.length) {
  116. Meteor.call('sendInvitation', validEmails, boardsToInvite, (_, rc) => {
  117. if (rc == 0) {
  118. let divInfos = document.getElementById("invite-people-infos");
  119. if(divInfos && divInfos !== undefined){
  120. divInfos.innerHTML = "<span style='color: green'>" + TAPi18n.__('invite-people-success') + "</span>";
  121. }
  122. }
  123. else{
  124. let divInfos = document.getElementById("invite-people-infos");
  125. if(divInfos && divInfos !== undefined){
  126. divInfos.innerHTML = "<span style='color: red'>" + TAPi18n.__('invite-people-error') + "</span>";
  127. }
  128. }
  129. // Popup.close();
  130. });
  131. }
  132. },
  133. });
  134. Template.invitePeoplePopup.helpers({
  135. currentSetting() {
  136. return Settings.findOne();
  137. },
  138. });
  139. Template.editProfilePopup.helpers({
  140. allowEmailChange() {
  141. Meteor.call('AccountSettings.allowEmailChange', (_, result) => {
  142. if (result) {
  143. return true;
  144. } else {
  145. return false;
  146. }
  147. });
  148. },
  149. allowUserNameChange() {
  150. Meteor.call('AccountSettings.allowUserNameChange', (_, result) => {
  151. if (result) {
  152. return true;
  153. } else {
  154. return false;
  155. }
  156. });
  157. },
  158. allowUserDelete() {
  159. Meteor.call('AccountSettings.allowUserDelete', (_, result) => {
  160. if (result) {
  161. return true;
  162. } else {
  163. return false;
  164. }
  165. });
  166. },
  167. });
  168. Template.editProfilePopup.events({
  169. submit(event, templateInstance) {
  170. event.preventDefault();
  171. const fullname = templateInstance.find('.js-profile-fullname').value.trim();
  172. const username = templateInstance.find('.js-profile-username').value.trim();
  173. const initials = templateInstance.find('.js-profile-initials').value.trim();
  174. const email = templateInstance.find('.js-profile-email').value.trim();
  175. let isChangeUserName = false;
  176. let isChangeEmail = false;
  177. Users.update(Meteor.userId(), {
  178. $set: {
  179. 'profile.fullname': fullname,
  180. 'profile.initials': initials,
  181. },
  182. });
  183. isChangeUserName = username !== Meteor.user().username;
  184. isChangeEmail =
  185. email.toLowerCase() !== Meteor.user().emails[0].address.toLowerCase();
  186. if (isChangeUserName && isChangeEmail) {
  187. Meteor.call(
  188. 'setUsernameAndEmail',
  189. username,
  190. email.toLowerCase(),
  191. Meteor.userId(),
  192. function(error) {
  193. const usernameMessageElement = templateInstance.$('.username-taken');
  194. const emailMessageElement = templateInstance.$('.email-taken');
  195. if (error) {
  196. const errorElement = error.error;
  197. if (errorElement === 'username-already-taken') {
  198. usernameMessageElement.show();
  199. emailMessageElement.hide();
  200. } else if (errorElement === 'email-already-taken') {
  201. usernameMessageElement.hide();
  202. emailMessageElement.show();
  203. }
  204. } else {
  205. usernameMessageElement.hide();
  206. emailMessageElement.hide();
  207. Popup.back();
  208. }
  209. },
  210. );
  211. } else if (isChangeUserName) {
  212. Meteor.call('setUsername', username, Meteor.userId(), function(error) {
  213. const messageElement = templateInstance.$('.username-taken');
  214. if (error) {
  215. messageElement.show();
  216. } else {
  217. messageElement.hide();
  218. Popup.back();
  219. }
  220. });
  221. } else if (isChangeEmail) {
  222. Meteor.call('setEmail', email.toLowerCase(), Meteor.userId(), function(
  223. error,
  224. ) {
  225. const messageElement = templateInstance.$('.email-taken');
  226. if (error) {
  227. messageElement.show();
  228. } else {
  229. messageElement.hide();
  230. Popup.back();
  231. }
  232. });
  233. } else Popup.back();
  234. },
  235. 'click #deleteButton': Popup.afterConfirm('userDelete', function() {
  236. Popup.back();
  237. Users.remove(Meteor.userId());
  238. AccountsTemplates.logout();
  239. }),
  240. });
  241. // XXX For some reason the useraccounts autofocus isnt working in this case.
  242. // See https://github.com/meteor-useraccounts/core/issues/384
  243. Template.changePasswordPopup.onRendered(function() {
  244. this.find('#at-field-current_password').focus();
  245. });
  246. Template.changeLanguagePopup.helpers({
  247. languages() {
  248. return _.map(TAPi18n.getLanguages(), (lang, code) => {
  249. // Same code in /client/components/main/layouts.js
  250. // TODO : Make code reusable
  251. const tag = code;
  252. let name = lang.name;
  253. if (lang.name === 'br') {
  254. name = 'Brezhoneg';
  255. } else if (lang.name === 'ar-EG') {
  256. // ar-EG = Arabic (Egypt), simply Masri (مَصرى, [ˈmɑsˤɾi], Egyptian, Masr refers to Cairo)
  257. name = 'مَصرى';
  258. } else if (lang.name === 'cs-CZ') {
  259. name = 'čeština (Česká republika)';
  260. } else if (lang.name === 'de-CH') {
  261. name = 'Deutsch (Schweiz)';
  262. } else if (lang.name === 'de-AT') {
  263. name = 'Deutsch (Österreich)';
  264. } else if (lang.name === 'en-BR') {
  265. name = 'English (Brazil)';
  266. } else if (lang.name === 'en-DE') {
  267. name = 'English (Germany)';
  268. } else if (lang.name === 'et-EE') {
  269. name = 'eesti keel (Eesti)';
  270. } else if (lang.name === 'fa-IR') {
  271. // fa-IR = Persian (Iran)
  272. name = 'فارسی/پارسی (ایران‎)';
  273. } else if (lang.name === 'fr-BE') {
  274. name = 'Français (Belgique)';
  275. } else if (lang.name === 'fr-CA') {
  276. name = 'Français (Canada)';
  277. } else if (lang.name === 'fr-CH') {
  278. name = 'Français (Schweiz)';
  279. } else if (lang.name === 'gu-IN') {
  280. // gu-IN = Gurajati (India)
  281. name = 'ગુજરાતી';
  282. } else if (lang.name === 'hi-IN') {
  283. // hi-IN = Hindi (India)
  284. name = 'हिंदी (भारत)';
  285. } else if (lang.name === 'ig') {
  286. name = 'Igbo';
  287. } else if (lang.name === 'lv') {
  288. name = 'Latviešu';
  289. } else if (lang.name === 'latviešu valoda') {
  290. name = 'Latviešu';
  291. } else if (lang.name === 'ms-MY') {
  292. // ms-MY = Malay (Malaysia)
  293. name = 'بهاس ملايو';
  294. } else if (lang.name === 'en-IT') {
  295. name = 'English (Italy)';
  296. } else if (lang.name === 'el-GR') {
  297. // el-GR = Greek (Greece)
  298. name = 'Ελληνικά (Ελλάδα)';
  299. } else if (lang.name === 'Español') {
  300. name = 'español';
  301. } else if (lang.name === 'es_419') {
  302. name = 'español de América Latina';
  303. } else if (lang.name === 'es-419') {
  304. name = 'español de América Latina';
  305. } else if (lang.name === 'Español de América Latina') {
  306. name = 'español de América Latina';
  307. } else if (lang.name === 'es-LA') {
  308. name = 'español de América Latina';
  309. } else if (lang.name === 'Español de Argentina') {
  310. name = 'español de Argentina';
  311. } else if (lang.name === 'Español de Chile') {
  312. name = 'español de Chile';
  313. } else if (lang.name === 'Español de Colombia') {
  314. name = 'español de Colombia';
  315. } else if (lang.name === 'Español de México') {
  316. name = 'español de México';
  317. } else if (lang.name === 'es-PY') {
  318. name = 'español de Paraguayo';
  319. } else if (lang.name === 'Español de Paraguayo') {
  320. name = 'español de Paraguayo';
  321. } else if (lang.name === 'Español de Perú') {
  322. name = 'español de Perú';
  323. } else if (lang.name === 'Español de Puerto Rico') {
  324. name = 'español de Puerto Rico';
  325. } else if (lang.name === 'gl-ES') {
  326. name = 'Galego (España)';
  327. } else if (lang.name === 'oc') {
  328. name = 'Occitan';
  329. } else if (lang.name === 'ru-UA') {
  330. name = 'Русский (Украина)';
  331. } else if (lang.name === 'st') {
  332. name = 'Sãotomense';
  333. } else if (lang.name === 'uk-UA') {
  334. name = 'українська (Україна)';
  335. } else if (lang.name === '繁体中文(台湾)') {
  336. // Traditional Chinese (Taiwan)
  337. name = '繁體中文(台灣)';
  338. }
  339. return { tag, name };
  340. }).sort(function(a, b) {
  341. if (a.name === b.name) {
  342. return 0;
  343. } else {
  344. return a.name > b.name ? 1 : -1;
  345. }
  346. });
  347. },
  348. isCurrentLanguage() {
  349. return this.tag === TAPi18n.getLanguage();
  350. },
  351. });
  352. Template.changeLanguagePopup.events({
  353. 'click .js-set-language'(event) {
  354. Users.update(Meteor.userId(), {
  355. $set: {
  356. 'profile.language': this.tag,
  357. },
  358. });
  359. TAPi18n.setLanguage(this.tag);
  360. event.preventDefault();
  361. },
  362. });
  363. Template.changeSettingsPopup.helpers({
  364. hiddenSystemMessages() {
  365. currentUser = Meteor.user();
  366. if (currentUser) {
  367. return (currentUser.profile || {}).hasHiddenSystemMessages;
  368. } else if (window.localStorage.getItem('hasHiddenSystemMessages')) {
  369. return true;
  370. } else {
  371. return false;
  372. }
  373. },
  374. showCardsCountAt() {
  375. currentUser = Meteor.user();
  376. if (currentUser) {
  377. return Meteor.user().getLimitToShowCardsCount();
  378. } else {
  379. return window.localStorage.getItem('limitToShowCardsCount');
  380. }
  381. },
  382. weekDays(startDay) {
  383. return [
  384. TAPi18n.__('sunday'),
  385. TAPi18n.__('monday'),
  386. TAPi18n.__('tuesday'),
  387. TAPi18n.__('wednesday'),
  388. TAPi18n.__('thursday'),
  389. TAPi18n.__('friday'),
  390. TAPi18n.__('saturday'),
  391. ].map(function(day, index) {
  392. return { name: day, value: index, isSelected: index === startDay };
  393. });
  394. },
  395. startDayOfWeek() {
  396. currentUser = Meteor.user();
  397. if (currentUser) {
  398. return currentUser.getStartDayOfWeek();
  399. } else {
  400. return window.localStorage.getItem('startDayOfWeek');
  401. }
  402. },
  403. });
  404. Template.changeSettingsPopup.events({
  405. 'keypress/paste #show-cards-count-at'() {
  406. let keyCode = event.keyCode;
  407. let charCode = String.fromCharCode(keyCode);
  408. let regex = new RegExp('[-0-9]');
  409. let ret = regex.test(charCode);
  410. return ret;
  411. },
  412. 'click .js-toggle-desktop-drag-handles'() {
  413. currentUser = Meteor.user();
  414. if (currentUser) {
  415. Meteor.call('toggleDesktopDragHandles');
  416. } else if (window.localStorage.getItem('showDesktopDragHandles')) {
  417. window.localStorage.removeItem('showDesktopDragHandles');
  418. } else {
  419. window.localStorage.setItem('showDesktopDragHandles', 'true');
  420. }
  421. },
  422. 'click .js-toggle-system-messages'() {
  423. currentUser = Meteor.user();
  424. if (currentUser) {
  425. Meteor.call('toggleSystemMessages');
  426. } else if (window.localStorage.getItem('hasHiddenSystemMessages')) {
  427. window.localStorage.removeItem('hasHiddenSystemMessages');
  428. } else {
  429. window.localStorage.setItem('hasHiddenSystemMessages', 'true');
  430. }
  431. },
  432. 'click .js-apply-user-settings'(event, templateInstance) {
  433. event.preventDefault();
  434. let minLimit = parseInt(
  435. templateInstance.$('#show-cards-count-at').val(),
  436. 10,
  437. );
  438. const startDay = parseInt(
  439. templateInstance.$('#start-day-of-week').val(),
  440. 10,
  441. );
  442. const currentUser = Meteor.user();
  443. if (isNaN(minLimit) || minLimit < -1) {
  444. minLimit = -1;
  445. }
  446. if (!isNaN(minLimit)) {
  447. if (currentUser) {
  448. Meteor.call('changeLimitToShowCardsCount', minLimit);
  449. } else {
  450. window.localStorage.setItem('limitToShowCardsCount', minLimit);
  451. }
  452. }
  453. if (!isNaN(startDay)) {
  454. if (currentUser) {
  455. Meteor.call('changeStartDayOfWeek', startDay);
  456. } else {
  457. window.localStorage.setItem('startDayOfWeek', startDay);
  458. }
  459. }
  460. Popup.back();
  461. },
  462. });