cardDate.js 9.4 KB

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