commit
3039d4aaea
@ -0,0 +1 @@ |
|||||||
|
<op-date date-value="displayPaneController.getReadValue()" no-date-text="displayPaneController.placeholder"></op-date> |
@ -0,0 +1 @@ |
|||||||
|
<inplace-editor-date></inplace-editor-date> |
@ -0,0 +1 @@ |
|||||||
|
<input class="focus-input inplace-edit--date" type="text" /> |
@ -0,0 +1,164 @@ |
|||||||
|
//-- copyright
|
||||||
|
// OpenProject is a project management system.
|
||||||
|
// Copyright (C) 2012-2015 the OpenProject Foundation (OPF)
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License version 3.
|
||||||
|
//
|
||||||
|
// OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
|
||||||
|
// Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||||
|
// Copyright (C) 2010-2013 the ChiliProject Team
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License
|
||||||
|
// as published by the Free Software Foundation; either version 2
|
||||||
|
// of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
//
|
||||||
|
// See doc/COPYRIGHT.rdoc for more details.
|
||||||
|
//++
|
||||||
|
|
||||||
|
module.exports = function(WorkPackageFieldService, EditableFieldsState,
|
||||||
|
TimezoneService, ConfigurationService, I18n,
|
||||||
|
$timeout) { |
||||||
|
var parseDate = TimezoneService.parseDate, |
||||||
|
parseISODate = TimezoneService.parseISODate, |
||||||
|
formattedDate = function(date) { |
||||||
|
return TimezoneService.parseDate(date).format('L'); |
||||||
|
}, |
||||||
|
formattedISODate = TimezoneService.formattedISODate, |
||||||
|
customDateFormat = 'DD/MM/YYYY', |
||||||
|
datepickerFormat = 'dd/mm/yy', |
||||||
|
customFormattedDate = function(date) { |
||||||
|
return parseISODate(date).format(customDateFormat); |
||||||
|
}; |
||||||
|
return { |
||||||
|
restrict: 'E', |
||||||
|
transclude: true, |
||||||
|
replace: true, |
||||||
|
scope: {}, |
||||||
|
require: '^workPackageField', |
||||||
|
templateUrl: '/templates/work_packages/inplace_editor/custom/editable/date.html', |
||||||
|
controller: function() { |
||||||
|
}, |
||||||
|
controllerAs: 'customEditorController', |
||||||
|
link: function(scope, element, attrs, fieldController) { |
||||||
|
scope.fieldController = fieldController; |
||||||
|
var timerId = 0, |
||||||
|
prevDate = '', |
||||||
|
input = element, |
||||||
|
addClearButton = function (inp) { |
||||||
|
setTimeout(function() { |
||||||
|
var buttonPane = angular.element('.ui-datepicker-buttonpane'); |
||||||
|
|
||||||
|
if(buttonPane.find('.ui-datepicker-clear').length > 0) { |
||||||
|
buttonPane.find('.ui-datepicker-clear').remove(); |
||||||
|
} |
||||||
|
|
||||||
|
angular.element( '<button>', { |
||||||
|
text: 'Clear', |
||||||
|
click: function() { |
||||||
|
setDate(inp, null); |
||||||
|
} |
||||||
|
}) |
||||||
|
.addClass('ui-datepicker-clear ui-state-default ui-priority-primary ui-corner-all') |
||||||
|
.appendTo(buttonPane); |
||||||
|
}, 1); |
||||||
|
}, |
||||||
|
setDate = function(inp, date) { |
||||||
|
if(date) { |
||||||
|
inp.datepicker('option', 'defaultDate', customFormattedDate(date)); |
||||||
|
inp.datepicker('option', 'setDate', customFormattedDate(date)); |
||||||
|
inp.val(customFormattedDate(date)); |
||||||
|
inp.change(); |
||||||
|
} else { |
||||||
|
inp.datepicker('option', 'defaultDate', null); |
||||||
|
inp.datepicker('option', 'setDate', null); |
||||||
|
inp.val(''); |
||||||
|
inp.change(); |
||||||
|
date = null; |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
input.attr('placeholder', '-'); |
||||||
|
|
||||||
|
input.on('change', function() { |
||||||
|
if(input.val().replace(/^\s+|\s+$/g, '') === '') { |
||||||
|
$timeout(function() { |
||||||
|
scope.fieldController.writeValue = null; |
||||||
|
}); |
||||||
|
input.val(''); |
||||||
|
$timeout.cancel(timerId); |
||||||
|
return; |
||||||
|
} |
||||||
|
$timeout.cancel(timerId); |
||||||
|
timerId = $timeout(function() { |
||||||
|
var date = input.val(), |
||||||
|
isValid = TimezoneService.isValid(date, customDateFormat); |
||||||
|
|
||||||
|
if(isValid){ |
||||||
|
scope.fieldController.writeValue = formattedISODate(parseDate(date, customDateFormat)); |
||||||
|
} |
||||||
|
}, 1000); |
||||||
|
}); |
||||||
|
|
||||||
|
input.datepicker({ |
||||||
|
firstDay: ConfigurationService.startOfWeek(), |
||||||
|
showWeeks: true, |
||||||
|
changeMonth: true, |
||||||
|
numberOfMonths: 1, |
||||||
|
dateFormat: datepickerFormat, |
||||||
|
alterOffset: function(offset) { |
||||||
|
var wHeight = angular.element(window).height(), |
||||||
|
dpHeight = angular.element('#ui-datepicker-div').height(), |
||||||
|
inputTop = input.offset().top, |
||||||
|
inputHeight = input.innerHeight(); |
||||||
|
|
||||||
|
if((inputTop + inputHeight + dpHeight) > wHeight) { |
||||||
|
offset.top -= inputHeight - 4; |
||||||
|
} |
||||||
|
return offset; |
||||||
|
}, |
||||||
|
beforeShow: function() { |
||||||
|
addClearButton(input); |
||||||
|
}, |
||||||
|
onChangeMonthYear: function() { |
||||||
|
addClearButton(input); |
||||||
|
}, |
||||||
|
onClose: function(selectedDate) { |
||||||
|
if(!selectedDate || selectedDate === '' || selectedDate === prevDate) { |
||||||
|
return; |
||||||
|
} |
||||||
|
prevDate = parseDate(selectedDate, customDateFormat); |
||||||
|
$timeout(function() { |
||||||
|
scope.fieldController.writeValue = formattedISODate(prevDate); |
||||||
|
}); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
if(scope.fieldController.writeValue) { |
||||||
|
prevDate = formattedDate(scope.fieldController.writeValue); |
||||||
|
} |
||||||
|
|
||||||
|
setDate(input, scope.fieldController.writeValue); |
||||||
|
|
||||||
|
angular.element('.work-packages--details-content').scroll(function() { |
||||||
|
input.datepicker('hide'); |
||||||
|
angular.element('#ui-datepicker-div').blur(); |
||||||
|
}); |
||||||
|
|
||||||
|
angular.element(window).resize(function() { |
||||||
|
input.datepicker('hide'); |
||||||
|
angular.element('#ui-datepicker-div').blur(); |
||||||
|
}); |
||||||
|
} |
||||||
|
}; |
||||||
|
}; |
@ -0,0 +1,120 @@ |
|||||||
|
//-- copyright
|
||||||
|
// OpenProject is a project management system.
|
||||||
|
// Copyright (C) 2012-2015 the OpenProject Foundation (OPF)
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License version 3.
|
||||||
|
//
|
||||||
|
// OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
|
||||||
|
// Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||||
|
// Copyright (C) 2010-2013 the ChiliProject Team
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License
|
||||||
|
// as published by the Free Software Foundation; either version 2
|
||||||
|
// of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
//
|
||||||
|
// See doc/COPYRIGHT.rdoc for more details.
|
||||||
|
//++
|
||||||
|
|
||||||
|
/* jshint ignore:start */ |
||||||
|
|
||||||
|
var expect = require('../../../../spec_helper.js').expect, |
||||||
|
detailsPaneHelper = require('../details-pane-helper.js'); |
||||||
|
|
||||||
|
|
||||||
|
describe('details pane', function() { |
||||||
|
describe('custom fields', function() { |
||||||
|
var datePicker; |
||||||
|
describe('date editbale', function() { |
||||||
|
beforeEach(function() { |
||||||
|
detailsPaneHelper.loadPane(819, 'overview'); |
||||||
|
datePicker = element(by.css('.inplace-edit.attribute-customField9')); |
||||||
|
}); |
||||||
|
|
||||||
|
context('read value', function() { |
||||||
|
it('should be present on page', function(){ |
||||||
|
expect(datePicker.isDisplayed()).to.eventually.be.true; |
||||||
|
}); |
||||||
|
|
||||||
|
it('shows date range', function() { |
||||||
|
expect(datePicker.getText()).to.eventually.equal('04/12/2015'); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
context('write value', function() { |
||||||
|
var date; |
||||||
|
|
||||||
|
beforeEach(function() { |
||||||
|
date = datePicker.$('input.inplace-edit--date'); |
||||||
|
}); |
||||||
|
|
||||||
|
beforeEach(function() { |
||||||
|
datePicker.$('.inplace-edit--read-value').click(); |
||||||
|
}); |
||||||
|
|
||||||
|
it('opens calendar on click', function() { |
||||||
|
date.click(); |
||||||
|
expect($('.ui-datepicker').isDisplayed()).to.eventually.be.true; |
||||||
|
}); |
||||||
|
|
||||||
|
it('shows date in input', function() { |
||||||
|
date.getText(function(text) { |
||||||
|
expect(text).to.equal('04/12/2015'); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
describe('validation', function() { |
||||||
|
it('validates valid date', function() { |
||||||
|
date.clear(); |
||||||
|
date.sendKeys('04/12/2015'); |
||||||
|
date.getText(function(text) { |
||||||
|
expect(text).to.equal('04/12/2015'); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
it('doesn\'t validate invalid date', function() { |
||||||
|
date.clear(); |
||||||
|
date.sendKeys('13/24/2014'); |
||||||
|
date.getText(function(text) { |
||||||
|
expect(text).to.equal('04/12/2015'); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
it('validates empty date', function() { |
||||||
|
date.clear(); |
||||||
|
date.getText(function(text) { |
||||||
|
expect(text).to.equal(''); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
describe('date selection', function() { |
||||||
|
it('changes date by clicking on calendar', function() { |
||||||
|
date.click(); |
||||||
|
element.all(by.css('a.ui-state-default')).filter(function(elem) { |
||||||
|
return elem.getText().then(function(text) { |
||||||
|
return text.indexOf('9') !== -1; |
||||||
|
}); |
||||||
|
}).then(function(filteredElements) { |
||||||
|
filteredElements[0].click(); |
||||||
|
date.getText(function(text) { |
||||||
|
expect(text).to.equal('04/09/2015'); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
||||||
|
/* jshint ignore:end */ |
Loading…
Reference in new issue