Skip to content

Commit

Permalink
feat(emeisOptions): passing options as a function
Browse files Browse the repository at this point in the history
- this enable to pass options for meta-fields of type choice as static list or as a function
  • Loading branch information
derrabauke committed Mar 8, 2022
1 parent cf6395b commit f171980
Show file tree
Hide file tree
Showing 15 changed files with 357 additions and 317 deletions.
12 changes: 11 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,12 @@ export default class EmeisOptionsService extends Service {
{
slug: "test-input-2",
label: "some.translation.key",
options: [ // insert a static list of options (value, label), or a (async) function which resolves to a list of options
{
value: "option-1",
label: "Option one"
}
],
type: "choice",
visible: () => true,
readOnly: false
Expand All @@ -134,12 +140,16 @@ export default class EmeisOptionsService extends Service {
_Watch out_ - the translation key has to be present in your local translation files.
There are special options available for `type` and `visible` properties.
There are special options available for `options`, `type` and `visible` properties.
#### **type** - meta field
Defines the type of the output component and can either be a _text_ or a _choice_.
#### **options** - meta field
In combination with `type:"choice"` the options can be a list of options (`{value, label}`) or a (async) function which resolves to a list of options.
#### **visible** & **readOnly** meta field
Accepts a boolean value for static visibility or a function which evaluates to a boolean value. Submitted functions will evaluate live while rendering.
Expand Down
32 changes: 32 additions & 0 deletions addon/components/meta-field.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{{#if this.visible}}
<EditForm::Element @label={{optional-translate @field.label}}>
{{#if (eq @field.type "choice")}}
{{#if this.options.isRunning}}
<UkSpinner @ratio="1" />
{{else}}
<PowerSelect
@disabled={{this.disabled}}
@options={{this.options.value}}
@selected={{find-by "value" (get @model.metainfo @field.slug) this.options.value}}
@onChange={{fn this.updateMetaField @field @model}}
@placeholder={{t @field.label}}
@allowClear={{true}}
@renderInPlace={{true}}
as |option|
>
{{optional-translate option.label}}
</PowerSelect>
{{/if}}
{{/if}}
{{#if (eq @field.type "text")}}
<input
data-test-meta-field-text={{@field.slug}}
class="uk-input"
type="text"
value={{get @model.metainfo @field.slug}}
disabled={{this.disabled}}
{{on "input" (fn this.updateMetaField @field @model)}}
>
{{/if}}
</EditForm::Element>
{{/if}}
50 changes: 50 additions & 0 deletions addon/components/meta-field.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { assert } from "@ember/debug";
import { action } from "@ember/object";
import { inject as service } from "@ember/service";
import Component from "@glimmer/component";
import { task } from "ember-concurrency";
import { useTask } from "ember-resources";

export default class MetaFieldComponent extends Component {
@service intl;

constructor(...args) {
super(...args);

assert("Must pass a valid field argument", this.args.field);
assert("Must pass a valid model argument", this.args.model);
}

evaluateProperty(expression) {
if (typeof expression === "boolean") return expression;
if (typeof expression === "function") return expression(this.args.model);
if (typeof expression === "string") return expression === "true";
return false;
}

get visible() {
return this.evaluateProperty(this.args.field.visible);
}

get disabled() {
return this.evaluateProperty(this.args.field.readOnly);
}

options = useTask(this, this.fetchOptions, () => [this.args.field.options]);

@task
*fetchOptions(options) {
// options may be a (asnyc) function or a complex property
if (typeof options !== "function") {
return options;
}
return yield options();
}

@action
updateMetaField(field, model, optionOrEvent) {
const value = optionOrEvent?.target?.value ?? optionOrEvent?.value;
model.metainfo = { ...model.metainfo, [field.slug]: value };
model.notifyPropertyChange("metainfo");
}
}
30 changes: 0 additions & 30 deletions addon/components/meta-fields.hbs

This file was deleted.

14 changes: 0 additions & 14 deletions addon/components/meta-fields.js

This file was deleted.

8 changes: 0 additions & 8 deletions addon/helpers/eval-meta.js

This file was deleted.

8 changes: 4 additions & 4 deletions addon/templates/scopes/edit.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,10 @@
</RelationshipSelect>
</EditForm::Element>

<MetaFields
@model={{@model}}
@fields={{this.metaFields}}
/>
{{#each this.metaFields as |field|}}
<MetaField @field={{field}} @model={{@model}} />
{{/each}}

</EditForm>
</div>
<div class="uk-width-1-2@xl">
Expand Down
7 changes: 3 additions & 4 deletions addon/templates/users/edit.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -131,10 +131,9 @@
</EditForm::Element>
{{/if}}

<MetaFields
@model={{@model}}
@fields={{this.metaFields}}
/>
{{#each this.metaFields as |field|}}
<MetaField @field={{field}} @model={{@model}} />
{{/each}}

<EditForm::Element @label={{t "emeis.users.headings.isActive"}}>
<input
Expand Down
1 change: 1 addition & 0 deletions app/components/meta-field.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from "ember-emeis/components/meta-field";
1 change: 0 additions & 1 deletion app/components/meta-fields.js

This file was deleted.

1 change: 0 additions & 1 deletion app/helpers/eval-meta.js

This file was deleted.

49 changes: 35 additions & 14 deletions tests/dummy/app/services/emeis-options.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import Service from "@ember/service";
import { timeout } from "ember-concurrency";

import TestButtonComponent from "../components/dummy-button/dummy-button"; // template and component file must have the same name (if not template only)

Expand All @@ -25,26 +26,46 @@ export default class EmeisOptionsService extends Service {
visible: true,
readOnly: false,
},
// {
// slug: "user-meta-example-2",
// label: "emeis.options.meta.user.example",
// type: "choice", // initially supported: "text", "choice"
// options: [
// {
// value: "Option 1",
// label: "Option One",
// },
// {
// value: "Option 2",
// label: "Option Two",
// },
// ],
// visible: true,
// readOnly: false,
// },
],
scope: [
{
slug: "meta-example",
label: "emeis.options.meta.scope.meta-example",
type: "choice", // initially supported: "text", "choice"
options: [
{
value: "Option 1",
label: "emeis.options.meta.scope.options.label-1", // again a ember-intl translation key
},
{
value: "Option 2",
label: "emeis.options.meta.scope.options.label-2",
},
{
value: "Option 3",
label: "emeis.options.meta.scope.options.label-3",
},
],
options: async () => {
await timeout(2000);
return [
{
value: "Option 1",
label: "emeis.options.meta.scope.options.label-1", // again a ember-intl translation key
},
{
value: "Option 2",
label: "emeis.options.meta.scope.options.label-2",
},
{
value: "Option 3",
label: "emeis.options.meta.scope.options.label-3",
},
];
},
visible: () => true, // boolean or function which evaluates to a boolean value
readOnly: false,
},
Expand Down
Loading

0 comments on commit f171980

Please sign in to comment.