Ember AddOns
Before adding a new requirement to the project, check Django Requirements
ember-cli-app-version
Warning
We are not using this add-on at the moment. For more information, see ember-cli-new-version (below)…
Helper that allows you to show your current app version: https://github.com/ember-cli/ember-cli-app-version
Very easy to use e.g:
<p class="text-center text-gray-500 pt-10">
Version
{{app-version versionOnly=true}}
</p>
FileSaver
Warning
14/02/2023, I couldn’t get ember-cli-file-saver
working with
the most recent version of Ember.
From https://github.com/eligrey/FileSaver.js/:
pnpm install -D file-saver
import { saveAs } from 'file-saver';
saveAs(blob, "pretty-image.png");
ember-cli-flash
Simple, highly configurable flash messages, https://github.com/poteto/ember-cli-flash
ember-cli-new-version
We were installing ember-cli-app-version
alongside
ember-cli-new-version
but for now we are using the kb.py
script to
update config/environment.js
and generate dist/VERSION.txt
:
We converted
ember-cli-new-version
to be a V2 addon, so theindex.js
file in the root of the project is not being called by the build process to generatedist/VERSION.txt
For more information on using kb.py
:
To update the
config/environment.js
file, see Patch, install and publish.To create the
dist/VERSION.txt
file, run``python ../kb.py –version-txt`` after running the build script (ember bui;d
)
Development / Testing
To test locally:
# generate a ``VERSION.txt`` file
python ../kb.py --version
# edit the file, so it as a different version number to ``package.json``
vim dist/VERSION.txt
# move it to the test folder (don't forget to delete before building)
mv dist/VERSION.txt public/assets/
Tip
Example contents for VERSION.txt
, 0.1.59
In config/environment.js
, set the versionFileName
and enableInDev
:
newVersion: {
currentVersion: null,
versionFileName: 'assets/VERSION.txt',
enableInDev: true,
ember-cli-sass
Update ember-cli-build.js
and add sassOptions
:
let app = new EmberApp(defaults, {
// Add options here
sassOptions: {
extension: 'scss'
}
});
Note
To get started with sass
in an Ember project,
I renamed app/styles/app.css
to app/styles/app.scss
and
appended all my css
files into app.scss
.
For more information, see sass.
ember-concurrency
Allows you to write concise, worry-free, cancelable, restartable, asynchronous tasks. http://ember-concurrency.com
ember-cp-validations
To validate models, http://offirgolan.github.io/ember-cp-validations/
ember-css-transitions
To convert Tailwind UI Entering and Leaving transitions to
a css-transition
:
Tailwind UI css-transition
------------- ----------------
Entering: enterActiveClass
From: enterClass
To: enterToClass
Leaving: leaveActiveClass
From: leaveClass
To: leaveToClass
For more information, see the documentation for ember-css-transitions and Tailwind UI Dropdowns with Ember
ember-django-adapter
We use the https://github.com/dustinfarris/ember-django-adapter to connect to Django REST Framework.
Note
We do not use https://github.com/django-json-api/django-rest-framework-json-api
ember-file-upload
Note
I couldn’t get ember-file-upload working, so ended up using https://github.com/knownasilya/ember-plupload (I think Tim has ember-file-upload working).
Here is some sample code plan-detail.hbs
ember-font-awesome
To use the Font Awesome icons.
ember-infinity
We didn’t get on too well with ember-infinity
and concurrency, so this
section has been removed for now.
Information on pagination was deleted from here. Revised notes can be found at Pagination (JSON API).
ember-intl
Configure in the application route, app/routes/application.js
:
export default class ApplicationRoute extends Route {
@service intl
beforeModel(transition) {
this.intl.setLocale(["en-uk"])
// ...
}
Tip
Both staticModifiers: true
and staticComponents: true
in (ember-cli-build.js
) both need to be set to true
.
Usage:
{{format-date
ticket.created
day="numeric"
month="numeric"
year="numeric"
}}
Date and time:
{{format-date
ticket.created
year="numeric"
month="numeric"
day="numeric"
hour="numeric"
minute="numeric"
}}
Other options:
month="short"
weekday="long"
Date formats:
ember-modal-dialog
I have started using this addon for a simple confirmation dialog.
For source code see:
ember-moment
Note
14/08/2021, We are going to try ember-intl instead… (ref https://github.com/stefanpenner/ember-moment/issues/340)
Tip
To set-up a date
field in an Ember model,
see Date / Time.
I had to install ember-cli-moment-shim
as well as ember-moment
:
yarn add ember-moment ember-cli-moment-shim
e.g.
ember-promise-modals
We haven’t used this yet, but it looks great: https://simplabs.github.io/ember-promise-modals/
For more information, see, Managing modal dialogs in Ember.js with Promises, https://simplabs.com/blog/2021/08/26/managing-modals-in-ember/
ember-route-action-helper
Recommended by https://twitter.com/EmmaDelescolle to bubble closure actions in routes.
ember-simple-auth
For authentication, we use https://github.com/simplabs/ember-simple-auth with Django REST framework Token Authentication
This video explains how to setup and use Ember Simple Auth…
Route
Check a user is authenticated:
import { inject as service } from "@ember/service"
export default class MyRoute extends Route {
@service session
beforeModel(transition) {
// if not authenticated, transition to 'authenticate'
this.session.requireAuthentication(transition, "authenticate")
}
Tip
PJK 24/11/2021, Changed the transition
to authenticate
rather
than login
. Not sure if this is correct or not?!
Controller (login
)
import { inject as service } from "@ember/service"
export default class LoginController extends Controller {
@service session
@action
async login(event) {
event.preventDefault()
try {
await this.session.authenticate('authenticator:token', this.username, this.password)
} catch(error) {
...
Tip
authenticator:token
is the name of the authenticator we want to
use. this.username
and this.password
are passed on to the
authenticator.
Authenticator (write our own)
// app/authenticators/token.js
import Base from 'ember-simple-auth/authenticators/base'
export default Base.extend({
async authenticate(username, password) {
let response = await fetch('/api/token', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
username, password
})
})
if (response.ok) {
return response.json()
} else {
let error = await response.text()
throw new Error(error)
}
})
async restore(data) {
let { token } = data
if (token) {
return data
} else {
throw 'no valid session data'
}
}
Tip
The authenticate
method automatically stores the token
in the session.
Session Store
// app/session-stores/application.js
import CookieStore from 'ember-simple-auth/session-stores/cookie'
export default class ApplicationSessionStore extends CookieStore {
}
Adapter
import { inject as service } from "@ember/service"
export default class ApplicationAdapter extends JSONAPIAdapter {
@service session
@computed('session.data.authenticated.token')
get headers() {
let headers = {}
if (this.session.isAuthenticated) {
headers['token'] = this.session.data.authenticated.token
}
return headers
}
}
Route (login
)
The login
route should not be accessible to a logged in user:
import { inject as service } from "@ember/service"
export default class LoginRoute extends Route {
@service session
beforeModel(transition) {
this.session.prohibitAuthentication("index")
}
Note
The user will be taken to the index
route if they browse to the
login
route (and are already logged in).
Components
{{#if session.isAuthenticated}}
<button type="button" {{on 'click' this.logout}}>
import { inject as service } from "@ember/service"
export default class NavComponent extends Component {
@service session
@action
logout()
this.session.invalidate()
Current Contact
Warning
The following code doesn’t get called if installed into an ember add on, so copy into the project!
Use the following code in front/app/services/session.js
:
import { inject as service } from "@ember/service"
import BaseSessionService from "ember-simple-auth/services/session"
export default class SessionService extends BaseSessionService {
@service currentContact
async handleAuthentication() {
super.handleAuthentication(...arguments)
try {
await this.currentContact.load()
} catch (err) {
await this.invalidate()
}
}
}
FileSaver
06/09/2021, I am using FileSaver.js instead of ember-cli-file-saver
:
npm install ember-auto-import
npm install file-saver
For more details, see:
<Report::Button
@reportSlug={{"contact-tickets"}}
@reportParameters={{this.reportParameters}}
/>