settingBody.js 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. BlazeComponent.extendComponent({
  2. onCreated() {
  3. this.error = new ReactiveVar('');
  4. this.loading = new ReactiveVar(false);
  5. this.generalSetting = new ReactiveVar(true);
  6. this.emailSetting = new ReactiveVar(false);
  7. this.accountSetting = new ReactiveVar(false);
  8. this.announcementSetting = new ReactiveVar(false);
  9. this.layoutSetting = new ReactiveVar(false);
  10. Meteor.subscribe('setting');
  11. Meteor.subscribe('mailServer');
  12. Meteor.subscribe('accountSettings');
  13. Meteor.subscribe('announcements');
  14. },
  15. setError(error) {
  16. this.error.set(error);
  17. },
  18. setLoading(w) {
  19. this.loading.set(w);
  20. },
  21. checkField(selector) {
  22. const value = $(selector).val();
  23. if (!value || value.trim() === '') {
  24. $(selector).parents('li.smtp-form').addClass('has-error');
  25. throw Error('blank field');
  26. } else {
  27. return value;
  28. }
  29. },
  30. currentSetting() {
  31. return Settings.findOne();
  32. },
  33. boards() {
  34. return Boards.find({
  35. archived: false,
  36. 'members.userId': Meteor.userId(),
  37. 'members.isAdmin': true,
  38. }, {
  39. sort: ['title'],
  40. });
  41. },
  42. toggleRegistration() {
  43. this.setLoading(true);
  44. const registrationClosed = this.currentSetting().disableRegistration;
  45. Settings.update(Settings.findOne()._id, {$set: {disableRegistration: !registrationClosed}});
  46. this.setLoading(false);
  47. if (registrationClosed) {
  48. $('.invite-people').slideUp();
  49. } else {
  50. $('.invite-people').slideDown();
  51. }
  52. },
  53. toggleTLS() {
  54. $('#mail-server-tls').toggleClass('is-checked');
  55. },
  56. toggleHideLogo() {
  57. $('#hide-logo').toggleClass('is-checked');
  58. },
  59. toggleDisplayAuthenticationMethod() {
  60. $('#display-authentication-method').toggleClass('is-checked');
  61. },
  62. switchMenu(event) {
  63. const target = $(event.target);
  64. if (!target.hasClass('active')) {
  65. $('.side-menu li.active').removeClass('active');
  66. target.parent().addClass('active');
  67. const targetID = target.data('id');
  68. this.generalSetting.set('registration-setting' === targetID);
  69. this.emailSetting.set('email-setting' === targetID);
  70. this.accountSetting.set('account-setting' === targetID);
  71. this.announcementSetting.set('announcement-setting' === targetID);
  72. this.layoutSetting.set('layout-setting' === targetID);
  73. }
  74. },
  75. checkBoard(event) {
  76. let target = $(event.target);
  77. if (!target.hasClass('js-toggle-board-choose')) {
  78. target = target.parent();
  79. }
  80. const checkboxId = target.attr('id');
  81. $(`#${checkboxId} .materialCheckBox`).toggleClass('is-checked');
  82. $(`#${checkboxId}`).toggleClass('is-checked');
  83. },
  84. inviteThroughEmail() {
  85. const emails = $('#email-to-invite').val().toLowerCase().trim().split('\n').join(',').split(',');
  86. const boardsToInvite = [];
  87. $('.js-toggle-board-choose .materialCheckBox.is-checked').each(function () {
  88. boardsToInvite.push($(this).data('id'));
  89. });
  90. const validEmails = [];
  91. emails.forEach((email) => {
  92. if (email && SimpleSchema.RegEx.Email.test(email.trim())) {
  93. validEmails.push(email.trim());
  94. }
  95. });
  96. if (validEmails.length) {
  97. this.setLoading(true);
  98. Meteor.call('sendInvitation', validEmails, boardsToInvite, () => {
  99. // if (!err) {
  100. // TODO - show more info to user
  101. // }
  102. this.setLoading(false);
  103. });
  104. }
  105. },
  106. saveMailServerInfo() {
  107. this.setLoading(true);
  108. $('li').removeClass('has-error');
  109. try {
  110. const host = this.checkField('#mail-server-host');
  111. const port = this.checkField('#mail-server-port');
  112. const username = $('#mail-server-username').val().trim();
  113. const password = $('#mail-server-password').val().trim();
  114. const from = this.checkField('#mail-server-from');
  115. const tls = $('#mail-server-tls.is-checked').length > 0;
  116. Settings.update(Settings.findOne()._id, {
  117. $set: {
  118. 'mailServer.host': host, 'mailServer.port': port, 'mailServer.username': username,
  119. 'mailServer.password': password, 'mailServer.enableTLS': tls, 'mailServer.from': from,
  120. },
  121. });
  122. } catch (e) {
  123. return;
  124. } finally {
  125. this.setLoading(false);
  126. }
  127. },
  128. saveLayout() {
  129. this.setLoading(true);
  130. $('li').removeClass('has-error');
  131. const productName = $('#product-name').val().trim();
  132. const hideLogoChange = ($('input[name=hideLogo]:checked').val() === 'true');
  133. const displayAuthenticationMethod = ($('input[name=displayAuthenticationMethod]:checked').val() === 'true');
  134. const defaultAuthenticationMethod = $('#defaultAuthenticationMethod').val();
  135. const customHTMLafterBodyStart = $('#customHTMLafterBodyStart').val().trim();
  136. const customHTMLbeforeBodyEnd = $('#customHTMLbeforeBodyEnd').val().trim();
  137. try {
  138. Settings.update(Settings.findOne()._id, {
  139. $set: {
  140. productName,
  141. hideLogo: hideLogoChange,
  142. customHTMLafterBodyStart,
  143. customHTMLbeforeBodyEnd,
  144. displayAuthenticationMethod,
  145. defaultAuthenticationMethod,
  146. },
  147. });
  148. } catch (e) {
  149. return;
  150. } finally {
  151. this.setLoading(false);
  152. }
  153. DocHead.setTitle(productName);
  154. },
  155. sendSMTPTestEmail() {
  156. Meteor.call('sendSMTPTestEmail', (err, ret) => {
  157. if (!err && ret) {
  158. const message = `${TAPi18n.__(ret.message)}: ${ret.email}`;
  159. alert(message);
  160. } else {
  161. const reason = err.reason || '';
  162. const message = `${TAPi18n.__(err.error)}\n${reason}`;
  163. alert(message);
  164. }
  165. });
  166. },
  167. events() {
  168. return [{
  169. 'click a.js-toggle-registration': this.toggleRegistration,
  170. 'click a.js-toggle-tls': this.toggleTLS,
  171. 'click a.js-setting-menu': this.switchMenu,
  172. 'click a.js-toggle-board-choose': this.checkBoard,
  173. 'click button.js-email-invite': this.inviteThroughEmail,
  174. 'click button.js-save': this.saveMailServerInfo,
  175. 'click button.js-send-smtp-test-email': this.sendSMTPTestEmail,
  176. 'click a.js-toggle-hide-logo': this.toggleHideLogo,
  177. 'click button.js-save-layout': this.saveLayout,
  178. 'click a.js-toggle-display-authentication-method': this.toggleDisplayAuthenticationMethod,
  179. }];
  180. },
  181. }).register('setting');
  182. BlazeComponent.extendComponent({
  183. saveAccountsChange() {
  184. const allowEmailChange = ($('input[name=allowEmailChange]:checked').val() === 'true');
  185. const allowUserNameChange = ($('input[name=allowUserNameChange]:checked').val() === 'true');
  186. AccountSettings.update('accounts-allowEmailChange', {
  187. $set: {'booleanValue': allowEmailChange},
  188. });
  189. AccountSettings.update('accounts-allowUserNameChange', {
  190. $set: {'booleanValue': allowUserNameChange},
  191. });
  192. },
  193. allowEmailChange() {
  194. return AccountSettings.findOne('accounts-allowEmailChange').booleanValue;
  195. },
  196. allowUserNameChange() {
  197. return AccountSettings.findOne('accounts-allowUserNameChange').booleanValue;
  198. },
  199. events() {
  200. return [{
  201. 'click button.js-accounts-save': this.saveAccountsChange,
  202. }];
  203. },
  204. }).register('accountSettings');
  205. BlazeComponent.extendComponent({
  206. onCreated() {
  207. this.loading = new ReactiveVar(false);
  208. },
  209. setLoading(w) {
  210. this.loading.set(w);
  211. },
  212. currentSetting() {
  213. return Announcements.findOne();
  214. },
  215. saveMessage() {
  216. const message = $('#admin-announcement').val().trim();
  217. Announcements.update(Announcements.findOne()._id, {
  218. $set: {'body': message},
  219. });
  220. },
  221. toggleActive() {
  222. this.setLoading(true);
  223. const isActive = this.currentSetting().enabled;
  224. Announcements.update(Announcements.findOne()._id, {
  225. $set: {'enabled': !isActive},
  226. });
  227. this.setLoading(false);
  228. if (isActive) {
  229. $('.admin-announcement').slideUp();
  230. } else {
  231. $('.admin-announcement').slideDown();
  232. }
  233. },
  234. events() {
  235. return [{
  236. 'click a.js-toggle-activemessage': this.toggleActive,
  237. 'click button.js-announcement-save': this.saveMessage,
  238. }];
  239. },
  240. }).register('announcementSettings');
  241. Template.selectAuthenticationMethod.onCreated(function() {
  242. this.authenticationMethods = new ReactiveVar([]);
  243. Meteor.call('getAuthenticationsEnabled', (_, result) => {
  244. if (result) {
  245. // TODO : add a management of different languages
  246. // (ex {value: ldap, text: TAPi18n.__('ldap', {}, T9n.getLanguage() || 'en')})
  247. this.authenticationMethods.set([
  248. {value: 'password'},
  249. // Gets only the authentication methods availables
  250. ...Object.entries(result).filter((e) => e[1]).map((e) => ({value: e[0]})),
  251. ]);
  252. }
  253. });
  254. });
  255. Template.selectAuthenticationMethod.helpers({
  256. authentications() {
  257. return Template.instance().authenticationMethods.get();
  258. },
  259. isSelected(match) {
  260. return Template.instance().data.authenticationMethod === match;
  261. },
  262. });