diff --git a/app/components/create-options-text.js b/app/components/create-options-text.js index 2f50e17..0ad08d8 100644 --- a/app/components/create-options-text.js +++ b/app/components/create-options-text.js @@ -1,6 +1,6 @@ import { inject as service } from '@ember/service'; import Component from '@ember/component'; -import { observer } from '@ember/object'; +import { next } from '@ember/runloop'; export default Component.extend({ actions: { @@ -19,16 +19,26 @@ export default Component.extend({ } }, - enforceMinimalOptionsAmount: observer('options', 'isMakeAPoll', function() { - if (this.get('options.length') < 2) { - let options = this.options; - for (let missingOptions = 2 - this.get('options.length'); missingOptions > 0; missingOptions--) { - options.pushObject( - this.store.createFragment('option') - ); - } + enforceMinimalOptionsAmount() { + let options = this.options; + + while (options.length < 2) { + options.pushObject( + this.store.createFragment('option') + ); } - }).on('init'), + }, store: service('store'), + + init() { + this._super(...arguments); + + // need to delay pushing fragments into options array to prevent + // > You modified "disabled" twice on <(unknown):ember330> in a single render. + // error. + next(() => { + this.enforceMinimalOptionsAmount(); + }); + } }); diff --git a/app/controllers/create.js b/app/controllers/create.js index 6234deb..13fcb93 100644 --- a/app/controllers/create.js +++ b/app/controllers/create.js @@ -1,67 +1,94 @@ import { inject as service } from '@ember/service'; -import { readOnly } from '@ember/object/computed'; -import EmberObject, { computed, observer } from '@ember/object'; +import EmberObject, { computed } from '@ember/object'; import Controller from '@ember/controller'; import { getOwner } from '@ember/application'; +import { getProperties } from '@ember/object'; -const formStepObject = EmberObject.extend({ - active: computed('routing.currentRouteName', function() { - const currentRouteName = this.get('routing.currentRouteName'); - return currentRouteName === this.route; +const FormStep = EmberObject.extend({ + router: service(), + + disabled: computed('requiredState', 'visited', function() { + let { visited, requiredState } = this; + return !visited || requiredState === false; }), - disabled: true, hidden: false, label: null, route: null, - routing: service('-routing'), - updateDisabledState: observer('active', function() { - if (this.active) { - this.set('disabled', false); - } - }).on('init'), + visited: false, + + init() { + this._super(...arguments); + + let setVisited = () => { + if (this.router.currentRouteName === this.route) { + this.set('visited', true); + } + }; + this.router.on('routeDidChange', setVisited); + } }); +const FORM_STEPS = [ + { + label: 'create.formStep.type', + route: 'create.index', + }, + { + label: 'create.formStep.meta', + requiredState: computed('model.pollType', function() { + return this.model.pollType; + }), + route: 'create.meta', + }, + { + label: computed('model.pollType', function() { + let { pollType } = this.model; + return pollType === 'FindADate' ? 'create.formStep.options.days' : 'create.formStep.options.text'; + }), + requiredState: computed('model.title', function() { + let { title } = this.model; + return typeof title === 'string' && title.length >= 2; + }), + route: 'create.options', + }, + { + hidden: computed('model.pollType', function() { + let { pollType } = this.model; + return pollType !== 'FindADate'; + }), + label: 'create.formStep.options-datetime', + requiredState: computed('model.options.length', function() { + return this.model.options.length >= 1; + }), + route: 'create.options-datetime' + }, + { + label: 'create.formStep.settings', + requiredState: computed('model.options.length', function() { + return this.model.options.length >= 1; + }), + route: 'create.settings', + }, +]; + export default Controller.extend({ + router: service(), + formSteps: computed('model', function() { - const owner = getOwner(this); - return [ - formStepObject.create(owner.ownerInjection(), { - label: 'create.formStep.type', - route: 'create.index' - }), - formStepObject.create(owner.ownerInjection(), { - label: 'create.formStep.meta', - route: 'create.meta' - }), - formStepObject.extend({ - label: computed('pollType', function() { - const pollType = this.pollType; - if (pollType === 'FindADate') { - return 'create.formStep.options.days'; - } else { - return 'create.formStep.options.text'; - } - }), - pollType: readOnly('model.pollType') - }).create(owner.ownerInjection(), { - model: this.model, - route: 'create.options' - }), - formStepObject.extend({ - hidden: computed('pollType', function() { - const pollType = this.pollType; - return pollType !== 'FindADate'; - }), - pollType: readOnly('model.pollType') - }).create(owner.ownerInjection(), { - label: 'create.formStep.options-datetime', - model: this.model, - route: 'create.options-datetime' - }), - formStepObject.create(owner.ownerInjection(), { - label: 'create.formStep.settings', - route: 'create.settings' - }) - ]; + let owner = getOwner(this); + + return FORM_STEPS.map((definition, index) => { + let computedProperties = Object.keys(definition).filter((key) => typeof definition[key] === 'function'); + let values = Object.keys(definition).filter((key) => typeof definition[key] !== 'function'); + + let extendDefinition = getProperties(definition, ...computedProperties) + let createDefinition = Object.assign({ model: this.model }, getProperties(definition, ...values)); + + if (index === 0) { + createDefinition.visited = true; + } + + return FormStep.extend(extendDefinition).create(owner.ownerInjection(), createDefinition); + }); }) }); diff --git a/app/templates/components/create-options-text.hbs b/app/templates/components/create-options-text.hbs index b32d9b2..bc7639d 100644 --- a/app/templates/components/create-options-text.hbs +++ b/app/templates/components/create-options-text.hbs @@ -10,10 +10,11 @@ >
{{#each formSteps as |formStep|}} {{#unless formStep.hidden}} - {{#bs-button - onClick=(transition-to formStep.route) - type=(if formStep.active "primary is-active" "default") - disabled=formStep.disabled - classNames="cr-steps-top-nav__button" - }} + {{t formStep.label}} - {{/bs-button}} + {{/unless}} {{/each}} -{{/bs-button-group}} + {{outlet}}