boardHeader.js 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. Template.boardMenuPopup.events({
  2. 'click .js-rename-board': Popup.open('boardChangeTitle'),
  3. 'click .js-custom-fields'() {
  4. Sidebar.setView('customFields');
  5. Popup.close();
  6. },
  7. 'click .js-open-archives'() {
  8. Sidebar.setView('archives');
  9. Popup.close();
  10. },
  11. 'click .js-change-board-color': Popup.open('boardChangeColor'),
  12. 'click .js-change-language': Popup.open('changeLanguage'),
  13. 'click .js-archive-board ': Popup.afterConfirm('archiveBoard', function() {
  14. const currentBoard = Boards.findOne(Session.get('currentBoard'));
  15. currentBoard.archive();
  16. // XXX We should have some kind of notification on top of the page to
  17. // confirm that the board was successfully archived.
  18. FlowRouter.go('home');
  19. }),
  20. 'click .js-delete-board': Popup.afterConfirm('deleteBoard', function() {
  21. const currentBoard = Boards.findOne(Session.get('currentBoard'));
  22. Popup.close();
  23. Boards.remove(currentBoard._id);
  24. FlowRouter.go('home');
  25. }),
  26. 'click .js-outgoing-webhooks': Popup.open('outgoingWebhooks'),
  27. 'click .js-import-board': Popup.open('chooseBoardSource'),
  28. });
  29. Template.boardMenuPopup.helpers({
  30. exportUrl() {
  31. const params = {
  32. boardId: Session.get('currentBoard'),
  33. };
  34. const queryParams = {
  35. authToken: Accounts._storedLoginToken(),
  36. };
  37. return FlowRouter.path('/api/boards/:boardId/export', params, queryParams);
  38. },
  39. exportFilename() {
  40. const boardId = Session.get('currentBoard');
  41. return `wekan-export-board-${boardId}.json`;
  42. },
  43. });
  44. Template.boardChangeTitlePopup.events({
  45. submit(evt, tpl) {
  46. const newTitle = tpl.$('.js-board-name').val().trim();
  47. const newDesc = tpl.$('.js-board-desc').val().trim();
  48. if (newTitle) {
  49. this.rename(newTitle);
  50. this.setDescription(newDesc);
  51. Popup.close();
  52. }
  53. evt.preventDefault();
  54. },
  55. });
  56. BlazeComponent.extendComponent({
  57. watchLevel() {
  58. const currentBoard = Boards.findOne(Session.get('currentBoard'));
  59. return currentBoard && currentBoard.getWatchLevel(Meteor.userId());
  60. },
  61. isStarred() {
  62. const boardId = Session.get('currentBoard');
  63. const user = Meteor.user();
  64. return user && user.hasStarred(boardId);
  65. },
  66. // Only show the star counter if the number of star is greater than 2
  67. showStarCounter() {
  68. const currentBoard = Boards.findOne(Session.get('currentBoard'));
  69. return currentBoard && currentBoard.stars >= 2;
  70. },
  71. events() {
  72. return [{
  73. 'click .js-edit-board-title': Popup.open('boardChangeTitle'),
  74. 'click .js-star-board'() {
  75. Meteor.user().toggleBoardStar(Session.get('currentBoard'));
  76. },
  77. 'click .js-open-board-menu': Popup.open('boardMenu'),
  78. 'click .js-change-visibility': Popup.open('boardChangeVisibility'),
  79. 'click .js-watch-board': Popup.open('boardChangeWatch'),
  80. 'click .js-open-archived-board'() {
  81. Modal.open('archivedBoards');
  82. },
  83. 'click .js-toggle-board-view'() {
  84. const currentUser = Meteor.user();
  85. if (currentUser.profile.boardView === 'board-view-swimlanes') {
  86. currentUser.setBoardView('board-view-cal');
  87. } else if (currentUser.profile.boardView === 'board-view-lists') {
  88. currentUser.setBoardView('board-view-swimlanes');
  89. } else if (currentUser.profile.boardView === 'board-view-cal') {
  90. currentUser.setBoardView('board-view-lists');
  91. }
  92. },
  93. 'click .js-open-filter-view'() {
  94. Sidebar.setView('filter');
  95. },
  96. 'click .js-filter-reset'(evt) {
  97. evt.stopPropagation();
  98. Sidebar.setView();
  99. Filter.reset();
  100. },
  101. 'click .js-open-search-view'() {
  102. Sidebar.setView('search');
  103. },
  104. 'click .js-multiselection-activate'() {
  105. const currentCard = Session.get('currentCard');
  106. MultiSelection.activate();
  107. if (currentCard) {
  108. MultiSelection.add(currentCard);
  109. }
  110. },
  111. 'click .js-multiselection-reset'(evt) {
  112. evt.stopPropagation();
  113. MultiSelection.disable();
  114. },
  115. 'click .js-log-in'() {
  116. FlowRouter.go('atSignIn');
  117. },
  118. }];
  119. },
  120. }).register('boardHeaderBar');
  121. Template.boardHeaderBar.helpers({
  122. canModifyBoard() {
  123. return Meteor.user() && Meteor.user().isBoardMember() && !Meteor.user().isCommentOnly();
  124. },
  125. });
  126. BlazeComponent.extendComponent({
  127. backgroundColors() {
  128. return Boards.simpleSchema()._schema.color.allowedValues;
  129. },
  130. isSelected() {
  131. const currentBoard = Boards.findOne(Session.get('currentBoard'));
  132. return currentBoard.color === this.currentData().toString();
  133. },
  134. events() {
  135. return [{
  136. 'click .js-select-background'(evt) {
  137. const currentBoard = Boards.findOne(Session.get('currentBoard'));
  138. const newColor = this.currentData().toString();
  139. currentBoard.setColor(newColor);
  140. evt.preventDefault();
  141. },
  142. }];
  143. },
  144. }).register('boardChangeColorPopup');
  145. const CreateBoard = BlazeComponent.extendComponent({
  146. template() {
  147. return 'createBoard';
  148. },
  149. onCreated() {
  150. this.visibilityMenuIsOpen = new ReactiveVar(false);
  151. this.visibility = new ReactiveVar('private');
  152. this.boardId = new ReactiveVar('');
  153. },
  154. visibilityCheck() {
  155. return this.currentData() === this.visibility.get();
  156. },
  157. setVisibility(visibility) {
  158. this.visibility.set(visibility);
  159. this.visibilityMenuIsOpen.set(false);
  160. },
  161. toggleVisibilityMenu() {
  162. this.visibilityMenuIsOpen.set(!this.visibilityMenuIsOpen.get());
  163. },
  164. onSubmit(evt) {
  165. evt.preventDefault();
  166. const title = this.find('.js-new-board-title').value;
  167. const visibility = this.visibility.get();
  168. this.boardId.set(Boards.insert({
  169. title,
  170. permission: visibility,
  171. }));
  172. Swimlanes.insert({
  173. title: 'Default',
  174. boardId: this.boardId.get(),
  175. });
  176. Utils.goBoardId(this.boardId.get());
  177. },
  178. events() {
  179. return [{
  180. 'click .js-select-visibility'() {
  181. this.setVisibility(this.currentData());
  182. },
  183. 'click .js-change-visibility': this.toggleVisibilityMenu,
  184. 'click .js-import': Popup.open('boardImportBoard'),
  185. submit: this.onSubmit,
  186. 'click .js-import-board': Popup.open('chooseBoardSource'),
  187. }];
  188. },
  189. }).register('createBoardPopup');
  190. BlazeComponent.extendComponent({
  191. template() {
  192. return 'chooseBoardSource';
  193. },
  194. }).register('chooseBoardSourcePopup');
  195. (class HeaderBarCreateBoard extends CreateBoard {
  196. onSubmit(evt) {
  197. super.onSubmit(evt);
  198. // Immediately star boards crated with the headerbar popup.
  199. Meteor.user().toggleBoardStar(this.boardId.get());
  200. }
  201. }).register('headerBarCreateBoardPopup');
  202. BlazeComponent.extendComponent({
  203. visibilityCheck() {
  204. const currentBoard = Boards.findOne(Session.get('currentBoard'));
  205. return this.currentData() === currentBoard.permission;
  206. },
  207. selectBoardVisibility() {
  208. const currentBoard = Boards.findOne(Session.get('currentBoard'));
  209. const visibility = this.currentData();
  210. currentBoard.setVisibility(visibility);
  211. Popup.close();
  212. },
  213. events() {
  214. return [{
  215. 'click .js-select-visibility': this.selectBoardVisibility,
  216. }];
  217. },
  218. }).register('boardChangeVisibilityPopup');
  219. BlazeComponent.extendComponent({
  220. watchLevel() {
  221. const currentBoard = Boards.findOne(Session.get('currentBoard'));
  222. return currentBoard.getWatchLevel(Meteor.userId());
  223. },
  224. watchCheck() {
  225. return this.currentData() === this.watchLevel();
  226. },
  227. events() {
  228. return [{
  229. 'click .js-select-watch'() {
  230. const level = this.currentData();
  231. Meteor.call('watch', 'board', Session.get('currentBoard'), level, (err, ret) => {
  232. if (!err && ret) Popup.close();
  233. });
  234. },
  235. }];
  236. },
  237. }).register('boardChangeWatchPopup');
  238. BlazeComponent.extendComponent({
  239. integrations() {
  240. const boardId = Session.get('currentBoard');
  241. return Integrations.find({ boardId: `${boardId}` }).fetch();
  242. },
  243. integration(id) {
  244. const boardId = Session.get('currentBoard');
  245. return Integrations.findOne({ _id: id, boardId: `${boardId}` });
  246. },
  247. events() {
  248. return [{
  249. 'submit'(evt) {
  250. evt.preventDefault();
  251. const url = evt.target.url.value;
  252. const boardId = Session.get('currentBoard');
  253. let id = null;
  254. let integration = null;
  255. if (evt.target.id) {
  256. id = evt.target.id.value;
  257. integration = this.integration(id);
  258. if (url) {
  259. Integrations.update(integration._id, {
  260. $set: {
  261. url: `${url}`,
  262. },
  263. });
  264. } else {
  265. Integrations.remove(integration._id);
  266. }
  267. } else if (url) {
  268. Integrations.insert({
  269. userId: Meteor.userId(),
  270. enabled: true,
  271. type: 'outgoing-webhooks',
  272. url: `${url}`,
  273. boardId: `${boardId}`,
  274. activities: ['all'],
  275. });
  276. }
  277. Popup.close();
  278. },
  279. }];
  280. },
  281. }).register('outgoingWebhooksPopup');