2018-12-29 01:27:37 +01:00
|
|
|
import { inject as service } from '@ember/service';
|
|
|
|
import { readOnly } from '@ember/object/computed';
|
|
|
|
import { assert } from '@ember/debug';
|
|
|
|
import { computed } from '@ember/object';
|
|
|
|
import { isEmpty } from '@ember/utils';
|
2015-10-13 11:29:51 +02:00
|
|
|
import DS from 'ember-data';
|
2016-06-08 13:55:00 +02:00
|
|
|
import moment from 'moment';
|
2017-07-30 18:19:17 +02:00
|
|
|
import Fragment from 'ember-data-model-fragments/fragment';
|
|
|
|
import { fragmentOwner } from 'ember-data-model-fragments/attributes';
|
2016-01-19 04:56:51 +01:00
|
|
|
import {
|
|
|
|
validator, buildValidations
|
|
|
|
}
|
|
|
|
from 'ember-cp-validations';
|
2015-10-13 11:29:51 +02:00
|
|
|
|
2016-08-12 19:19:19 +02:00
|
|
|
const { attr } = DS;
|
2016-06-08 13:55:00 +02:00
|
|
|
|
2016-01-28 23:48:14 +01:00
|
|
|
const Validations = buildValidations({
|
2019-11-02 16:51:47 +01:00
|
|
|
isPartiallyFilled: validator('falsy', {
|
|
|
|
messageKey: 'errors.time.notPartially',
|
|
|
|
dependentKeys: ['model.i18n.locale'],
|
|
|
|
}),
|
2016-01-19 04:56:51 +01:00
|
|
|
title: [
|
2016-02-13 18:37:33 +01:00
|
|
|
validator('iso8601', {
|
2018-12-29 01:27:37 +01:00
|
|
|
active: readOnly('model.poll.isFindADate'),
|
2016-02-13 18:37:33 +01:00
|
|
|
validFormats: [
|
|
|
|
'YYYY-MM-DD',
|
|
|
|
'YYYY-MM-DDTHH:mmZ',
|
|
|
|
'YYYY-MM-DDTHH:mm:ssZ',
|
|
|
|
'YYYY-MM-DDTHH:mm:ss.SSSZ'
|
2016-05-23 13:40:45 +02:00
|
|
|
],
|
2018-12-28 22:26:34 +01:00
|
|
|
dependentKeys: ['model.i18n.locale']
|
2016-05-23 13:40:45 +02:00
|
|
|
}),
|
|
|
|
validator('presence', {
|
|
|
|
presence: true,
|
2018-12-28 22:26:34 +01:00
|
|
|
dependentKeys: ['model.i18n.locale']
|
2016-01-19 04:56:51 +01:00
|
|
|
}),
|
2016-05-20 21:49:29 +02:00
|
|
|
validator('unique', {
|
|
|
|
parent: 'poll',
|
|
|
|
attributeInParent: 'options',
|
2018-12-28 22:26:34 +01:00
|
|
|
dependentKeys: ['model.poll.options.[]', 'model.poll.options.@each.title', 'model.i18n.locale'],
|
|
|
|
descriptionKey: computed('model.poll.isFindADate', function() {
|
|
|
|
let isFindADate = this.get('model.poll.isFindADate');
|
|
|
|
return isFindADate ? 'times' : 'options';
|
|
|
|
})
|
2016-05-20 21:49:29 +02:00
|
|
|
})
|
2016-06-08 13:55:00 +02:00
|
|
|
],
|
|
|
|
time: [
|
|
|
|
validator('time', {
|
|
|
|
allowEmpty: true
|
|
|
|
}),
|
|
|
|
// alias title validation especially for unique validation
|
|
|
|
validator('alias', {
|
|
|
|
alias: 'title',
|
|
|
|
firstMessageOnly: true
|
2019-11-02 16:51:47 +01:00
|
|
|
}),
|
|
|
|
// alias is partially filled validation as that's part of time validation
|
|
|
|
validator('alias', {
|
|
|
|
alias: 'isPartiallyFilled',
|
|
|
|
}),
|
2016-01-19 04:56:51 +01:00
|
|
|
]
|
|
|
|
});
|
|
|
|
|
2016-08-12 19:19:19 +02:00
|
|
|
export default Fragment.extend(Validations, {
|
|
|
|
poll: fragmentOwner(),
|
|
|
|
title: attr('string'),
|
2016-05-23 13:40:45 +02:00
|
|
|
|
2016-06-08 13:55:00 +02:00
|
|
|
date: computed('title', function() {
|
|
|
|
const allowedFormats = [
|
|
|
|
'YYYY-MM-DD',
|
|
|
|
'YYYY-MM-DDTHH:mm:ss.SSSZ'
|
|
|
|
];
|
2018-12-29 20:35:04 +01:00
|
|
|
const value = this.title;
|
2018-12-29 01:27:37 +01:00
|
|
|
if (isEmpty(value)) {
|
2016-06-08 13:55:00 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const format = allowedFormats.find((f) => {
|
|
|
|
// if format length does not match value length
|
|
|
|
// string can't be in this format
|
|
|
|
return f.length === value.length && moment(value, f, true).isValid();
|
|
|
|
});
|
2016-06-13 11:14:42 +02:00
|
|
|
if (isEmpty(format)) {
|
2016-06-08 13:55:00 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
return moment(value, format, true);
|
|
|
|
}),
|
|
|
|
|
|
|
|
day: computed('date', function() {
|
2018-12-29 20:35:04 +01:00
|
|
|
const date = this.date;
|
2016-06-08 13:55:00 +02:00
|
|
|
if (!moment.isMoment(date)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
return date.format('YYYY-MM-DD');
|
|
|
|
}),
|
|
|
|
|
|
|
|
dayFormatted: computed('date', 'i18n.locale', function() {
|
2018-12-29 20:35:04 +01:00
|
|
|
let date = this.date;
|
2016-06-08 13:55:00 +02:00
|
|
|
if (!moment.isMoment(date)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const locale = this.get('i18n.locale');
|
|
|
|
const format = moment.localeData(locale)
|
|
|
|
.longDateFormat('LLLL')
|
|
|
|
.replace(
|
|
|
|
moment.localeData(locale).longDateFormat('LT'), '')
|
|
|
|
.trim();
|
|
|
|
|
|
|
|
// momentjs object caches the locale on creation
|
|
|
|
if (date.locale() !== locale) {
|
|
|
|
// we clone the date to allow adjusting timezone without changing the object
|
|
|
|
date = date.clone();
|
|
|
|
date.locale(locale);
|
|
|
|
}
|
|
|
|
|
|
|
|
return date.format(format);
|
|
|
|
}),
|
|
|
|
|
2016-06-20 20:48:48 +02:00
|
|
|
hasTime: computed('title', function() {
|
2018-12-29 20:35:04 +01:00
|
|
|
return moment.isMoment(this.date) &&
|
|
|
|
this.title.length === 'YYYY-MM-DDTHH:mm:ss.SSSZ'.length;
|
2016-06-20 20:48:48 +02:00
|
|
|
}),
|
|
|
|
|
2019-11-02 16:51:47 +01:00
|
|
|
// isPartiallyFilled should be set only for times on creation if input is filled
|
|
|
|
// partially (e.g. "11:--"). It's required cause ember-cp-validations does not
|
|
|
|
// provide any method to push a validation error into validations. It's only
|
|
|
|
// working based on a property of the model.
|
|
|
|
isPartiallyFilled: false,
|
|
|
|
|
2016-06-08 13:55:00 +02:00
|
|
|
time: computed('date', {
|
|
|
|
get() {
|
2018-12-29 20:35:04 +01:00
|
|
|
const date = this.date;
|
2016-06-08 13:55:00 +02:00
|
|
|
if (!moment.isMoment(date)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
// verify that value is an ISO 8601 date string containg time
|
|
|
|
// testing length is faster than parsing with moment
|
2018-12-29 20:35:04 +01:00
|
|
|
const value = this.title;
|
2016-06-08 13:55:00 +02:00
|
|
|
if (value.length !== 'YYYY-MM-DDTHH:mm:ss.SSSZ'.length) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
return date.format('HH:mm');
|
|
|
|
},
|
|
|
|
set(key, value) {
|
2019-11-02 16:51:47 +01:00
|
|
|
let date = this.date;
|
2016-06-08 13:55:00 +02:00
|
|
|
assert(
|
|
|
|
'can not set a time if current value is not a valid date',
|
|
|
|
moment.isMoment(date)
|
|
|
|
);
|
|
|
|
|
2016-06-10 20:59:02 +02:00
|
|
|
// set time to undefined if value is false
|
2018-12-29 01:27:37 +01:00
|
|
|
if (isEmpty(value)) {
|
2016-06-10 20:59:02 +02:00
|
|
|
this.set('title', date.format('YYYY-MM-DD'));
|
2016-06-08 13:55:00 +02:00
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!moment(value, 'HH:mm', true).isValid()) {
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
|
|
|
const [ hour, minute ] = value.split(':');
|
|
|
|
this.set('title', date.hour(hour).minute(minute).toISOString());
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
}),
|
|
|
|
|
2018-12-29 01:27:37 +01:00
|
|
|
i18n: service(),
|
2016-05-23 13:40:45 +02:00
|
|
|
init() {
|
|
|
|
this.get('i18n.locale');
|
|
|
|
}
|
2015-11-20 01:09:37 +01:00
|
|
|
});
|