From 87a1dc2beeda8c73f0db3ebe38bbdd83f391211a Mon Sep 17 00:00:00 2001 From: Antonio Tapiador del Dujo Date: Wed, 21 Dec 2016 00:11:43 +0100 Subject: [PATCH] Recurrence selects --- frontend/app/components/select-element.js | 26 ----- frontend/app/components/task-details-form.js | 49 +------- frontend/app/locales/en/translations.js | 26 +++++ frontend/app/locales/es/translations.js | 26 +++++ .../models/recurrence-match-day-options.js | 13 +++ frontend/app/models/recurrence-match-days.js | 11 -- .../recurrence-match-position-options.js | 12 ++ .../app/models/recurrence-match-positions.js | 10 -- frontend/app/models/recurrence-options.js | 13 ++- frontend/app/models/task.js | 105 +++++++++++++++++- .../templates/components/select-element.hbs | 5 - .../components/task-details-form.hbs | 63 +++++++---- 12 files changed, 233 insertions(+), 126 deletions(-) delete mode 100644 frontend/app/components/select-element.js create mode 100644 frontend/app/models/recurrence-match-day-options.js delete mode 100644 frontend/app/models/recurrence-match-days.js create mode 100644 frontend/app/models/recurrence-match-position-options.js delete mode 100644 frontend/app/models/recurrence-match-positions.js delete mode 100644 frontend/app/templates/components/select-element.hbs diff --git a/frontend/app/components/select-element.js b/frontend/app/components/select-element.js deleted file mode 100644 index 3b24f90..0000000 --- a/frontend/app/components/select-element.js +++ /dev/null @@ -1,26 +0,0 @@ -import Ember from 'ember'; - -export default Ember.Component.extend({ - tagName: 'select', - change: function(event) { - var index = event.target.selectedIndex; - var choice = this.get('iterableChoices').objectAt(index); - - this.set('value', choice.value); - }, - iterableChoices: function() { - if(this.get('choices.length') === 0) { - return {}; - } - return this.get('choices').map(function(choice) { - if(choice.constructor.name === 'String') { - var selected = this.get('value') === choice ? 'selected="selected"' : ''; - return { label: choice, value: choice, selected: selected }; - } else { - let isSelected = this.get('value') === choice.value ? 'selected' : ''; - choice.set('selected', isSelected); - return choice; - } - }, this); - }.property('choices,value') -}); diff --git a/frontend/app/components/task-details-form.js b/frontend/app/components/task-details-form.js index 158fa8a..c56c7db 100644 --- a/frontend/app/components/task-details-form.js +++ b/frontend/app/components/task-details-form.js @@ -1,8 +1,5 @@ import Ember from 'ember'; - -import recurrenceOptions from 'frontend/models/recurrence-options'; -import recurrenceMatchPositions from 'frontend/models/recurrence-match-positions'; -import recurrenceMatchDays from 'frontend/models/recurrence-match-days'; +import Task from 'frontend/models/task'; export default Ember.Component.extend({ i18n: Ember.inject.service(), @@ -16,48 +13,8 @@ export default Ember.Component.extend({ return translations; }.property('taskAttributes'), - recurrenceOptions: recurrenceOptions, - recurrenceMatchPositions: recurrenceMatchPositions, - recurrenceMatchDays: recurrenceMatchDays, - recurrenceMatchPositionId: Ember.computed('task.recurrenceMatch', { - get: function() { - return this.getRecurrencePositionId(); - }, - set: function(_key, value) { - let recurrenceMatch = `${ value } ${ this.getRecurrenceDayId() }`; - this.set('task.recurrenceMatch', recurrenceMatch); - } - }), - recurrenceMatchDayId: Ember.computed('task.recurrenceMatch', { - get: function() { - return this.getRecurrenceDayId(); - }, - set: function(_key, value) { - let recurrenceMatch = `${ this.getRecurrencePositionId() } ${ value }`; - this.set('task.recurrenceMatch', recurrenceMatch); - } - }), - getRecurrencePositionId: function() { - if(this.get('task.recurrenceMatch')) { - return this.recurrenceOptionAt(0); - } else { - return 0; - } - }, - getRecurrenceDayId: function() { - if(this.get('task.recurrenceMatch')) { - return this.recurrenceOptionAt(1); - } else { - return 0; - } - }, - recurrenceOptionAt: function(index) { - let option = this.get('task.recurrenceMatch').split(' ')[index]; - return parseInt(option); - }, - taskRecurreceIsMonthly: function() { - return this.get('task.recurrence') === 2; - }.property('task.recurrence'), + Task: Task, + actions: { submitForm() { return this.sendAction('formAction', this.task); diff --git a/frontend/app/locales/en/translations.js b/frontend/app/locales/en/translations.js index efdeac1..f3b439f 100644 --- a/frontend/app/locales/en/translations.js +++ b/frontend/app/locales/en/translations.js @@ -91,6 +91,32 @@ export default { 'subject': 'Subject', 'to': 'To:' }, + 'recurrence': { + 'montly': 'Every month', + 'placeholder': 'Task is carried out...', + 'weekly': 'Every week' + }, + 'recurrenceMatch': { + 'day': { + 'monday': 'Monday', + 'tuesday': 'Tuesday', + 'wednesday': 'Wednesday', + 'thursday': 'Thursday', + 'friday': 'Friday', + 'saturday': 'Saturday', + 'sunday': 'Sunday', + 'placeholder': 'day of the week' + }, + 'position': { + 'first': 'the first', + 'second': 'the second', + 'third': 'the third', + 'fourth': 'the fourth', + 'nextToLast': 'the next to last', + 'last': 'the last', + 'placeholder': 'at certain...' + } + }, 'show': { 'notifications': { 'title': 'Notifications' diff --git a/frontend/app/locales/es/translations.js b/frontend/app/locales/es/translations.js index 07c3ff6..c3df14c 100644 --- a/frontend/app/locales/es/translations.js +++ b/frontend/app/locales/es/translations.js @@ -91,6 +91,32 @@ export default { 'subject': 'Asunto', 'to': 'Para' }, + 'recurrence': { + 'montly': 'Cada mes', + 'placeholder': 'La tarea se lleva a cabo...', + 'weekly': 'Cada semana' + }, + 'recurrenceMatch': { + 'day': { + 'monday': 'lunes', + 'tuesday': 'martes', + 'wednesday': 'miércoles', + 'thursday': 'jueves', + 'friday': 'viernes', + 'saturday': 'sábado', + 'sunday': 'domingo', + 'placeholder': 'día de la semana' + }, + 'position': { + 'first': 'el primer', + 'second': 'el segundo', + 'third': 'el tercer', + 'fourth': 'el cuarto', + 'nextToLast': 'el penúltimo', + 'last': 'el último', + 'placeholder': 'en tal...' + } + }, 'show': { 'notifications': { 'title': 'Notificaciones' diff --git a/frontend/app/models/recurrence-match-day-options.js b/frontend/app/models/recurrence-match-day-options.js new file mode 100644 index 0000000..a46a58d --- /dev/null +++ b/frontend/app/models/recurrence-match-day-options.js @@ -0,0 +1,13 @@ +import Ember from 'ember'; + +const options = [ + Ember.Object.create({ value: 0, label: "sunday" }), + Ember.Object.create({ value: 1, label: "monday" }), + Ember.Object.create({ value: 2, label: "tuesday" }), + Ember.Object.create({ value: 3, label: "wednesday" }), + Ember.Object.create({ value: 4, label: "thursday" }), + Ember.Object.create({ value: 5, label: "friday" }), + Ember.Object.create({ value: 6, label: "saturday" }) +]; + +export default options; diff --git a/frontend/app/models/recurrence-match-days.js b/frontend/app/models/recurrence-match-days.js deleted file mode 100644 index 486cfb0..0000000 --- a/frontend/app/models/recurrence-match-days.js +++ /dev/null @@ -1,11 +0,0 @@ -import Ember from 'ember'; - -export default [ - Ember.Object.create({ value: 0, label: "Sunday" }), - Ember.Object.create({ value: 1, label: "Monday" }), - Ember.Object.create({ value: 2, label: "Tuesday" }), - Ember.Object.create({ value: 3, label: "Wednesday" }), - Ember.Object.create({ value: 4, label: "Thursday" }), - Ember.Object.create({ value: 5, label: "Friday" }), - Ember.Object.create({ value: 6, label: "Saturday" }) -]; diff --git a/frontend/app/models/recurrence-match-position-options.js b/frontend/app/models/recurrence-match-position-options.js new file mode 100644 index 0000000..ea25b48 --- /dev/null +++ b/frontend/app/models/recurrence-match-position-options.js @@ -0,0 +1,12 @@ +import Ember from 'ember'; + +const options = [ + Ember.Object.create({ value: 0, label: "first" }), + Ember.Object.create({ value: 1, label: "second" }), + Ember.Object.create({ value: 2, label: "third" }), + Ember.Object.create({ value: 3, label: "fourth" }), + Ember.Object.create({ value: -2, label: "nextToLast" }), + Ember.Object.create({ value: -1, label: "last" }) +]; + +export default options; diff --git a/frontend/app/models/recurrence-match-positions.js b/frontend/app/models/recurrence-match-positions.js deleted file mode 100644 index 031ef17..0000000 --- a/frontend/app/models/recurrence-match-positions.js +++ /dev/null @@ -1,10 +0,0 @@ -import Ember from 'ember'; - -export default [ - Ember.Object.create({ value: 0, label: "First" }), - Ember.Object.create({ value: 1, label: "Second" }), - Ember.Object.create({ value: 2, label: "Third" }), - Ember.Object.create({ value: 3, label: "Fourth" }), - Ember.Object.create({ value: -1, label: "Last" }), - Ember.Object.create({ value: -2, label: "Next to last" }) -]; diff --git a/frontend/app/models/recurrence-options.js b/frontend/app/models/recurrence-options.js index 4e22146..bc8b01e 100644 --- a/frontend/app/models/recurrence-options.js +++ b/frontend/app/models/recurrence-options.js @@ -1,8 +1,11 @@ import Ember from 'ember'; -export default [ - Ember.Object.create({ value: 0, label: "Daily" }), - Ember.Object.create({ value: 1, label: "Weekly" }), - Ember.Object.create({ value: 2, label: "Montly" }), - Ember.Object.create({ value: 3, label: "Yearly" }) +const options = [ +// Recurrence is currently implemented for weeks and months +// Ember.Object.create({ value: 0, label: "daily" }), + Ember.Object.create({ value: 1, label: "weekly" }), + Ember.Object.create({ value: 2, label: "montly" }) +// Ember.Object.create({ value: 3, label: "yearly" }) ]; + +export default options; diff --git a/frontend/app/models/task.js b/frontend/app/models/task.js index 1854871..b424ce0 100644 --- a/frontend/app/models/task.js +++ b/frontend/app/models/task.js @@ -1,7 +1,11 @@ import Ember from 'ember'; import DS from 'ember-data'; -export default DS.Model.extend({ +import recurrenceOptions from 'frontend/models/recurrence-options'; +import recurrenceMatchPositionOptions from 'frontend/models/recurrence-match-position-options'; +import recurrenceMatchDayOptions from 'frontend/models/recurrence-match-day-options'; + +const Task = DS.Model.extend({ title: DS.attr('string'), recurrence: DS.attr('number'), recurrenceMatch: DS.attr('string'), @@ -9,10 +13,73 @@ export default DS.Model.extend({ notificationEmail: DS.attr('string'), notificationSubject: DS.attr('string'), notificationBody: DS.attr('string'), + + // Relations + turns: DS.hasMany('turn'), + + // Computed properties + recurrenceObject: Ember.computed('recurrence', { + get() { + return this.findOption('recurrence'); + }, + set(key, option) { + this.set('recurrence', option.value); + + return this.findOption('recurrence'); + } + }), + recurrenceMatchPosition: Ember.computed('recurrenceMatch', { + get() { + return this.recurrenceMatchAt(0); + }, + set(key, value) { + let recurrenceMatch = `${ value } ${ this.get('recurrenceMatchDay') }`; + + this.set('recurrenceMatch', recurrenceMatch); + + return value; + } + }), + recurrenceMatchPositionObject: Ember.computed('recurrenceMatchPosition', { + get() { + return this.findOption('recurrenceMatchPosition'); + }, + set(key, option) { + this.set('recurrenceMatchPosition', option.value); + + return this.findOption('recurrenceMatchPosition'); + } + }), + recurrenceMatchDay: Ember.computed('recurrenceMatch', { + get() { + return this.recurrenceMatchAt(1); + }, + set(key, value) { + let recurrenceMatch = `${ this.get('recurrenceMatchPosition') } ${ value }`; + + this.set('recurrenceMatch', recurrenceMatch); + + return value; + } + }), + recurrenceMatchDayObject: Ember.computed('recurrenceMatchDay', { + get() { + return this.findOption('recurrenceMatchDay'); + }, + set(key, option) { + this.set('recurrenceMatchDay', option.value); + + return this.findOption('recurrenceMatchDay'); + } + }), + + recurreceIsMonthly: Ember.computed('recurrence', function() { + return this.get('recurrence') === 2; + }), + notificationEmpty: Ember.computed('notificationSubject', 'notificationBody', function () { return ! (this.get('notificationSubject') || this.get('notificationBody')); }), - turns: DS.hasMany('turn'), turnsSorting: ['position'], sortedTurns: Ember.computed.sort('turns', 'turnsSorting'), responsibles: Ember.computed('sortedTurns', function() { @@ -23,5 +90,37 @@ export default DS.Model.extend({ } else { return null; } - }) + }), + + // Helper functions + + /* + * Finds the option from recurrenceOptions, recurrenceMatchPositionOptions, + * recurrenceMatchDayOptions that matches value + * + * Defaults to current value + */ + findOption: function(name, value = this.get(name)) { + return Task.findOption(name, value); + }, + recurrenceMatchAt: function(index) { + var value = this.get('recurrenceMatch').split(' ')[index]; + + return parseInt(value); + }, +}); + +Task.reopenClass({ + // Options + recurrenceOptions: recurrenceOptions, + recurrenceMatchPositionOptions: recurrenceMatchPositionOptions, + recurrenceMatchDayOptions: recurrenceMatchDayOptions, + + findOption: function(name, value) { + var property = name + 'Options'; + + return this[property].find(opt => opt.value === value); + } }); + +export default Task; diff --git a/frontend/app/templates/components/select-element.hbs b/frontend/app/templates/components/select-element.hbs deleted file mode 100644 index 4d39abe..0000000 --- a/frontend/app/templates/components/select-element.hbs +++ /dev/null @@ -1,5 +0,0 @@ -{{#each iterableChoices as |choice|}} - -{{/each}} diff --git a/frontend/app/templates/components/task-details-form.hbs b/frontend/app/templates/components/task-details-form.hbs index 6a0fcac..fa0cafb 100644 --- a/frontend/app/templates/components/task-details-form.hbs +++ b/frontend/app/templates/components/task-details-form.hbs @@ -8,34 +8,57 @@ {{#bs-form action="submitForm"}} {{bs-form-element label=labels.title placeholder=labels.title value=task.title}} - {{bs-form-element label=labels.description - placeholder=labels.description - controlType="textarea" - value=task.description}}
- {{select-element choices=recurrenceOptions - value=task.recurrence - classNames="form-control"}} -
- {{#if taskRecurreceIsMonthly}} - - {{select-element choices=recurrenceMatchPositions - value=recurrenceMatchPositionId - classNames="form-control"}} +
- - {{select-element choices=recurrenceMatchDays - value=recurrenceMatchDayId - classNames="form-control"}} +
+ {{#power-select + options=Task.recurrenceOptions + selected=task.recurrenceObject + onchange=(action (mut task.recurrenceObject)) + searchEnabled=false + placeholder=(t 'tasks.recurrence.placeholder') + as |option|}} + {{ t (concat 'tasks.recurrence.' option.label)}} + {{/power-select}} +
+ {{#if task.recurreceIsMonthly}} +
- {{bs-form-element controlType="hidden" - value=task.recurrenceMatch}} + {{#power-select + options=Task.recurrenceMatchPositionOptions + selected=task.recurrenceMatchPositionObject + onchange=(action (mut task.recurrenceMatchPositionObject)) + searchEnabled=false + placeholder=(t 'tasks.recurrenceMatch.position.placeholder') + as |option|}} + {{ t (concat 'tasks.recurrenceMatch.position.' option.label)}} + {{/power-select}} +
+
+ {{#power-select + options=Task.recurrenceMatchDayOptions + selected=task.recurrenceMatchDayObject + onchange=(action (mut task.recurrenceMatchDayObject)) + searchEnabled=false + placeholder=(t 'tasks.recurrenceMatch.day.placeholder') + as |option|}} + {{ t (concat 'tasks.recurrenceMatch.day.' option.label)}} + {{/power-select}} - {{/if}} +
+ {{/if}} +
+ + + {{bs-form-element label=labels.description + placeholder=labels.description + controlType="textarea" + value=task.description}}
{{#bs-button type="primary" action="submitForm" class="pull-right"}}