labels.js 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. import { ReactiveCache } from '/imports/reactiveCache';
  2. let labelColors;
  3. Meteor.startup(() => {
  4. labelColors = Boards.simpleSchema()._schema['labels.$.color'].allowedValues;
  5. });
  6. BlazeComponent.extendComponent({
  7. onCreated() {
  8. this.currentColor = new ReactiveVar(this.data().color);
  9. },
  10. labels() {
  11. return labelColors.map(color => ({ color, name: '' }));
  12. },
  13. isSelected(color) {
  14. return this.currentColor.get() === color;
  15. },
  16. events() {
  17. return [
  18. {
  19. 'click .js-palette-color'() {
  20. this.currentColor.set(this.currentData().color);
  21. },
  22. },
  23. ];
  24. },
  25. }).register('formLabel');
  26. Template.createLabelPopup.helpers({
  27. // This is the default color for a new label. We search the first color that
  28. // is not already used in the board (although it's not a problem if two
  29. // labels have the same color).
  30. defaultColor() {
  31. const labels = Utils.getCurrentBoard().labels;
  32. const usedColors = _.pluck(labels, 'color');
  33. const availableColors = _.difference(labelColors, usedColors);
  34. return availableColors.length > 1 ? availableColors[0] : labelColors[0];
  35. },
  36. });
  37. BlazeComponent.extendComponent({
  38. onRendered() {
  39. const itemsSelector = 'li.js-card-label-item:not(.placeholder)';
  40. const $labels = this.$('.edit-labels-pop-over');
  41. $labels.sortable({
  42. connectWith: '.edit-labels-pop-over',
  43. tolerance: 'pointer',
  44. appendTo: '.edit-labels-pop-over',
  45. helper(element, currentItem) {
  46. let ret = currentItem.clone();
  47. if (currentItem.closest('.popup-container-depth-0').length == 0)
  48. { // only set css transform at every sub-popup, not at the main popup
  49. const content = currentItem.closest('.content')[0]
  50. const offsetLeft = content.offsetLeft;
  51. const offsetTop = $('.pop-over > .header').height() * -1;
  52. ret.css("transform", `translate(${offsetLeft}px, ${offsetTop}px)`);
  53. }
  54. return ret;
  55. },
  56. distance: 7,
  57. items: itemsSelector,
  58. placeholder: 'card-label-wrapper placeholder',
  59. start(evt, ui) {
  60. ui.helper.css('z-index', 1000);
  61. ui.placeholder.height(ui.helper.height());
  62. EscapeActions.clickExecute(evt.target, 'inlinedForm');
  63. },
  64. stop(evt, ui) {
  65. const newLabelOrderOnlyIds = ui.item.parent().children().toArray().map(_element => Blaze.getData(_element)._id)
  66. const card = Blaze.getData(this);
  67. card.board().setNewLabelOrder(newLabelOrderOnlyIds);
  68. },
  69. });
  70. // Disable drag-dropping if the current user is not a board member or is comment only
  71. this.autorun(() => {
  72. if (Utils.isTouchScreenOrShowDesktopDragHandles()) {
  73. $labels.sortable({
  74. handle: '.label-handle',
  75. });
  76. }
  77. });
  78. },
  79. events() {
  80. return [
  81. {
  82. 'click .js-select-label'(event) {
  83. const card = this.data();
  84. const labelId = this.currentData()._id;
  85. card.toggleLabel(labelId);
  86. event.preventDefault();
  87. },
  88. 'click .js-edit-label': Popup.open('editLabel'),
  89. 'click .js-add-label': Popup.open('createLabel'),
  90. }
  91. ];
  92. }
  93. }).register('cardLabelsPopup');
  94. Template.cardLabelsPopup.events({
  95. });
  96. Template.formLabel.events({
  97. 'click .js-palette-color'(event) {
  98. const $this = $(event.currentTarget);
  99. // hide selected ll colors
  100. $('.js-palette-select').addClass('hide');
  101. // show select color
  102. $this.find('.js-palette-select').removeClass('hide');
  103. },
  104. });
  105. Template.createLabelPopup.events({
  106. // Create the new label
  107. 'submit .create-label'(event, templateInstance) {
  108. event.preventDefault();
  109. const board = Utils.getCurrentBoard();
  110. const name = templateInstance
  111. .$('#labelName')
  112. .val()
  113. .trim();
  114. // Find the selected color by looking for the palette color that contains the checkmark
  115. let selectedColor = null;
  116. templateInstance.$('.js-palette-color').each(function() {
  117. if ($(this).text().includes('✅')) {
  118. selectedColor = Blaze.getData(this).color;
  119. return false; // break out of loop
  120. }
  121. });
  122. if (selectedColor) {
  123. board.addLabel(name, selectedColor);
  124. }
  125. Popup.back();
  126. },
  127. });
  128. Template.editLabelPopup.events({
  129. 'click .js-delete-label': Popup.afterConfirm('deleteLabel', function () {
  130. const board = Utils.getCurrentBoard();
  131. board.removeLabel(this._id);
  132. Popup.back(2);
  133. }),
  134. 'submit .edit-label'(event, templateInstance) {
  135. event.preventDefault();
  136. const board = Utils.getCurrentBoard();
  137. const name = templateInstance
  138. .$('#labelName')
  139. .val()
  140. .trim();
  141. // Find the selected color by looking for the palette color that contains the checkmark
  142. let selectedColor = null;
  143. templateInstance.$('.js-palette-color').each(function() {
  144. if ($(this).text().includes('✅')) {
  145. selectedColor = Blaze.getData(this).color;
  146. return false; // break out of loop
  147. }
  148. });
  149. if (selectedColor) {
  150. board.editLabel(this._id, name, selectedColor);
  151. }
  152. Popup.back();
  153. },
  154. });
  155. Template.cardLabelsPopup.helpers({
  156. isLabelSelected(cardId) {
  157. return _.contains(ReactiveCache.getCard(cardId).labelIds, this._id);
  158. },
  159. });