Commit 112f4453 authored by Filipa Lacerda's avatar Filipa Lacerda Committed by Phil Hughes

Port of 38986-due-date to EE

parent 0cd6e5ad
...@@ -9,6 +9,7 @@ import Flash from '../../flash'; ...@@ -9,6 +9,7 @@ import Flash from '../../flash';
import eventHub from '../../sidebar/event_hub'; import eventHub from '../../sidebar/event_hub';
import AssigneeTitle from '../../sidebar/components/assignees/assignee_title'; import AssigneeTitle from '../../sidebar/components/assignees/assignee_title';
import Assignees from '../../sidebar/components/assignees/assignees'; import Assignees from '../../sidebar/components/assignees/assignees';
import DueDateSelectors from '../../due_date_select';
import './sidebar/remove_issue'; import './sidebar/remove_issue';
const Store = gl.issueBoards.BoardsStore; const Store = gl.issueBoards.BoardsStore;
...@@ -113,7 +114,7 @@ gl.issueBoards.BoardSidebar = Vue.extend({ ...@@ -113,7 +114,7 @@ gl.issueBoards.BoardSidebar = Vue.extend({
mounted () { mounted () {
new IssuableContext(this.currentUser); new IssuableContext(this.currentUser);
new MilestoneSelect(); new MilestoneSelect();
new gl.DueDateSelectors(); new DueDateSelectors();
new LabelsSelect(); new LabelsSelect();
new Sidebar(); new Sidebar();
gl.Subscription.bindAll('.subscription'); gl.Subscription.bindAll('.subscription');
......
...@@ -88,6 +88,7 @@ import ShortcutsIssuable from './shortcuts_issuable'; ...@@ -88,6 +88,7 @@ import ShortcutsIssuable from './shortcuts_issuable';
import U2FAuthenticate from './u2f/authenticate'; import U2FAuthenticate from './u2f/authenticate';
import Members from './members'; import Members from './members';
import memberExpirationDate from './member_expiration_date'; import memberExpirationDate from './member_expiration_date';
import DueDateSelectors from './due_date_select';
// EE-only // EE-only
import ApproversSelect from './approvers_select'; import ApproversSelect from './approvers_select';
...@@ -256,7 +257,7 @@ import initGroupAnalytics from './init_group_analytics'; ...@@ -256,7 +257,7 @@ import initGroupAnalytics from './init_group_analytics';
case 'groups:milestones:edit': case 'groups:milestones:edit':
case 'groups:milestones:update': case 'groups:milestones:update':
new ZenMode(); new ZenMode();
new gl.DueDateSelectors(); new DueDateSelectors();
new GLForm($('.milestone-form'), true); new GLForm($('.milestone-form'), true);
break; break;
case 'projects:compare:show': case 'projects:compare:show':
...@@ -584,7 +585,7 @@ import initGroupAnalytics from './init_group_analytics'; ...@@ -584,7 +585,7 @@ import initGroupAnalytics from './init_group_analytics';
break; break;
case 'profiles:personal_access_tokens:index': case 'profiles:personal_access_tokens:index':
case 'admin:impersonation_tokens:index': case 'admin:impersonation_tokens:index':
new gl.DueDateSelectors(); new DueDateSelectors();
break; break;
case 'projects:clusters:show': case 'projects:clusters:show':
import(/* webpackChunkName: "clusters" */ './clusters') import(/* webpackChunkName: "clusters" */ './clusters')
......
/* eslint-disable wrap-iife, func-names, space-before-function-paren, comma-dangle, prefer-template, consistent-return, class-methods-use-this, arrow-body-style, no-unused-vars, no-underscore-dangle, no-new, max-len, no-sequences, no-unused-expressions, no-param-reassign */
/* global dateFormat */ /* global dateFormat */
import Pikaday from 'pikaday'; import Pikaday from 'pikaday';
import DateFix from './lib/utils/datefix'; import { parsePikadayDate, pikadayToString } from './lib/utils/datefix';
class DueDateSelect { class DueDateSelect {
constructor({ $dropdown, $loading } = {}) { constructor({ $dropdown, $loading } = {}) {
...@@ -17,8 +16,8 @@ class DueDateSelect { ...@@ -17,8 +16,8 @@ class DueDateSelect {
this.$value = $block.find('.value'); this.$value = $block.find('.value');
this.$valueContent = $block.find('.value-content'); this.$valueContent = $block.find('.value-content');
this.$sidebarValue = $('.js-due-date-sidebar-value', $block); this.$sidebarValue = $('.js-due-date-sidebar-value', $block);
this.fieldName = $dropdown.data('field-name'), this.fieldName = $dropdown.data('field-name');
this.abilityName = $dropdown.data('ability-name'), this.abilityName = $dropdown.data('ability-name');
this.issueUpdateURL = $dropdown.data('issue-update'); this.issueUpdateURL = $dropdown.data('issue-update');
this.rawSelectedDate = null; this.rawSelectedDate = null;
...@@ -39,20 +38,20 @@ class DueDateSelect { ...@@ -39,20 +38,20 @@ class DueDateSelect {
hidden: () => { hidden: () => {
this.$selectbox.hide(); this.$selectbox.hide();
this.$value.css('display', ''); this.$value.css('display', '');
} },
}); });
} }
initDatePicker() { initDatePicker() {
const $dueDateInput = $(`input[name='${this.fieldName}']`); const $dueDateInput = $(`input[name='${this.fieldName}']`);
const dateFix = DateFix.dashedFix($dueDateInput.val());
const calendar = new Pikaday({ const calendar = new Pikaday({
field: $dueDateInput.get(0), field: $dueDateInput.get(0),
theme: 'gitlab-theme', theme: 'gitlab-theme',
format: 'yyyy-mm-dd', format: 'yyyy-mm-dd',
parse: dateString => parsePikadayDate(dateString),
toString: date => pikadayToString(date),
onSelect: (dateText) => { onSelect: (dateText) => {
const formattedDate = dateFormat(new Date(dateText), 'yyyy-mm-dd'); $dueDateInput.val(calendar.toString(dateText));
$dueDateInput.val(formattedDate);
if (this.$dropdown.hasClass('js-issue-boards-due-date')) { if (this.$dropdown.hasClass('js-issue-boards-due-date')) {
gl.issueBoards.BoardsStore.detail.issue.dueDate = $dueDateInput.val(); gl.issueBoards.BoardsStore.detail.issue.dueDate = $dueDateInput.val();
...@@ -60,10 +59,10 @@ class DueDateSelect { ...@@ -60,10 +59,10 @@ class DueDateSelect {
} else { } else {
this.saveDueDate(true); this.saveDueDate(true);
} }
} },
}); });
calendar.setDate(dateFix); calendar.setDate(parsePikadayDate($dueDateInput.val()));
this.$datePicker.append(calendar.el); this.$datePicker.append(calendar.el);
this.$datePicker.data('pikaday', calendar); this.$datePicker.data('pikaday', calendar);
} }
...@@ -79,8 +78,8 @@ class DueDateSelect { ...@@ -79,8 +78,8 @@ class DueDateSelect {
gl.issueBoards.BoardsStore.detail.issue.dueDate = ''; gl.issueBoards.BoardsStore.detail.issue.dueDate = '';
this.updateIssueBoardIssue(); this.updateIssueBoardIssue();
} else { } else {
$("input[name='" + this.fieldName + "']").val(''); $(`input[name='${this.fieldName}']`).val('');
return this.saveDueDate(false); this.saveDueDate(false);
} }
}); });
} }
...@@ -111,7 +110,7 @@ class DueDateSelect { ...@@ -111,7 +110,7 @@ class DueDateSelect {
this.datePayload = datePayload; this.datePayload = datePayload;
} }
updateIssueBoardIssue () { updateIssueBoardIssue() {
this.$loading.fadeIn(); this.$loading.fadeIn();
this.$dropdown.trigger('loading.gl.dropdown'); this.$dropdown.trigger('loading.gl.dropdown');
this.$selectbox.hide(); this.$selectbox.hide();
...@@ -149,8 +148,8 @@ class DueDateSelect { ...@@ -149,8 +148,8 @@ class DueDateSelect {
return selectedDateValue.length ? return selectedDateValue.length ?
$('.js-remove-due-date-holder').removeClass('hidden') : $('.js-remove-due-date-holder').removeClass('hidden') :
$('.js-remove-due-date-holder').addClass('hidden'); $('.js-remove-due-date-holder').addClass('hidden');
} },
}).done((data) => { }).done(() => {
if (isDropdown) { if (isDropdown) {
this.$dropdown.trigger('loaded.gl.dropdown'); this.$dropdown.trigger('loaded.gl.dropdown');
this.$dropdown.dropdown('toggle'); this.$dropdown.dropdown('toggle');
...@@ -160,27 +159,28 @@ class DueDateSelect { ...@@ -160,27 +159,28 @@ class DueDateSelect {
} }
} }
class DueDateSelectors { export default class DueDateSelectors {
constructor() { constructor() {
this.initMilestoneDatePicker(); this.initMilestoneDatePicker();
this.initIssuableSelect(); this.initIssuableSelect();
} }
// eslint-disable-next-line class-methods-use-this
initMilestoneDatePicker() { initMilestoneDatePicker() {
$('.datepicker').each(function() { $('.datepicker').each(function initPikadayMilestone() {
const $datePicker = $(this); const $datePicker = $(this);
const dateFix = DateFix.dashedFix($datePicker.val());
const calendar = new Pikaday({ const calendar = new Pikaday({
field: $datePicker.get(0), field: $datePicker.get(0),
theme: 'gitlab-theme animate-picker', theme: 'gitlab-theme animate-picker',
format: 'yyyy-mm-dd', format: 'yyyy-mm-dd',
container: $datePicker.parent().get(0), container: $datePicker.parent().get(0),
parse: dateString => parsePikadayDate(dateString),
toString: date => pikadayToString(date),
onSelect(dateText) { onSelect(dateText) {
$datePicker.val(dateFormat(new Date(dateText), 'yyyy-mm-dd')); $datePicker.val(calendar.toString(dateText));
} },
}); });
calendar.setDate(dateFix); calendar.setDate(parsePikadayDate($datePicker.val()));
$datePicker.data('pikaday', calendar); $datePicker.data('pikaday', calendar);
}); });
...@@ -191,19 +191,17 @@ class DueDateSelectors { ...@@ -191,19 +191,17 @@ class DueDateSelectors {
calendar.setDate(null); calendar.setDate(null);
}); });
} }
// eslint-disable-next-line class-methods-use-this
initIssuableSelect() { initIssuableSelect() {
const $loading = $('.js-issuable-update .due_date').find('.block-loading').hide(); const $loading = $('.js-issuable-update .due_date').find('.block-loading').hide();
$('.js-due-date-select').each((i, dropdown) => { $('.js-due-date-select').each((i, dropdown) => {
const $dropdown = $(dropdown); const $dropdown = $(dropdown);
// eslint-disable-next-line no-new
new DueDateSelect({ new DueDateSelect({
$dropdown, $dropdown,
$loading $loading,
}); });
}); });
} }
} }
window.gl = window.gl || {};
window.gl.DueDateSelectors = DueDateSelectors;
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
/* global IssuableContext */ /* global IssuableContext */
/* global Sidebar */ /* global Sidebar */
import DueDateSelectors from './due_date_select';
export default () => { export default () => {
const sidebarOptions = JSON.parse(document.querySelector('.js-sidebar-options').innerHTML); const sidebarOptions = JSON.parse(document.querySelector('.js-sidebar-options').innerHTML);
...@@ -15,6 +17,6 @@ export default () => { ...@@ -15,6 +17,6 @@ export default () => {
new WeightSelect(); new WeightSelect();
new IssuableContext(sidebarOptions.currentUser); new IssuableContext(sidebarOptions.currentUser);
gl.Subscription.bindAll('.subscription'); gl.Subscription.bindAll('.subscription');
new gl.DueDateSelectors(); new DueDateSelectors();
window.sidebar = new Sidebar(); window.sidebar = new Sidebar();
}; };
...@@ -2,12 +2,12 @@ ...@@ -2,12 +2,12 @@
/* global GitLab */ /* global GitLab */
/* global Autosave */ /* global Autosave */
/* global GroupsSelect */ /* global GroupsSelect */
/* global dateFormat */
import Pikaday from 'pikaday'; import Pikaday from 'pikaday';
import UsersSelect from './users_select'; import UsersSelect from './users_select';
import GfmAutoComplete from './gfm_auto_complete'; import GfmAutoComplete from './gfm_auto_complete';
import ZenMode from './zen_mode'; import ZenMode from './zen_mode';
import { parsePikadayDate, pikadayToString } from './lib/utils/datefix';
(function() { (function() {
this.IssuableForm = (function() { this.IssuableForm = (function() {
...@@ -40,11 +40,13 @@ import ZenMode from './zen_mode'; ...@@ -40,11 +40,13 @@ import ZenMode from './zen_mode';
theme: 'gitlab-theme animate-picker', theme: 'gitlab-theme animate-picker',
format: 'yyyy-mm-dd', format: 'yyyy-mm-dd',
container: $issuableDueDate.parent().get(0), container: $issuableDueDate.parent().get(0),
parse: dateString => parsePikadayDate(dateString),
toString: date => pikadayToString(date),
onSelect: function(dateText) { onSelect: function(dateText) {
$issuableDueDate.val(dateFormat(new Date(dateText), 'yyyy-mm-dd')); $issuableDueDate.val(calendar.toString(dateText));
} }
}); });
calendar.setDate(new Date($issuableDueDate.val())); calendar.setDate(parsePikadayDate($issuableDueDate.val()));
} }
} }
......
const DateFix = {
dashedFix(val) { export const pad = (val, len = 2) => (`0${val}`).slice(-len);
const [y, m, d] = val.split('-');
return new Date(y, m - 1, d); /**
}, * Formats dates in Pickaday
* @param {String} dateString Date in yyyy-mm-dd format
* @return {Date} UTC format
*/
export const parsePikadayDate = (dateString) => {
const parts = dateString.split('-');
const year = parseInt(parts[0], 10);
const month = parseInt(parts[1] - 1, 10);
const day = parseInt(parts[2], 10);
return new Date(year, month, day);
}; };
export default DateFix; /**
* Used `onSelect` method in pickaday
* @param {Date} date UTC format
* @return {String} Date formated in yyyy-mm-dd
*/
export const pikadayToString = (date) => {
const day = pad(date.getDate());
const month = pad(date.getMonth() + 1);
const year = date.getFullYear();
return `${year}-${month}-${day}`;
};
...@@ -51,8 +51,6 @@ import './confirm_danger_modal'; ...@@ -51,8 +51,6 @@ import './confirm_danger_modal';
import './copy_as_gfm'; import './copy_as_gfm';
import './copy_to_clipboard'; import './copy_to_clipboard';
import './diff'; import './diff';
import './dropzone_input';
import './due_date_select';
import './files_comment_button'; import './files_comment_button';
import Flash, { removeFlashClickListener } from './flash'; import Flash, { removeFlashClickListener } from './flash';
import './gl_dropdown'; import './gl_dropdown';
......
/* global dateFormat */
import Pikaday from 'pikaday'; import Pikaday from 'pikaday';
import { parsePikadayDate, pikadayToString } from './lib/utils/datefix';
// Add datepickers to all `js-access-expiration-date` elements. If those elements are // Add datepickers to all `js-access-expiration-date` elements. If those elements are
// children of an element with the `clearable-input` class, and have a sibling // children of an element with the `clearable-input` class, and have a sibling
...@@ -22,8 +21,10 @@ export default function memberExpirationDate(selector = '.js-access-expiration-d ...@@ -22,8 +21,10 @@ export default function memberExpirationDate(selector = '.js-access-expiration-d
format: 'yyyy-mm-dd', format: 'yyyy-mm-dd',
minDate: new Date(), minDate: new Date(),
container: $input.parent().get(0), container: $input.parent().get(0),
parse: dateString => parsePikadayDate(dateString),
toString: date => pikadayToString(date),
onSelect(dateText) { onSelect(dateText) {
$input.val(dateFormat(new Date(dateText), 'yyyy-mm-dd')); $input.val(calendar.toString(dateText));
$input.trigger('change'); $input.trigger('change');
...@@ -31,7 +32,7 @@ export default function memberExpirationDate(selector = '.js-access-expiration-d ...@@ -31,7 +32,7 @@ export default function memberExpirationDate(selector = '.js-access-expiration-d
}, },
}); });
calendar.setDate(new Date($input.val())); calendar.setDate(parsePikadayDate($input.val()));
$input.data('pikaday', calendar); $input.data('pikaday', calendar);
}); });
......
---
title: Fix timezone bug in Pikaday and upgrade Pikaday version
merge_request:
author:
type: fixed
...@@ -464,3 +464,10 @@ ...@@ -464,3 +464,10 @@
:why: Our own library - https://gitlab.com/gitlab-org/gitlab-svgs :why: Our own library - https://gitlab.com/gitlab-org/gitlab-svgs
:versions: [] :versions: []
:when: 2017-09-19 14:36:32.795496000 Z :when: 2017-09-19 14:36:32.795496000 Z
- - :license
- pikaday
- MIT
- :who:
:why:
:versions: []
:when: 2017-10-17 17:46:12.367554000 Z
import { pad, parsePikadayDate, pikadayToString } from '~/lib/utils/datefix';
describe('datefix', () => {
describe('pad', () => {
it('should add a 0 when length is smaller than 2', () => {
expect(pad(2)).toEqual('02');
});
it('should not add a zero when lenght matches the default', () => {
expect(pad(12)).toEqual('12');
});
it('should add a 0 when lenght is smaller than the provided', () => {
expect(pad(12, 3)).toEqual('012');
});
});
describe('parsePikadayDate', () => {
it('should return a UTC date', () => {
expect(parsePikadayDate('2020-01-29')).toEqual(new Date('2020-01-29'));
});
});
describe('pikadayToString', () => {
it('should format a UTC date into yyyy-mm-dd format', () => {
expect(pikadayToString(new Date('2020-01-29'))).toEqual('2020-01-29');
});
});
});
...@@ -4677,9 +4677,9 @@ pify@^3.0.0: ...@@ -4677,9 +4677,9 @@ pify@^3.0.0:
version "3.0.0" version "3.0.0"
resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176"
pikaday@^1.5.1: pikaday@^1.6.1:
version "1.5.1" version "1.6.1"
resolved "https://registry.yarnpkg.com/pikaday/-/pikaday-1.5.1.tgz#0a48549bc1a14ea1d08c44074d761bc2f2bfcfd3" resolved "https://registry.yarnpkg.com/pikaday/-/pikaday-1.6.1.tgz#b91bcb9b8539cedd8d6d08e4e7465e12095671b0"
optionalDependencies: optionalDependencies:
moment "2.x" moment "2.x"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment