Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-06-03 12:08:47 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-06-03 12:08:47 +0300
commit31a432e38a8b70d3ffb16afa8d7cfeee4f5f5921 (patch)
treeb59f8b4e2ef7486f13adb01328a749f19b93a023 /app/assets/javascripts/vue_shared/components/date_time_picker
parent6b7b853dff4cb7e72d76bd501d75708111c95585 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/vue_shared/components/date_time_picker')
-rw-r--r--app/assets/javascripts/vue_shared/components/date_time_picker/date_time_picker.vue106
-rw-r--r--app/assets/javascripts/vue_shared/components/date_time_picker/date_time_picker_input.vue4
-rw-r--r--app/assets/javascripts/vue_shared/components/date_time_picker/date_time_picker_lib.js65
3 files changed, 117 insertions, 58 deletions
diff --git a/app/assets/javascripts/vue_shared/components/date_time_picker/date_time_picker.vue b/app/assets/javascripts/vue_shared/components/date_time_picker/date_time_picker.vue
index 07748482204..ddbb474bab6 100644
--- a/app/assets/javascripts/vue_shared/components/date_time_picker/date_time_picker.vue
+++ b/app/assets/javascripts/vue_shared/components/date_time_picker/date_time_picker.vue
@@ -1,20 +1,17 @@
<script>
-import { GlDeprecatedButton, GlDropdown, GlDropdownItem, GlFormGroup } from '@gitlab/ui';
+import { GlIcon, GlDeprecatedButton, GlDropdown, GlDropdownItem, GlFormGroup } from '@gitlab/ui';
import { __, sprintf } from '~/locale';
import { convertToFixedRange, isEqualTimeRanges, findTimeRange } from '~/lib/utils/datetime_range';
-import Icon from '~/vue_shared/components/icon.vue';
import TooltipOnTruncate from '~/vue_shared/components/tooltip_on_truncate.vue';
import DateTimePickerInput from './date_time_picker_input.vue';
import {
defaultTimeRanges,
defaultTimeRange,
- isValidDate,
- stringToISODate,
- ISODateToString,
- truncateZerosInDateTime,
- isDateTimePickerInputValid,
+ isValidInputString,
+ inputStringToIsoDate,
+ isoDateToInputString,
} from './date_time_picker_lib';
const events = {
@@ -24,13 +21,13 @@ const events = {
export default {
components: {
- Icon,
- TooltipOnTruncate,
- DateTimePickerInput,
- GlFormGroup,
+ GlIcon,
GlDeprecatedButton,
GlDropdown,
GlDropdownItem,
+ GlFormGroup,
+ TooltipOnTruncate,
+ DateTimePickerInput,
},
props: {
value: {
@@ -48,20 +45,41 @@ export default {
required: false,
default: true,
},
+ utc: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
},
data() {
return {
timeRange: this.value,
- startDate: '',
- endDate: '',
+
+ /**
+ * Valid start iso date string, null if not valid value
+ */
+ startDate: null,
+ /**
+ * Invalid start date string as input by the user
+ */
+ startFallbackVal: '',
+
+ /**
+ * Valid end iso date string, null if not valid value
+ */
+ endDate: null,
+ /**
+ * Invalid end date string as input by the user
+ */
+ endFallbackVal: '',
};
},
computed: {
startInputValid() {
- return isValidDate(this.startDate);
+ return isValidInputString(this.startDate);
},
endInputValid() {
- return isValidDate(this.endDate);
+ return isValidInputString(this.endDate);
},
isValid() {
return this.startInputValid && this.endInputValid;
@@ -69,21 +87,31 @@ export default {
startInput: {
get() {
- return this.startInputValid ? this.formatDate(this.startDate) : this.startDate;
+ return this.dateToInput(this.startDate) || this.startFallbackVal;
},
set(val) {
- // Attempt to set a formatted date if possible
- this.startDate = isDateTimePickerInputValid(val) ? stringToISODate(val) : val;
+ try {
+ this.startDate = this.inputToDate(val);
+ this.startFallbackVal = null;
+ } catch (e) {
+ this.startDate = null;
+ this.startFallbackVal = val;
+ }
this.timeRange = null;
},
},
endInput: {
get() {
- return this.endInputValid ? this.formatDate(this.endDate) : this.endDate;
+ return this.dateToInput(this.endDate) || this.endFallbackVal;
},
set(val) {
- // Attempt to set a formatted date if possible
- this.endDate = isDateTimePickerInputValid(val) ? stringToISODate(val) : val;
+ try {
+ this.endDate = this.inputToDate(val);
+ this.endFallbackVal = null;
+ } catch (e) {
+ this.endDate = null;
+ this.endFallbackVal = val;
+ }
this.timeRange = null;
},
},
@@ -96,10 +124,10 @@ export default {
}
const { start, end } = convertToFixedRange(this.value);
- if (isValidDate(start) && isValidDate(end)) {
+ if (isValidInputString(start) && isValidInputString(end)) {
return sprintf(__('%{start} to %{end}'), {
- start: this.formatDate(start),
- end: this.formatDate(end),
+ start: this.stripZerosInDateTime(this.dateToInput(start)),
+ end: this.stripZerosInDateTime(this.dateToInput(end)),
});
}
} catch {
@@ -107,6 +135,13 @@ export default {
}
return '';
},
+
+ customLabel() {
+ if (this.utc) {
+ return __('Custom range (UTC)');
+ }
+ return __('Custom range');
+ },
},
watch: {
value(newValue) {
@@ -132,8 +167,17 @@ export default {
}
},
methods: {
- formatDate(date) {
- return truncateZerosInDateTime(ISODateToString(date));
+ dateToInput(date) {
+ if (date === null) {
+ return null;
+ }
+ return isoDateToInputString(date, this.utc);
+ },
+ inputToDate(value) {
+ return inputStringToIsoDate(value, this.utc);
+ },
+ stripZerosInDateTime(str = '') {
+ return str.replace(' 00:00:00', '');
},
closeDropdown() {
this.$refs.dropdown.hide();
@@ -169,10 +213,16 @@ export default {
menu-class="date-time-picker-menu"
toggle-class="date-time-picker-toggle text-truncate"
>
+ <template #button-content>
+ <span class="gl-flex-grow-1 text-truncate">{{ timeWindowText }}</span>
+ <span v-if="utc" class="text-muted gl-font-weight-bold gl-font-sm">{{ __('UTC') }}</span>
+ <gl-icon class="gl-dropdown-caret" name="chevron-down" aria-hidden="true" />
+ </template>
+
<div class="d-flex justify-content-between gl-p-2-deprecated-no-really-do-not-use-me">
<gl-form-group
v-if="customEnabled"
- :label="__('Custom range')"
+ :label="customLabel"
label-for="custom-from-time"
label-class="gl-pb-1-deprecated-no-really-do-not-use-me"
class="custom-time-range-form-group col-md-7 gl-pl-1-deprecated-no-really-do-not-use-me gl-pr-0 m-0"
@@ -214,7 +264,7 @@ export default {
active-class="active"
@click="setQuickRange(option)"
>
- <icon
+ <gl-icon
name="mobile-issue-close"
class="align-bottom"
:class="{ invisible: !isOptionActive(option) }"
diff --git a/app/assets/javascripts/vue_shared/components/date_time_picker/date_time_picker_input.vue b/app/assets/javascripts/vue_shared/components/date_time_picker/date_time_picker_input.vue
index f19f8bd46b3..32a24844d71 100644
--- a/app/assets/javascripts/vue_shared/components/date_time_picker/date_time_picker_input.vue
+++ b/app/assets/javascripts/vue_shared/components/date_time_picker/date_time_picker_input.vue
@@ -6,9 +6,9 @@ import { dateFormats } from './date_time_picker_lib';
const inputGroupText = {
invalidFeedback: sprintf(__('Format: %{dateFormat}'), {
- dateFormat: dateFormats.stringDate,
+ dateFormat: dateFormats.inputFormat,
}),
- placeholder: dateFormats.stringDate,
+ placeholder: dateFormats.inputFormat,
};
export default {
diff --git a/app/assets/javascripts/vue_shared/components/date_time_picker/date_time_picker_lib.js b/app/assets/javascripts/vue_shared/components/date_time_picker/date_time_picker_lib.js
index 673d981cf07..40708453d79 100644
--- a/app/assets/javascripts/vue_shared/components/date_time_picker/date_time_picker_lib.js
+++ b/app/assets/javascripts/vue_shared/components/date_time_picker/date_time_picker_lib.js
@@ -2,12 +2,6 @@ import dateformat from 'dateformat';
import { __ } from '~/locale';
/**
- * Valid strings for this regex are
- * 2019-10-01 and 2019-10-01 01:02:03
- */
-const dateTimePickerRegex = /^(\d{4})-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])(?: (0[0-9]|1[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9]))?$/;
-
-/**
* Default time ranges for the date picker.
* @see app/assets/javascripts/lib/utils/datetime_range.js
*/
@@ -34,23 +28,33 @@ export const defaultTimeRanges = [
export const defaultTimeRange = defaultTimeRanges.find(tr => tr.default);
export const dateFormats = {
- ISODate: "yyyy-mm-dd'T'HH:MM:ss'Z'",
- stringDate: 'yyyy-mm-dd HH:MM:ss',
+ /**
+ * Format used by users to input dates
+ *
+ * Note: Should be a format that can be parsed by Date.parse.
+ */
+ inputFormat: 'yyyy-mm-dd HH:MM:ss',
+ /**
+ * Format used to strip timezone from inputs
+ */
+ stripTimezoneFormat: "yyyy-mm-dd'T'HH:MM:ss'Z'",
};
/**
- * The URL params start and end need to be validated
- * before passing them down to other components.
+ * Returns true if the date can be parsed succesfully after
+ * being typed by a user.
*
- * @param {string} dateString
- * @returns true if the string is a valid date, false otherwise
+ * It allows some ambiguity so validation is not strict.
+ *
+ * @param {string} value - Value as typed by the user
+ * @returns true if the value can be parsed as a valid date, false otherwise
*/
-export const isValidDate = dateString => {
+export const isValidInputString = value => {
try {
// dateformat throws error that can be caught.
// This is better than using `new Date()`
- if (dateString && dateString.trim()) {
- dateformat(dateString, 'isoDateTime');
+ if (value && value.trim()) {
+ dateformat(value, 'isoDateTime');
return true;
}
return false;
@@ -60,25 +64,30 @@ export const isValidDate = dateString => {
};
/**
- * Convert the input in Time picker component to ISO date.
+ * Convert the input in time picker component to an ISO date.
*
- * @param {string} val
- * @returns {string}
+ * @param {string} value
+ * @param {Boolean} utc - If true, it forces the date to by
+ * formatted using UTC format, ignoring the local time.
+ * @returns {Date}
*/
-export const stringToISODate = val =>
- dateformat(new Date(val.replace(/-/g, '/')), dateFormats.ISODate, true);
+export const inputStringToIsoDate = (value, utc = false) => {
+ let date = new Date(value);
+ if (utc) {
+ // Forces date to be interpreted as UTC by stripping the timezone
+ // by formatting to a string with 'Z' and skipping timezone
+ date = dateformat(date, dateFormats.stripTimezoneFormat);
+ }
+ return dateformat(date, 'isoUtcDateTime');
+};
/**
- * Convert the ISO date received from the URL to string
- * for the Time picker component.
+ * Converts a iso date string to a formatted string for the Time picker component.
*
- * @param {Date} date
+ * @param {String} ISO Formatted date
* @returns {string}
*/
-export const ISODateToString = date => dateformat(date, dateFormats.stringDate);
-
-export const truncateZerosInDateTime = datetime => datetime.replace(' 00:00:00', '');
-
-export const isDateTimePickerInputValid = val => dateTimePickerRegex.test(val);
+export const isoDateToInputString = (date, utc = false) =>
+ dateformat(date, dateFormats.inputFormat, utc);
export default {};