2
0

cardDate.js 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  1. import moment from 'moment';
  2. import { DatePicker } from '/client/lib/datepicker';
  3. Template.dateBadge.helpers({
  4. canModifyCard() {
  5. return (
  6. Meteor.user() &&
  7. Meteor.user().isBoardMember() &&
  8. !Meteor.user().isCommentOnly() &&
  9. !Meteor.user().isWorker()
  10. );
  11. },
  12. });
  13. // editCardReceivedDatePopup
  14. (class extends DatePicker {
  15. onCreated() {
  16. super.onCreated(moment().format('YYYY-MM-DD HH:mm'));
  17. this.data().getReceived() &&
  18. this.date.set(moment(this.data().getReceived()));
  19. }
  20. _storeDate(date) {
  21. this.card.setReceived(date);
  22. }
  23. _deleteDate() {
  24. this.card.setReceived(null);
  25. }
  26. }.register('editCardReceivedDatePopup'));
  27. // editCardStartDatePopup
  28. (class extends DatePicker {
  29. onCreated() {
  30. super.onCreated(moment().format('YYYY-MM-DD HH:mm'));
  31. this.data().getStart() && this.date.set(moment(this.data().getStart()));
  32. }
  33. onRendered() {
  34. super.onRendered();
  35. if (moment.isDate(this.card.getReceived())) {
  36. this.$('.js-datepicker').datepicker(
  37. 'setStartDate',
  38. this.card.getReceived(),
  39. );
  40. }
  41. }
  42. _storeDate(date) {
  43. this.card.setStart(date);
  44. }
  45. _deleteDate() {
  46. this.card.setStart(null);
  47. }
  48. }.register('editCardStartDatePopup'));
  49. // editCardDueDatePopup
  50. (class extends DatePicker {
  51. onCreated() {
  52. super.onCreated('1970-01-01 17:00:00');
  53. this.data().getDue() && this.date.set(moment(this.data().getDue()));
  54. }
  55. onRendered() {
  56. super.onRendered();
  57. if (moment.isDate(this.card.getStart())) {
  58. this.$('.js-datepicker').datepicker('setStartDate', this.card.getStart());
  59. }
  60. }
  61. _storeDate(date) {
  62. this.card.setDue(date);
  63. }
  64. _deleteDate() {
  65. this.card.setDue(null);
  66. }
  67. }.register('editCardDueDatePopup'));
  68. // editCardEndDatePopup
  69. (class extends DatePicker {
  70. onCreated() {
  71. super.onCreated(moment().format('YYYY-MM-DD HH:mm'));
  72. this.data().getEnd() && this.date.set(moment(this.data().getEnd()));
  73. }
  74. onRendered() {
  75. super.onRendered();
  76. if (moment.isDate(this.card.getStart())) {
  77. this.$('.js-datepicker').datepicker('setStartDate', this.card.getStart());
  78. }
  79. }
  80. _storeDate(date) {
  81. this.card.setEnd(date);
  82. }
  83. _deleteDate() {
  84. this.card.setEnd(null);
  85. }
  86. }.register('editCardEndDatePopup'));
  87. // Display received, start, due & end dates
  88. const CardDate = BlazeComponent.extendComponent({
  89. template() {
  90. return 'dateBadge';
  91. },
  92. onCreated() {
  93. const self = this;
  94. self.date = ReactiveVar();
  95. self.now = ReactiveVar(moment());
  96. window.setInterval(() => {
  97. self.now.set(moment());
  98. }, 60000);
  99. },
  100. showDate() {
  101. // this will start working once mquandalle:moment
  102. // is updated to at least moment.js 2.10.5
  103. // until then, the date is displayed in the "L" format
  104. return this.date.get().calendar(null, {
  105. sameElse: 'llll',
  106. });
  107. },
  108. showISODate() {
  109. return this.date.get().toISOString();
  110. },
  111. });
  112. class CardReceivedDate extends CardDate {
  113. onCreated() {
  114. super.onCreated();
  115. const self = this;
  116. self.autorun(() => {
  117. self.date.set(moment(self.data().getReceived()));
  118. });
  119. }
  120. classes() {
  121. let classes = 'received-date ';
  122. const dueAt = this.data().getDue();
  123. const endAt = this.data().getEnd();
  124. const startAt = this.data().getStart();
  125. const theDate = this.date.get();
  126. // if dueAt, endAt and startAt exist & are > receivedAt, receivedAt doesn't need to be flagged
  127. if (
  128. (startAt && theDate.isAfter(startAt)) ||
  129. (endAt && theDate.isAfter(endAt)) ||
  130. (dueAt && theDate.isAfter(dueAt))
  131. )
  132. classes += 'long-overdue';
  133. else classes += 'current';
  134. return classes;
  135. }
  136. showTitle() {
  137. return `${TAPi18n.__('card-received-on')} ${this.date
  138. .get()
  139. .format('LLLL')}`;
  140. }
  141. events() {
  142. return super.events().concat({
  143. 'click .js-edit-date': Popup.open('editCardReceivedDate'),
  144. });
  145. }
  146. }
  147. CardReceivedDate.register('cardReceivedDate');
  148. class CardStartDate extends CardDate {
  149. onCreated() {
  150. super.onCreated();
  151. const self = this;
  152. self.autorun(() => {
  153. self.date.set(moment(self.data().getStart()));
  154. });
  155. }
  156. classes() {
  157. let classes = 'start-date' + ' ';
  158. const dueAt = this.data().getDue();
  159. const endAt = this.data().getEnd();
  160. const theDate = this.date.get();
  161. const now = this.now.get();
  162. // if dueAt or endAt exist & are > startAt, startAt doesn't need to be flagged
  163. if ((endAt && theDate.isAfter(endAt)) || (dueAt && theDate.isAfter(dueAt)))
  164. classes += 'long-overdue';
  165. else if (theDate.isBefore(now, 'minute')) classes += 'almost-due';
  166. else classes += 'current';
  167. return classes;
  168. }
  169. showTitle() {
  170. return `${TAPi18n.__('card-start-on')} ${this.date.get().format('LLLL')}`;
  171. }
  172. events() {
  173. return super.events().concat({
  174. 'click .js-edit-date': Popup.open('editCardStartDate'),
  175. });
  176. }
  177. }
  178. CardStartDate.register('cardStartDate');
  179. class CardDueDate extends CardDate {
  180. onCreated() {
  181. super.onCreated();
  182. const self = this;
  183. self.autorun(() => {
  184. self.date.set(moment(self.data().getDue()));
  185. });
  186. }
  187. classes() {
  188. let classes = 'due-date' + ' ';
  189. const endAt = this.data().getEnd();
  190. const theDate = this.date.get();
  191. const now = this.now.get();
  192. // if the due date is after the end date, green - done early
  193. if (endAt && theDate.isAfter(endAt)) classes += 'current';
  194. // if there is an end date, don't need to flag the due date
  195. else if (endAt) classes += '';
  196. else if (now.diff(theDate, 'days') >= 2) classes += 'long-overdue';
  197. else if (now.diff(theDate, 'minute') >= 0) classes += 'due';
  198. else if (now.diff(theDate, 'days') >= -1) classes += 'almost-due';
  199. return classes;
  200. }
  201. showTitle() {
  202. return `${TAPi18n.__('card-due-on')} ${this.date.get().format('LLLL')}`;
  203. }
  204. events() {
  205. return super.events().concat({
  206. 'click .js-edit-date': Popup.open('editCardDueDate'),
  207. });
  208. }
  209. }
  210. CardDueDate.register('cardDueDate');
  211. class CardEndDate extends CardDate {
  212. onCreated() {
  213. super.onCreated();
  214. const self = this;
  215. self.autorun(() => {
  216. self.date.set(moment(self.data().getEnd()));
  217. });
  218. }
  219. classes() {
  220. let classes = 'end-date' + ' ';
  221. const dueAt = this.data().getDue();
  222. const theDate = this.date.get();
  223. if (!dueAt) classes += '';
  224. else if (theDate.isBefore(dueAt)) classes += 'current';
  225. else if (theDate.isAfter(dueAt)) classes += 'due';
  226. return classes;
  227. }
  228. showTitle() {
  229. return `${TAPi18n.__('card-end-on')} ${this.date.get().format('LLLL')}`;
  230. }
  231. events() {
  232. return super.events().concat({
  233. 'click .js-edit-date': Popup.open('editCardEndDate'),
  234. });
  235. }
  236. }
  237. CardEndDate.register('cardEndDate');
  238. class CardCustomFieldDate extends CardDate {
  239. template() {
  240. return 'dateCustomField';
  241. }
  242. onCreated() {
  243. super.onCreated();
  244. const self = this;
  245. self.autorun(() => {
  246. self.date.set(moment(self.data().value));
  247. });
  248. }
  249. classes() {
  250. return 'customfield-date';
  251. }
  252. showTitle() {
  253. return '';
  254. }
  255. events() {
  256. return [];
  257. }
  258. }
  259. CardCustomFieldDate.register('cardCustomFieldDate');
  260. (class extends CardReceivedDate {
  261. showDate() {
  262. return this.date.get().format('l');
  263. }
  264. }.register('minicardReceivedDate'));
  265. (class extends CardStartDate {
  266. showDate() {
  267. return this.date.get().format('l');
  268. }
  269. }.register('minicardStartDate'));
  270. (class extends CardDueDate {
  271. showDate() {
  272. return this.date.get().format('l');
  273. }
  274. }.register('minicardDueDate'));
  275. (class extends CardEndDate {
  276. showDate() {
  277. return this.date.get().format('l');
  278. }
  279. }.register('minicardEndDate'));
  280. (class extends CardCustomFieldDate {
  281. showDate() {
  282. return this.date.get().format('l');
  283. }
  284. }.register('minicardCustomFieldDate'));
  285. class VoteEndDate extends CardDate {
  286. onCreated() {
  287. super.onCreated();
  288. const self = this;
  289. self.autorun(() => {
  290. self.date.set(moment(self.data().getVoteEnd()));
  291. });
  292. }
  293. classes() {
  294. const classes = 'end-date' + ' ';
  295. return classes;
  296. }
  297. showDate() {
  298. return this.date.get().format('l LT');
  299. }
  300. showTitle() {
  301. return `${TAPi18n.__('card-end-on')} ${this.date.get().format('LLLL')}`;
  302. }
  303. events() {
  304. return super.events().concat({
  305. 'click .js-edit-date': Popup.open('editVoteEndDate'),
  306. });
  307. }
  308. }
  309. VoteEndDate.register('voteEndDate');