2016-01-28 23:48:14 +01:00
|
|
|
import Ember from 'ember';
|
2015-11-12 15:52:14 +01:00
|
|
|
import {
|
|
|
|
validator, buildValidations
|
|
|
|
}
|
|
|
|
from 'ember-cp-validations';
|
2015-11-23 13:32:40 +01:00
|
|
|
import moment from 'moment';
|
2015-11-12 15:52:14 +01:00
|
|
|
|
2016-08-12 19:19:19 +02:00
|
|
|
const {
|
|
|
|
computed,
|
|
|
|
Controller,
|
|
|
|
getOwner,
|
|
|
|
inject,
|
|
|
|
isEmpty,
|
|
|
|
Object: EmberObject
|
|
|
|
} = Ember;
|
2016-08-02 01:55:48 +02:00
|
|
|
|
2016-01-28 23:48:14 +01:00
|
|
|
const validCollection = function(collection) {
|
2015-11-12 15:52:14 +01:00
|
|
|
// return false if any object in collection is inValid
|
|
|
|
return !collection.any((object) => {
|
|
|
|
return object.get('validations.isInvalid');
|
|
|
|
});
|
|
|
|
};
|
2016-01-28 23:48:14 +01:00
|
|
|
const Validations = buildValidations({
|
2016-06-21 01:13:09 +02:00
|
|
|
name: [
|
|
|
|
validator('presence', {
|
|
|
|
presence() {
|
|
|
|
// only force presence if anonymousUser poll setting is false
|
|
|
|
if (!this.get('model.anonymousUser')) {
|
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
// disable presence validation
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
dependentKeys: ['anonymousUser', 'i18n.locale']
|
|
|
|
}),
|
|
|
|
validator('unique', {
|
|
|
|
parent: 'pollController.model',
|
|
|
|
attributeInParent: 'users',
|
|
|
|
dependentKeys: ['poll.users.[]', 'poll.users.@each.name', 'i18n.locale'],
|
|
|
|
disable() {
|
|
|
|
return this.get('model.anonymousUser');
|
|
|
|
},
|
|
|
|
messageKey: 'unique.name'
|
|
|
|
})
|
|
|
|
],
|
2015-11-12 15:52:14 +01:00
|
|
|
|
|
|
|
selections: [
|
|
|
|
validator('collection', true),
|
|
|
|
|
|
|
|
// all selection objects must be valid
|
|
|
|
// if forceAnswer is true in poll settings
|
|
|
|
validator(validCollection, {
|
2016-05-23 12:42:47 +02:00
|
|
|
dependentKeys: ['forceAnswer', 'selections.[]', 'selections.@each.value', 'i18n.locale']
|
2015-11-12 15:52:14 +01:00
|
|
|
})
|
|
|
|
]
|
|
|
|
});
|
2015-11-02 23:02:59 +01:00
|
|
|
|
2016-01-28 23:48:14 +01:00
|
|
|
const SelectionValidations = buildValidations({
|
2015-11-12 15:52:14 +01:00
|
|
|
value: validator('presence', {
|
|
|
|
presence() {
|
|
|
|
// only force present value if forceAnswer is true in poll settings
|
|
|
|
if (this.get('model.forceAnswer')) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
},
|
2016-06-27 12:53:05 +02:00
|
|
|
messageKey() {
|
|
|
|
if (this.get('model.isFreeText')) {
|
|
|
|
return 'errors.present';
|
|
|
|
} else {
|
|
|
|
return 'errors.present.answer.selection';
|
|
|
|
}
|
|
|
|
},
|
|
|
|
dependentKeys: ['isFreeText', 'forceAnswer', 'i18n.locale']
|
2015-11-12 15:52:14 +01:00
|
|
|
})
|
|
|
|
});
|
2015-11-02 23:02:59 +01:00
|
|
|
|
2016-08-02 01:55:48 +02:00
|
|
|
export default Controller.extend(Validations, {
|
2015-11-02 23:02:59 +01:00
|
|
|
actions: {
|
2015-11-12 15:52:14 +01:00
|
|
|
submit() {
|
|
|
|
if (this.get('validations.isValid')) {
|
2016-08-12 00:43:05 +02:00
|
|
|
const user = this.store.createRecord('user', {
|
2015-11-12 15:52:14 +01:00
|
|
|
creationDate: new Date(),
|
|
|
|
poll: this.get('pollController.model'),
|
|
|
|
version: this.buildInfo.semver
|
|
|
|
});
|
2015-11-02 23:02:59 +01:00
|
|
|
|
2016-08-04 22:24:53 +02:00
|
|
|
user.set('name', this.get('name'));
|
|
|
|
|
2016-01-28 23:48:14 +01:00
|
|
|
const selections = user.get('selections');
|
|
|
|
const possibleAnswers = this.get('pollController.model.answers');
|
2015-11-12 15:52:14 +01:00
|
|
|
|
|
|
|
this.get('selections').forEach((selection) => {
|
|
|
|
if (selection.get('value') !== null) {
|
|
|
|
if (this.get('isFreeText')) {
|
|
|
|
selections.createFragment({
|
|
|
|
label: selection.get('value')
|
|
|
|
});
|
2016-01-28 23:48:14 +01:00
|
|
|
} else {
|
|
|
|
const answer = possibleAnswers.findBy('type', selection.get('value'));
|
2015-11-12 15:52:14 +01:00
|
|
|
selections.createFragment({
|
|
|
|
icon: answer.get('icon'),
|
|
|
|
label: answer.get('label'),
|
|
|
|
labelTranslation: answer.get('labelTranslation'),
|
|
|
|
type: answer.get('type')
|
|
|
|
});
|
|
|
|
}
|
2016-01-28 23:48:14 +01:00
|
|
|
} else {
|
2015-11-12 15:52:14 +01:00
|
|
|
selections.createFragment();
|
2015-11-02 23:02:59 +01:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2016-08-04 22:24:53 +02:00
|
|
|
this.set('newUserRecord', user);
|
|
|
|
this.send('save');
|
2015-11-12 15:52:14 +01:00
|
|
|
}
|
2016-08-04 22:24:53 +02:00
|
|
|
},
|
|
|
|
save() {
|
|
|
|
const user = this.get('newUserRecord');
|
|
|
|
user.save()
|
|
|
|
.then(() => {
|
|
|
|
this.set('savingFailed', false);
|
|
|
|
|
|
|
|
// reset form
|
|
|
|
this.set('name', '');
|
|
|
|
this.get('selections').forEach((selection) => {
|
|
|
|
selection.set('value', null);
|
|
|
|
});
|
|
|
|
|
|
|
|
this.transitionToRoute('poll.evaluation', this.get('model'), {
|
|
|
|
queryParams: { encryptionKey: this.get('encryption.key') }
|
|
|
|
});
|
|
|
|
}, () => {
|
|
|
|
this.set('savingFailed', true);
|
|
|
|
});
|
2015-11-02 23:02:59 +01:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2016-08-02 01:55:48 +02:00
|
|
|
anonymousUser: computed.readOnly('pollController.model.anonymousUser'),
|
|
|
|
encryption: inject.service(),
|
|
|
|
forceAnswer: computed.readOnly('pollController.model.forceAnswer'),
|
|
|
|
i18n: inject.service(),
|
2016-05-23 12:42:47 +02:00
|
|
|
|
|
|
|
init() {
|
|
|
|
this.get('i18n.locale');
|
|
|
|
},
|
|
|
|
|
2016-08-02 01:55:48 +02:00
|
|
|
isFreeText: computed.readOnly('pollController.model.isFreeText'),
|
|
|
|
isFindADate: computed.readOnly('pollController.model.isFindADate'),
|
2015-11-12 15:52:14 +01:00
|
|
|
|
|
|
|
name: '',
|
|
|
|
|
2016-08-02 01:55:48 +02:00
|
|
|
pollController: inject.controller('poll'),
|
2015-11-12 15:52:14 +01:00
|
|
|
|
2016-08-02 01:55:48 +02:00
|
|
|
possibleAnswers: computed('pollController.model.answers', function() {
|
2015-11-12 15:52:14 +01:00
|
|
|
return this.get('pollController.model.answers').map((answer) => {
|
2016-08-12 19:19:19 +02:00
|
|
|
const owner = getOwner(this);
|
2015-11-24 00:53:03 +01:00
|
|
|
|
2016-08-02 01:55:48 +02:00
|
|
|
const AnswerObject = EmberObject.extend({
|
2015-11-24 00:53:03 +01:00
|
|
|
icon: answer.get('icon'),
|
|
|
|
type: answer.get('type')
|
|
|
|
});
|
2015-11-02 23:02:59 +01:00
|
|
|
|
2016-08-02 01:55:48 +02:00
|
|
|
if (!isEmpty(answer.get('labelTranslation'))) {
|
2016-08-12 19:19:19 +02:00
|
|
|
return AnswerObject.extend(owner.ownerInjection(), {
|
2016-08-02 01:55:48 +02:00
|
|
|
i18n: inject.service(),
|
|
|
|
label: computed('i18n.locale', function() {
|
2015-11-24 00:53:03 +01:00
|
|
|
return this.get('i18n').t(this.get('labelTranslation'));
|
|
|
|
}),
|
2016-01-28 23:48:14 +01:00
|
|
|
labelTranslation: answer.get('labelTranslation')
|
2015-11-24 00:53:03 +01:00
|
|
|
}).create();
|
2015-11-12 15:52:14 +01:00
|
|
|
} else {
|
2015-11-24 00:53:03 +01:00
|
|
|
return AnswerObject.extend({
|
|
|
|
label: answer.get('label')
|
|
|
|
});
|
2015-11-02 23:02:59 +01:00
|
|
|
}
|
2015-11-12 15:52:14 +01:00
|
|
|
});
|
|
|
|
}),
|
2015-11-02 23:02:59 +01:00
|
|
|
|
2016-08-04 22:24:53 +02:00
|
|
|
savingFailed: false,
|
|
|
|
|
2016-08-02 01:55:48 +02:00
|
|
|
selections: computed('pollController.model.options', 'pollController.dates', function() {
|
2016-01-28 23:48:14 +01:00
|
|
|
let options;
|
|
|
|
const isFindADate = this.get('isFindADate');
|
|
|
|
let lastDate;
|
2015-11-12 15:52:14 +01:00
|
|
|
|
|
|
|
if (this.get('isFindADate')) {
|
|
|
|
options = this.get('pollController.dates');
|
2016-01-28 23:48:14 +01:00
|
|
|
} else {
|
2015-11-12 15:52:14 +01:00
|
|
|
options = this.get('pollController.model.options');
|
2015-11-02 23:02:59 +01:00
|
|
|
}
|
|
|
|
|
2015-11-12 15:52:14 +01:00
|
|
|
return options.map((option) => {
|
2016-01-28 23:48:14 +01:00
|
|
|
let labelFormat;
|
|
|
|
let labelValue;
|
2015-11-12 15:52:14 +01:00
|
|
|
|
|
|
|
// format label
|
|
|
|
if (isFindADate) {
|
2016-02-13 18:37:33 +01:00
|
|
|
if (option.hasTime && lastDate && option.title.format('YYYY-MM-DD') === lastDate.format('YYYY-MM-DD')) {
|
2015-11-12 15:52:14 +01:00
|
|
|
// do not repeat dates for different times
|
2015-11-23 13:32:40 +01:00
|
|
|
labelValue = option.title;
|
2017-07-25 16:10:55 +02:00
|
|
|
labelFormat = 'time';
|
2015-11-12 15:52:14 +01:00
|
|
|
} else {
|
2015-11-23 13:32:40 +01:00
|
|
|
labelValue = option.title;
|
2017-07-25 16:10:55 +02:00
|
|
|
labelFormat = option.hasTime ? 'day-with-time' : 'day';
|
2015-11-12 15:52:14 +01:00
|
|
|
lastDate = option.title;
|
2015-11-02 23:02:59 +01:00
|
|
|
}
|
2016-01-28 23:48:14 +01:00
|
|
|
} else {
|
2015-11-23 13:32:40 +01:00
|
|
|
labelValue = option.get('title');
|
2017-07-25 16:10:55 +02:00
|
|
|
labelFormat = 'plain';
|
2015-11-12 15:52:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// https://github.com/offirgolan/ember-cp-validations#basic-usage---objects
|
2016-08-02 01:55:48 +02:00
|
|
|
// To lookup validators, container access is required which can cause an issue with Object creation
|
2015-11-12 15:52:14 +01:00
|
|
|
// if the object is statically imported. The current fix for this is as follows.
|
2016-08-12 19:19:19 +02:00
|
|
|
const owner = getOwner(this);
|
|
|
|
return EmberObject.extend(owner.ownerInjection(), SelectionValidations, {
|
2016-06-27 12:53:05 +02:00
|
|
|
// forceAnswer and isFreeText must be included in model
|
2015-11-12 15:52:14 +01:00
|
|
|
// cause otherwise validations can't depend on it
|
|
|
|
forceAnswer: this.get('forceAnswer'),
|
2016-06-27 12:53:05 +02:00
|
|
|
isFreeText: this.get('isFreeText'),
|
2015-11-12 15:52:14 +01:00
|
|
|
|
2015-11-23 13:32:40 +01:00
|
|
|
// a little bit hacky
|
|
|
|
// wasn't able to observe moment.locale since it should be in sync
|
|
|
|
// with i18n.locale we observe this one
|
|
|
|
// moment object stores it locale once it was created, therefore has
|
|
|
|
// to update the locale
|
|
|
|
// momentFormat from ember-moment does not currently observes locale
|
|
|
|
// changes https://github.com/stefanpenner/ember-moment/issues/108
|
|
|
|
// but that should be the way to go
|
2016-08-02 01:55:48 +02:00
|
|
|
label: computed('i18n.locale', function() {
|
2017-07-25 16:10:55 +02:00
|
|
|
let labelFormat = this.get('labelFormat');
|
|
|
|
|
|
|
|
if (labelFormat === 'plain') {
|
2015-11-23 13:32:40 +01:00
|
|
|
return this.get('labelValue');
|
|
|
|
}
|
2017-07-25 16:10:55 +02:00
|
|
|
|
|
|
|
let currentLocale = this.get('i18n.locale');
|
|
|
|
let momentFormat;
|
|
|
|
|
|
|
|
switch (labelFormat) {
|
|
|
|
case 'time':
|
|
|
|
momentFormat = 'LT';
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'day-with-time':
|
|
|
|
momentFormat = 'LLLL';
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'day':
|
|
|
|
momentFormat = moment.localeData(currentLocale)
|
|
|
|
.longDateFormat('LLLL')
|
|
|
|
.replace(moment.localeData(currentLocale).longDateFormat('LT'), '')
|
|
|
|
.trim();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return this.get('labelValue')
|
|
|
|
.locale(currentLocale)
|
|
|
|
.format(momentFormat);
|
2015-11-23 13:32:40 +01:00
|
|
|
}),
|
2016-01-28 23:48:14 +01:00
|
|
|
labelFormat,
|
|
|
|
labelValue,
|
2016-08-02 01:55:48 +02:00
|
|
|
i18n: inject.service(),
|
2016-05-23 12:42:47 +02:00
|
|
|
init() {
|
|
|
|
this.get('i18n.locale');
|
|
|
|
},
|
2015-11-12 15:52:14 +01:00
|
|
|
value: null
|
|
|
|
}).create();
|
|
|
|
});
|
|
|
|
})
|
2015-11-02 23:02:59 +01:00
|
|
|
});
|