refactor form steps implementation (#345)
This commit is contained in:
parent
9dae6eda0a
commit
9983f76189
3 changed files with 99 additions and 83 deletions
|
@ -1,93 +1,54 @@
|
|||
import { inject as service } from '@ember/service';
|
||||
import EmberObject, { computed, getProperties } from '@ember/object';
|
||||
import { action, computed } from '@ember/object';
|
||||
import Controller from '@ember/controller';
|
||||
import { getOwner } from '@ember/application';
|
||||
|
||||
const FormStep = EmberObject.extend({
|
||||
router: service(),
|
||||
|
||||
disabled: computed('requiredState', 'visited', function() {
|
||||
let { visited, requiredState } = this;
|
||||
return !visited || requiredState === false;
|
||||
}),
|
||||
hidden: false,
|
||||
label: null,
|
||||
route: null,
|
||||
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() {
|
||||
let owner = getOwner(this);
|
||||
canEnterMetaStep: computed('model.pollType', 'visitedSteps', function() {
|
||||
return this.visitedSteps.has('meta') && this.model.pollType;
|
||||
}),
|
||||
|
||||
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');
|
||||
canEnterOptionsStep: computed('model.title', 'visitedSteps', function() {
|
||||
let { title } = this.model;
|
||||
return this.visitedSteps.has('options') &&
|
||||
typeof title === 'string' && title.length >= 2;
|
||||
}),
|
||||
|
||||
let extendDefinition = getProperties(definition, ...computedProperties)
|
||||
let createDefinition = Object.assign({ model: this.model }, getProperties(definition, ...values));
|
||||
canEnterOptionsDatetimeStep: computed('model.options.[]', 'visitedSteps', function() {
|
||||
return this.visitedSteps.has('options-datetime') && this.model.options.length >= 1;
|
||||
}),
|
||||
|
||||
if (index === 0) {
|
||||
createDefinition.visited = true;
|
||||
canEnterSettingsStep: computed('model.options.[]', 'visitedSteps', function() {
|
||||
return this.visitedSteps.has('settings') && this.model.options.length >= 1;
|
||||
}),
|
||||
|
||||
isFindADate: computed('model.pollType', function() {
|
||||
return this.model.pollType === 'FindADate';
|
||||
}),
|
||||
|
||||
updateVisitedSteps: action(function() {
|
||||
let { currentRouteName } = this.router;
|
||||
|
||||
// currentRouteName might not be defined in some edge cases
|
||||
if (!currentRouteName) {
|
||||
return;
|
||||
}
|
||||
|
||||
return FormStep.extend(extendDefinition).create(owner.ownerInjection(), createDefinition);
|
||||
});
|
||||
})
|
||||
let step = currentRouteName.split('.').pop();
|
||||
this.visitedSteps.add(step);
|
||||
|
||||
// as visitedSteps is a Set must notify about changes manually
|
||||
this.notifyPropertyChange('visitedSteps');
|
||||
}),
|
||||
|
||||
listenForStepChanges() {
|
||||
this.set('visitedSteps', new Set());
|
||||
|
||||
this.router.on('routeDidChange', this.updateVisitedSteps);
|
||||
},
|
||||
|
||||
clearListenerForStepChanges() {
|
||||
this.router.off('routeDidChange', this.updateVisitedSteps);
|
||||
},
|
||||
});
|
||||
|
|
|
@ -30,5 +30,15 @@ export default Route.extend({
|
|||
expirationDate: moment().add(3, 'month').toISOString(),
|
||||
version: config.APP.version,
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
activate() {
|
||||
let controller = this.controllerFor(this.routeName);
|
||||
controller.listenForStepChanges();
|
||||
},
|
||||
|
||||
deactivate() {
|
||||
let controller = this.controllerFor(this.routeName);
|
||||
controller.clearListenerForStepChanges();
|
||||
},
|
||||
});
|
||||
|
|
|
@ -13,6 +13,51 @@
|
|||
</BsButton>
|
||||
{{/unless}}
|
||||
{{/each}}
|
||||
<BsButton
|
||||
@onClick={{transition-to "create.index"}}
|
||||
@type={{if (eq router.currentRouteName "create.index") "primary is-active" "default"}}
|
||||
class="cr-steps-top-nav__button"
|
||||
>
|
||||
{{t "create.formStep.type"}}
|
||||
</BsButton>
|
||||
<BsButton
|
||||
@onClick={{transition-to "create.meta"}}
|
||||
@type={{if (eq router.currentRouteName "create.meta") "primary is-active" "default"}}
|
||||
disabled={{not this.canEnterMetaStep}}
|
||||
class="cr-steps-top-nav__button"
|
||||
>
|
||||
{{t "create.formStep.meta"}}
|
||||
</BsButton>
|
||||
<BsButton
|
||||
@onClick={{transition-to "create.options"}}
|
||||
@type={{if (eq router.currentRouteName "create.options") "primary is-active" "default"}}
|
||||
disabled={{not this.canEnterOptionsStep}}
|
||||
class="cr-steps-top-nav__button"
|
||||
>
|
||||
{{#if this.isFindADate}}
|
||||
{{t "create.formStep.options.days"}}
|
||||
{{else}}
|
||||
{{t "create.formStep.options.text"}}
|
||||
{{/if}}
|
||||
</BsButton>
|
||||
{{#if this.isFindADate}}
|
||||
<BsButton
|
||||
@onClick={{transition-to "create.options-datetime"}}
|
||||
@type={{if (eq router.currentRouteName "create.options-datetime") "primary is-active" "default"}}
|
||||
disabled={{not this.canEnterOptionsDatetimeStep}}
|
||||
class="cr-steps-top-nav__button"
|
||||
>
|
||||
{{t "create.formStep.options-datetime"}}
|
||||
</BsButton>
|
||||
{{/if}}
|
||||
<BsButton
|
||||
@onClick={{transition-to "create.settings"}}
|
||||
@type={{if (eq router.currentRouteName "create.settings") "primary is-active" "default"}}
|
||||
disabled={{not this.canEnterSettingsStep}}
|
||||
class="cr-steps-top-nav__button"
|
||||
>
|
||||
{{t "create.formStep.settings"}}
|
||||
</BsButton>
|
||||
</BsButtonGroup>
|
||||
|
||||
{{outlet}}
|
||||
|
|
Loading…
Reference in a new issue