Source

fields/DateTimePickerRangeFieldPresets.js

  1. import BaseField from './BaseField';
  2. import ChoicePickerField from './ChoicePickerField';
  3. import DateTimePickerRangeField from './DateTimePickerRangeField';
  4. import { __ } from '@devoinc/applications-builder/i18n';
  5. import dateRange from '@devoinc/applications-builder/utils/dateRange';
  6. /**
  7. *
  8. * @category Fields
  9. * @class
  10. * Allows to select one date range from a list of presets or to select the range.
  11. * @extends BaseField
  12. */
  13. class DateTimePickerRangeFieldPresets extends BaseField {
  14. /**
  15. * @param props.id - id of the DOM container
  16. * @param props.choices - selectable choices, a map of string : dateRange pairs
  17. * @param props.timepicker - if true the user can select hours and minutes
  18. * @param props.apply - callback that will be called whenever the state of the component is changed
  19. * @param props.dataNode - data node
  20. */
  21. constructor(props = {}) {
  22. props = Object.assign(
  23. {
  24. choices: [
  25. {
  26. id: '1h',
  27. value: () => dateRange.fromNow(1, 'hour', 'minute'),
  28. text: '1h',
  29. },
  30. {
  31. id: '1d',
  32. value: () => dateRange.fromNow(1, 'day', 'minute'),
  33. text: '1d',
  34. },
  35. {
  36. id: '7d',
  37. value: () => dateRange.fromNow(7, 'day', true),
  38. text: '7d',
  39. },
  40. {
  41. id: '30d',
  42. value: () => dateRange.fromNow(30, 'day', true),
  43. text: '30d',
  44. },
  45. ],
  46. timepicker: true,
  47. default: '1h',
  48. },
  49. props
  50. );
  51. props.choices.push({
  52. id: '_custom_',
  53. text: __('Custom'),
  54. value: () => null,
  55. });
  56. super(props);
  57. if (!this.el) return undefined;
  58. return this;
  59. }
  60. setDefault() {
  61. if (this.default !== null) {
  62. this.setValue(this.default);
  63. }
  64. }
  65. /**
  66. * Set the value to the component
  67. * @param {Object|String} value Value of the component, dates object or string
  68. */
  69. setValue(value) {
  70. if (typeof value === 'string') {
  71. if (this.choicePickerField) {
  72. this.choicePickerField.setValue(value);
  73. let val = this.choicePickerField.getValue();
  74. if (val) {
  75. this.value = val();
  76. if (this.dateTimePickerRangeField) {
  77. this.dateTimePickerRangeField.setValue(this.value);
  78. this.dateTimePickerRangeField.highlight();
  79. if (this.onChange) this.onChange(this.value);
  80. }
  81. }
  82. }
  83. } else if (typeof value === 'object') {
  84. const processDate = (date) =>
  85. typeof date === 'string' ? new Date(date).getTime() : date;
  86. value.from = processDate(value.from);
  87. value.to = processDate(value.to);
  88. this.value = value;
  89. if (this.choicePickerField) {
  90. // Update the choice picker with an option similar to the
  91. // passed date range.
  92. this.choicePickerField.setValue(this.getChoiceFromDateRange(value));
  93. if (this.dateTimePickerRangeField) {
  94. this.dateTimePickerRangeField.setValue(value);
  95. this.dateTimePickerRangeField.highlight();
  96. }
  97. if (this.onChange) this.onChange(value);
  98. }
  99. }
  100. this.previous = this.value;
  101. }
  102. getDatesValue(value) {
  103. if (typeof value === 'string') {
  104. let choice = this.choices.find((el) => el.id === value);
  105. return choice.value();
  106. } else {
  107. return value;
  108. }
  109. }
  110. /**
  111. * Updates the component view / DOM representation on state change
  112. * @override
  113. */
  114. setDOM() {}
  115. /**
  116. * Builds the DOM representation (view) on initialization
  117. */
  118. buildDOM() {
  119. this.el.classList.add('lt-date-picker-presets');
  120. let cleanId = this.getCleanId();
  121. this.el.innerHTML = '';
  122. this.el.innerHTML = `<div id="${cleanId}_lt-choice-picker"></div>
  123. <div id="${cleanId}_lt-date-range"></div>`;
  124. // Custom date range selector
  125. this.dateTimePickerRangeField = new DateTimePickerRangeField({
  126. id: `#${cleanId}_lt-date-range`,
  127. timepicker: this.timepicker,
  128. default: this.default != null ? this.getDatesValue(this.default) : null,
  129. onChange: (value) => this.setValue(value),
  130. });
  131. // Presets date ranges selector
  132. this.choicePickerField = new ChoicePickerField({
  133. id: `#${cleanId}_lt-choice-picker`,
  134. choices: this.choices,
  135. default: this.default != null ? this.default : null,
  136. onChange: (value) => this.setValue(value.id),
  137. });
  138. }
  139. /**
  140. * Finds a choice in the choice picker that is nearly similar
  141. * to the passed dateRange
  142. * @param {Object} dateRange
  143. * @returns {string|null} choice id or null
  144. */
  145. getChoiceFromDateRange(dateRange) {
  146. let diff = dateRange.to - dateRange.from;
  147. for (let choice of this.choices.slice(0, this.choices.length - 1)) {
  148. let choice_range = choice.value();
  149. let diff_choice = choice_range.to - choice_range.from;
  150. if (Math.abs(diff_choice - diff) < 120000) {
  151. return choice.id;
  152. }
  153. }
  154. return '_custom_';
  155. }
  156. /**
  157. * Updates the from and to dates to the current moment
  158. */
  159. refresh() {
  160. this.dateTimePickerRangeField.refresh();
  161. }
  162. }
  163. export default DateTimePickerRangeFieldPresets;