cardDate.js 9.4 KB

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