debian-mirror-gitlab/app/assets/javascripts/due_date_select.js

192 lines
6 KiB
JavaScript
Raw Normal View History

2020-03-13 15:44:24 +05:30
/* eslint-disable max-classes-per-file */
2021-03-11 19:13:27 +05:30
import dateFormat from 'dateformat';
2018-05-09 12:01:36 +05:30
import $ from 'jquery';
2017-09-10 17:25:29 +05:30
import Pikaday from 'pikaday';
2021-06-08 01:23:25 +05:30
import initDatePicker from '~/behaviors/date_picker';
2021-03-11 19:13:27 +05:30
import initDeprecatedJQueryDropdown from '~/deprecated_jquery_dropdown';
2018-10-15 14:42:47 +05:30
import { __ } from '~/locale';
2021-03-11 19:13:27 +05:30
import boardsStore from './boards/stores/boards_store';
2018-03-17 18:26:18 +05:30
import axios from './lib/utils/axios_utils';
2018-12-13 13:39:08 +05:30
import { timeFor, parsePikadayDate, pikadayToString } from './lib/utils/datetime_utility';
2017-08-17 22:00:37 +05:30
class DueDateSelect {
constructor({ $dropdown, $loading } = {}) {
const $dropdownParent = $dropdown.closest('.dropdown');
const $block = $dropdown.closest('.block');
this.$loading = $loading;
this.$dropdown = $dropdown;
this.$dropdownParent = $dropdownParent;
this.$datePicker = $dropdownParent.find('.js-due-date-calendar');
this.$block = $block;
2018-10-15 14:42:47 +05:30
this.$sidebarCollapsedValue = $block.find('.sidebar-collapsed-icon');
2017-08-17 22:00:37 +05:30
this.$selectbox = $dropdown.closest('.selectbox');
this.$value = $block.find('.value');
this.$valueContent = $block.find('.value-content');
this.$sidebarValue = $('.js-due-date-sidebar-value', $block);
2018-03-27 19:54:05 +05:30
this.fieldName = $dropdown.data('fieldName');
this.abilityName = $dropdown.data('abilityName');
this.issueUpdateURL = $dropdown.data('issueUpdate');
2017-08-17 22:00:37 +05:30
this.rawSelectedDate = null;
this.displayedDate = null;
this.datePayload = null;
this.initGlDropdown();
this.initRemoveDueDate();
this.initDatePicker();
}
initGlDropdown() {
2020-11-24 15:15:51 +05:30
initDeprecatedJQueryDropdown(this.$dropdown, {
2017-08-17 22:00:37 +05:30
opened: () => {
const calendar = this.$datePicker.data('pikaday');
calendar.show();
},
hidden: () => {
this.$selectbox.hide();
this.$value.css('display', '');
2018-03-17 18:26:18 +05:30
},
2020-04-08 14:13:33 +05:30
shouldPropagate: false,
2017-08-17 22:00:37 +05:30
});
}
initDatePicker() {
const $dueDateInput = $(`input[name='${this.fieldName}']`);
const calendar = new Pikaday({
field: $dueDateInput.get(0),
theme: 'gitlab-theme',
format: 'yyyy-mm-dd',
2021-03-08 18:12:59 +05:30
parse: (dateString) => parsePikadayDate(dateString),
toString: (date) => pikadayToString(date),
onSelect: (dateText) => {
2018-03-17 18:26:18 +05:30
$dueDateInput.val(calendar.toString(dateText));
2017-08-17 22:00:37 +05:30
if (this.$dropdown.hasClass('js-issue-boards-due-date')) {
2018-12-13 13:39:08 +05:30
boardsStore.detail.issue.dueDate = $dueDateInput.val();
2017-08-17 22:00:37 +05:30
this.updateIssueBoardIssue();
} else {
this.saveDueDate(true);
}
2018-03-17 18:26:18 +05:30
},
2019-03-02 22:35:43 +05:30
firstDay: gon.first_day_of_week,
2017-08-17 22:00:37 +05:30
});
2018-03-17 18:26:18 +05:30
calendar.setDate(parsePikadayDate($dueDateInput.val()));
2017-08-17 22:00:37 +05:30
this.$datePicker.append(calendar.el);
this.$datePicker.data('pikaday', calendar);
}
initRemoveDueDate() {
2021-03-08 18:12:59 +05:30
this.$block.on('click', '.js-remove-due-date', (e) => {
2017-08-17 22:00:37 +05:30
const calendar = this.$datePicker.data('pikaday');
e.preventDefault();
calendar.setDate(null);
if (this.$dropdown.hasClass('js-issue-boards-due-date')) {
2018-12-13 13:39:08 +05:30
boardsStore.detail.issue.dueDate = '';
2017-08-17 22:00:37 +05:30
this.updateIssueBoardIssue();
} else {
2018-03-17 18:26:18 +05:30
$(`input[name='${this.fieldName}']`).val('');
this.saveDueDate(false);
2017-08-17 22:00:37 +05:30
}
});
}
saveDueDate(isDropdown) {
this.parseSelectedDate();
this.prepSelectedDate();
this.submitSelectedDate(isDropdown);
}
parseSelectedDate() {
this.rawSelectedDate = $(`input[name='${this.fieldName}']`).val();
if (this.rawSelectedDate.length) {
// Construct Date object manually to avoid buggy dateString support within Date constructor
2021-03-08 18:12:59 +05:30
const dateArray = this.rawSelectedDate.split('-').map((v) => parseInt(v, 10));
2017-08-17 22:00:37 +05:30
const dateObj = new Date(dateArray[0], dateArray[1] - 1, dateArray[2]);
this.displayedDate = dateFormat(dateObj, 'mmm d, yyyy');
} else {
2019-07-31 22:56:46 +05:30
this.displayedDate = __('None');
2017-08-17 22:00:37 +05:30
}
}
prepSelectedDate() {
const datePayload = {};
datePayload[this.abilityName] = {};
datePayload[this.abilityName].due_date = this.rawSelectedDate;
this.datePayload = datePayload;
}
2018-03-17 18:26:18 +05:30
updateIssueBoardIssue() {
2021-02-22 17:27:13 +05:30
this.$loading.removeClass('gl-display-none');
2017-08-17 22:00:37 +05:30
this.$dropdown.trigger('loading.gl.dropdown');
this.$selectbox.hide();
this.$value.css('display', '');
2021-02-22 17:27:13 +05:30
const hideLoader = () => {
this.$loading.addClass('gl-display-none');
2017-08-17 22:00:37 +05:30
};
2018-12-13 13:39:08 +05:30
boardsStore.detail.issue
2018-11-08 19:23:39 +05:30
.update(this.$dropdown.attr('data-issue-update'))
2021-02-22 17:27:13 +05:30
.then(hideLoader)
.catch(hideLoader);
2017-08-17 22:00:37 +05:30
}
submitSelectedDate(isDropdown) {
2018-03-17 18:26:18 +05:30
const selectedDateValue = this.datePayload[this.abilityName].due_date;
2019-07-31 22:56:46 +05:30
const hasDueDate = this.displayedDate !== __('None');
2018-10-15 14:42:47 +05:30
const displayedDateStyle = hasDueDate ? 'bold' : 'no-value';
2017-08-17 22:00:37 +05:30
2021-02-22 17:27:13 +05:30
this.$loading.removeClass('gl-display-none');
2017-08-17 22:00:37 +05:30
2018-03-17 18:26:18 +05:30
if (isDropdown) {
this.$dropdown.trigger('loading.gl.dropdown');
this.$selectbox.hide();
}
2017-08-17 22:00:37 +05:30
2018-03-17 18:26:18 +05:30
this.$value.css('display', '');
this.$valueContent.html(`<span class='${displayedDateStyle}'>${this.displayedDate}</span>`);
this.$sidebarValue.html(this.displayedDate);
2017-08-17 22:00:37 +05:30
2018-03-17 18:26:18 +05:30
$('.js-remove-due-date-holder').toggleClass('hidden', selectedDateValue.length);
2018-11-08 19:23:39 +05:30
return axios.put(this.issueUpdateURL, this.datePayload).then(() => {
const tooltipText = hasDueDate
? `${__('Due date')}<br />${selectedDateValue} (${timeFor(selectedDateValue)})`
: __('Due date');
if (isDropdown) {
this.$dropdown.trigger('loaded.gl.dropdown');
this.$dropdown.dropdown('toggle');
}
this.$sidebarCollapsedValue.attr('data-original-title', tooltipText);
2018-10-15 14:42:47 +05:30
2021-02-22 17:27:13 +05:30
return this.$loading.addClass('gl-display-none');
2018-11-08 19:23:39 +05:30
});
2017-08-17 22:00:37 +05:30
}
}
2018-03-17 18:26:18 +05:30
export default class DueDateSelectors {
2017-08-17 22:00:37 +05:30
constructor() {
2021-06-08 01:23:25 +05:30
initDatePicker();
2017-08-17 22:00:37 +05:30
this.initIssuableSelect();
}
2018-03-17 18:26:18 +05:30
// eslint-disable-next-line class-methods-use-this
2017-08-17 22:00:37 +05:30
initIssuableSelect() {
2018-11-08 19:23:39 +05:30
const $loading = $('.js-issuable-update .due_date')
.find('.block-loading')
2021-02-22 17:27:13 +05:30
.removeClass('hidden')
.addClass('gl-display-none');
2017-08-17 22:00:37 +05:30
$('.js-due-date-select').each((i, dropdown) => {
const $dropdown = $(dropdown);
2018-03-17 18:26:18 +05:30
// eslint-disable-next-line no-new
2017-08-17 22:00:37 +05:30
new DueDateSelect({
$dropdown,
2018-03-17 18:26:18 +05:30
$loading,
2017-08-17 22:00:37 +05:30
});
});
}
}