refactor create/options controller to component (#815)

This commit is contained in:
Jeldrik Hanschke 2023-12-17 23:10:57 +01:00 committed by GitHub
parent e3935e521f
commit f9f0c365e8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 50 additions and 80 deletions

View file

@ -3,11 +3,11 @@
@formLayout="horizontal"
@model={{this.formData}}
@onInvalid={{(scroll-first-invalid-element-into-view-port)}}
@onSubmit={{this.handleSubmit}}
@onSubmit={{this.submit}}
novalidate
as |form|
>
{{#if @isMakeAPoll}}
{{#if (eq @poll.pollType "MakeAPoll")}}
<CreateOptionsText
@options={{this.formData.options}}
@addOption={{this.formData.addOption}}

View file

@ -5,6 +5,7 @@ import { TrackedArray, TrackedSet } from 'tracked-built-ins';
import IntlMessage from '../utils/intl-message';
import { tracked } from '@glimmer/tracking';
import type RouterService from '@ember/routing/router-service';
import type { CreateOptionsRouteModel } from '../routes/create/options';
import type Transition from '@ember/routing/transition';
export class FormDataOption {
@ -96,11 +97,7 @@ class FormData {
export interface CreateOptionsSignature {
Args: {
isMakeAPoll: boolean;
options: TrackedSet<string>;
onNextPage: () => void;
onPrevPage: () => void;
updateOptions: (options: { value: string }[]) => void;
poll: CreateOptionsRouteModel;
};
}
@ -108,31 +105,58 @@ export default class CreateOptions extends Component<CreateOptionsSignature> {
@service declare router: RouterService;
formData = new FormData(
{ options: this.args.options },
{ defaultOptionCount: this.args.isMakeAPoll ? 2 : 0 },
{ options: this.options },
{ defaultOptionCount: this.args.poll.pollType === 'MakeAPoll' ? 2 : 0 },
);
get options() {
const { poll } = this.args;
const { dateOptions, freetextOptions, pollType } = poll;
return pollType === 'FindADate' ? dateOptions : freetextOptions;
}
@action
previousPage() {
this.args.onPrevPage();
this.router.transitionTo('create.meta');
}
@action
handleSubmit() {
this.args.onNextPage();
submit() {
const { pollType } = this.args.poll;
if (pollType === 'FindADate') {
this.router.transitionTo('create.options-datetime');
} else {
this.router.transitionTo('create.settings');
}
}
@action
handleTransition(transition: Transition) {
@action handleTransition(transition: Transition) {
if (transition.from?.name === 'create.options') {
this.args.updateOptions(this.formData.options);
this.updatePoll();
this.router.off('routeWillChange', this.handleTransition);
}
}
updatePoll() {
const { poll } = this.args;
const { pollType } = poll;
const { options } = this.formData;
const pollOptions = options.map(({ value }) => value);
if (pollType === 'FindADate') {
poll.dateOptions = new TrackedSet(pollOptions.sort());
} else {
poll.freetextOptions = new TrackedSet(pollOptions);
}
}
constructor(owner: unknown, args: CreateOptionsSignature['Args']) {
super(owner, args);
// Cannot use a destructor because that one runs _after_ the other component
// rendered by the next route is initialized.
this.router.on('routeWillChange', this.handleTransition);
}
}

View file

@ -1,40 +0,0 @@
import Controller from '@ember/controller';
import { inject as service } from '@ember/service';
import { action } from '@ember/object';
import { TrackedSet } from 'tracked-built-ins';
import type RouterService from '@ember/routing/router-service';
import type { CreateOptionsRouteModel } from 'croodle/routes/create/options';
export default class CreateOptionsController extends Controller {
@service declare router: RouterService;
declare model: CreateOptionsRouteModel;
@action
nextPage() {
const { pollType } = this.model;
if (pollType === 'FindADate') {
this.router.transitionTo('create.options-datetime');
} else {
this.router.transitionTo('create.settings');
}
}
@action
previousPage() {
this.router.transitionTo('create.meta');
}
@action
updateOptions(newOptions: { value: string }[]) {
const { pollType } = this.model;
const options = newOptions.map(({ value }) => value);
if (pollType === 'FindADate') {
this.model.dateOptions = new TrackedSet(options.sort());
} else {
this.model.freetextOptions = new TrackedSet(options);
}
}
}

View file

@ -1,11 +1 @@
<CreateOptions
@isMakeAPoll={{eq @model.pollType "MakeAPoll"}}
@options={{if
(eq @model.pollType "FindADate")
@model.dateOptions
@model.freetextOptions
}}
@onPrevPage={{this.previousPage}}
@onNextPage={{this.nextPage}}
@updateOptions={{this.updateOptions}}
/>
<CreateOptions @poll={{@model}} />

View file

@ -14,14 +14,12 @@ module('Integration | Component | create options', function (hooks) {
});
test('shows validation errors if options are not unique (makeAPoll)', async function (assert) {
this.set('options', new TrackedSet());
this.set('poll', {
pollType: 'MakeAPoll',
freetextOptions: new TrackedSet(),
});
await render(hbs`<CreateOptions
@options={{this.options}}
@isDateTime={{false}}
@isFindADate={{false}}
@isMakeAPoll={{true}}
/>`);
await render(hbs`<CreateOptions @poll={{this.poll}} />`);
assert
.dom('.form-group')
@ -51,14 +49,12 @@ module('Integration | Component | create options', function (hooks) {
});
test('shows validation errors if option is empty (makeAPoll)', async function (assert) {
this.set('options', new TrackedSet());
this.set('poll', {
pollType: 'MakeAPoll',
freetextOptions: new TrackedSet(),
});
await render(hbs`<CreateOptions
@options={{this.options}}
@isDateTime={{false}}
@isFindADate={{false}}
@isMakeAPoll={{true}}
/>`);
await render(hbs`<CreateOptions @poll={{this.poll}} />`);
assert.dom('.form-group.has-error').doesNotExist();