Skip to content

Commit

Permalink
feat: make addon configurable via config service (#269)
Browse files Browse the repository at this point in the history
* feat: add option "emailAsUsername"

* feat: add config option to hide "additional" user fields

* feat: add option to hide entries in main nav

* feat: add config option for optional user fields

* fix: make scope description optional
  • Loading branch information
czosel authored Aug 31, 2021
1 parent e002d85 commit 3a56283
Show file tree
Hide file tree
Showing 18 changed files with 279 additions and 107 deletions.
48 changes: 48 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,54 @@ export default class App extends Application {
```

## Configuration

### Emeis options

Basic configuration of ember-emeis can be done via the `emeis-options` service. To generate it, run `ember g service emeis-options` and add it to the dependencies in `app/app.js`:

```js
export default class App extends Application {
// ...

this.engines = {
emberEmeis: {
dependencies: {
services: ["store", "intl", "notification", "router", "emeis-options"],
},
},
};
}
});
```

The config service supports the following options:

```js
import Service from "@ember/service";

export default class EmeisOptionsService extends Service {
// number of items in list views
pageSize = 10;

// hide "username" field
emailAsUsername = false;

// show only a subset of the "additional" fields on the user model
additionalUserFields = {
"phone": "required",
"language": "required",
"address": "optional",
"city": "optional",
"zip": "optional"
];

// show only a subset of the main navigation entries
navigationEntries = ["users", "scopes"];
}
```
### Emeis store
If you need to customize your store service passed to emeis, use:
`ember g emeis-store <your_name>`
Expand Down
6 changes: 2 additions & 4 deletions addon/components/data-table.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { getOwner } from "@ember/application";
import { assert } from "@ember/debug";
import { action } from "@ember/object";
import { inject as service } from "@ember/service";
Expand All @@ -9,6 +8,7 @@ import { task, lastValue } from "ember-concurrency";
export default class DataTableComponent extends Component {
@service store;
@service router;
@service emeisOptions;

@tracked numPages;
@tracked internalSearch;
Expand Down Expand Up @@ -62,12 +62,10 @@ export default class DataTableComponent extends Component {
typeof this.args.modelName === "string"
);

const ENV = getOwner(this).resolveRegistration("config:environment");

const options = {
page: {
number: this.page,
size: ENV["ember-emeis"].pageSize,
size: this.emeisOptions.pageSize,
},
filter: { search: this.search, ...(this.args.filter || {}) },
include: this.args.include || "",
Expand Down
12 changes: 7 additions & 5 deletions addon/components/nav/item.hbs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<li class="uk-child-width-1-1 {{if this.isActive 'uk-active'}}" ...attributes>
<LinkTo @route={{@route}}>
{{yield}}
</LinkTo>
</li>
{{#if this.isVisible}}
<li class="uk-child-width-1-1 {{if this.isActive 'uk-active'}}" ...attributes>
<LinkTo @route={{@route}}>
{{yield}}
</LinkTo>
</li>
{{/if}}
8 changes: 8 additions & 0 deletions addon/components/nav/item.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,16 @@ import Component from "@glimmer/component";

export default class NavItemComponent extends Component {
@service router;
@service emeisOptions;

get isActive() {
return this.router.currentRoute.name.includes(this.args.route);
}

get isVisible() {
return (
!this.emeisOptions.navigationEntries ||
this.emeisOptions.navigationEntries.includes(this.args.route)
);
}
}
41 changes: 35 additions & 6 deletions addon/controllers/users/edit/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,51 @@ import Controller from "@ember/controller";
import { action } from "@ember/object";
import { inject as service } from "@ember/service";

const ALL_ADDITIONAL_FIELDS = ["phone", "language", "address", "city", "zip"];

export default class UsersEditIndexController extends Controller {
@service intl;
@service emeisOptions;

@action
updateModel(model, formElements) {
model.username = formElements.username.value;
model.firstName = formElements.firstName.value;
model.lastName = formElements.lastName.value;
model.email = formElements.email.value;
model.phone = formElements.phone.value;
model.language = formElements.language.selectedOptions[0].value;
model.address = formElements.address.value;
model.city = formElements.city.value;
model.zip = formElements.zip.value;
model.isActive = formElements.isActive.checked;

// additional fields might not be present
model.phone = formElements.phone?.value;
model.language = formElements.language?.selectedOptions[0].value;
model.address = formElements.address?.value;
model.city = formElements.city?.value;
model.zip = formElements.zip?.value;

model.username = this.emailAsUsername
? formElements.email.value
: formElements.username.value;

return model;
}

get emailAsUsername() {
return this.emeisOptions.emailAsUsername;
}

get visibleFields() {
if (!this.emeisOptions.additionalUserFields) {
return ALL_ADDITIONAL_FIELDS;
}

return Object.keys(this.emeisOptions.additionalUserFields);
}

get requiredFields() {
if (!this.emeisOptions.additionalUserFields) {
return ALL_ADDITIONAL_FIELDS;
}
return Object.entries(this.emeisOptions.additionalUserFields, {})
.filter(([, value]) => value === "required")
.map(([key]) => key);
}
}
10 changes: 9 additions & 1 deletion addon/controllers/users/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
import { inject as service } from "@ember/service";

import PaginationController from "ember-emeis/-private/controllers/pagination";

export default class UsersIndexController extends PaginationController {}
export default class UsersIndexController extends PaginationController {
@service emeisOptions;

get emailAsUsername() {
return this.emeisOptions.emailAsUsername;
}
}
2 changes: 1 addition & 1 deletion addon/engine.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export default class EmberEmeisEngine extends Engine {
Resolver = Resolver;

dependencies = {
services: ["store", "intl", "notification", "router"],
services: ["store", "intl", "notification", "router", "emeis-options"],
};
}

Expand Down
3 changes: 3 additions & 0 deletions addon/services/emeis-options.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import Service from "@ember/service";

export default class EmeisOptionsService extends Service {}
1 change: 0 additions & 1 deletion addon/templates/scopes/edit.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
name="description"
placeholder="{{t "emeis.scopes.headings.description"}}..."
value={{@model.description}}
required
></textarea>
</EditForm::Element>

Expand Down
145 changes: 80 additions & 65 deletions addon/templates/users/edit/index.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,18 @@
@noDelete={{true}}
@listViewRouteName="users.index"
>
<EditForm::Element @label={{t "emeis.users.headings.username"}}>
<input
class="uk-input"
type="text"
name="username"
placeholder="{{t "emeis.users.headings.username"}}..."
required
value={{@model.username}}
/>
</EditForm::Element>
{{#unless this.emailAsUsername}}
<EditForm::Element @label={{t "emeis.users.headings.username"}}>
<input
class="uk-input"
type="text"
name="username"
placeholder="{{t "emeis.users.headings.username"}}..."
required
value={{@model.username}}
/>
</EditForm::Element>
{{/unless}}

<EditForm::Element @label={{t "emeis.users.headings.firstName"}}>
<input
Expand Down Expand Up @@ -48,67 +50,80 @@
/>
</EditForm::Element>

<EditForm::Element @label={{t "emeis.users.headings.phone"}}>
<input
class="uk-input"
type="tel"
name="phone"
placeholder="{{t "emeis.users.headings.phone"}}..."
required
pattern="^[0-9()\-\s]+$"
value={{@model.phone}}
/>
{{#if (includes "phone" this.visibleFields)}}
<EditForm::Element @label={{t "emeis.users.headings.phone"}}>
<input
class="uk-input"
type="tel"
name="phone"
placeholder="{{t "emeis.users.headings.phone"}}..."
required={{includes "phone" this.requiredFields}}
pattern="^[0-9()\-\s]+$"
value={{@model.phone}}
/>

<span class="uk-text-meta">
{{t "emeis.form.phone-hint"}}
</span>
</EditForm::Element>
<span class="uk-text-meta">
{{t "emeis.form.phone-hint"}}
</span>
</EditForm::Element>
{{/if}}

<EditForm::Element @label={{t "emeis.users.headings.language"}}>
<select class="uk-select uk-text-uppercase" required name="language">
<option value="" class="uk-text-capitalize">
{{t "emeis.users.headings.language"}}...
</option>
{{#each this.intl.locales as |language|}}
<option value={{language}} selected={{eq language @model.language}}>
{{language}}
{{#if (includes "language" this.visibleFields)}}
<EditForm::Element @label={{t "emeis.users.headings.language"}}>
<select
class="uk-select uk-text-uppercase"
required={{includes "language" this.requiredFields}}
name="language">
<option value="" class="uk-text-capitalize">
{{t "emeis.users.headings.language"}}...
</option>
{{/each}}
</select>
</EditForm::Element>
{{#each this.intl.locales as |language|}}
<option value={{language}} selected={{eq language @model.language}}>
{{language}}
</option>
{{/each}}
</select>
</EditForm::Element>
{{/if}}

<EditForm::Element @label={{t "emeis.users.headings.address"}}>
<input
class="uk-input"
type="text"
name="address"
placeholder="{{t "emeis.users.headings.address"}}..."
required
value={{@model.address}}
/>
</EditForm::Element>
{{#if (includes "address" this.visibleFields)}}
<EditForm::Element @label={{t "emeis.users.headings.address"}}>
<input
class="uk-input"
type="text"
name="address"
placeholder="{{t "emeis.users.headings.address"}}..."
required={{includes "phone" this.requiredFields}}
value={{@model.address}}
/>
</EditForm::Element>
{{/if}}

<EditForm::Element @label={{t "emeis.users.headings.city"}}>
<input
class="uk-input"
type="text"
name="city"
placeholder="{{t "emeis.users.headings.city"}}..."
required
value={{@model.city}}
/>
</EditForm::Element>
{{#if (includes "city" this.visibleFields)}}
<EditForm::Element @label={{t "emeis.users.headings.city"}}>
<input
class="uk-input"
type="text"
name="city"
placeholder="{{t "emeis.users.headings.city"}}..."
required={{includes "city" this.requiredFields}}
value={{@model.city}}
/>
</EditForm::Element>
{{/if}}

<EditForm::Element @label={{t "emeis.users.headings.zip"}}>
<input
class="uk-input"
type="number"
name="zip"
placeholder="{{t "emeis.users.headings.zip"}}..."
required
value={{@model.zip}}
/>
</EditForm::Element>
{{#if (includes "zip" this.visibleFields)}}
<EditForm::Element @label={{t "emeis.users.headings.zip"}}>
<input
class="uk-input"
type="number"
name="zip"
placeholder="{{t "emeis.users.headings.zip"}}..."
required={{includes "zip" this.requiredFields}}
value={{@model.zip}}
/>
</EditForm::Element>
{{/if}}

<EditForm::Element @label={{t "emeis.users.headings.isActive"}}>
<input
Expand Down
Loading

0 comments on commit 3a56283

Please sign in to comment.