Ember ***** .. highlight:: python - :doc:`dev-ember-addons-kb` - :doc:`dev-ember-addons` - :doc:`dev-ember-auth` - :doc:`dev-ember-data` - :doc:`dev-ember-patterns` Salt ==== Ember Only ---------- If your site is purely Ember i.e. no Django, then set the ``profile`` to ``ember`` e.g: .. code-block:: yaml # sites/my.sls sites: mysite.hatherleigh.info: backup: none profile: ember ssl: True letsencrypt: True To build for production:: rm -rf dist/ node_modules/; and pnpm install; pnpm ember build --environment="production" tar -cvzf mysite-0.0.0.tar.gz dist/ To deploy:: # on my laptop scp mysite-0.0.0.tar.gz cloud-a.my.vpn:repo/release/ # on the server sudo -i -u web cd /home/web/repo/project/mysite.hatherleigh.info/ember/ tar --strip-components=1 -xzf /home/patrick/repo/release/mysite-0.0.0.tar.gz To create the certificate:: init-letsencrypt mysite.hatherleigh.info - /home/web/repo/project/mysite.hatherleigh.info/ember/ Django and Ember ---------------- If your Django site has an Ember front end, then add ``ember: True`` to your ``sites`` file: .. code-block:: yaml # sites/my.sls sites: www.hatherleigh.info: package: hatherleigh_info profile: django ember: True The default path for your Django app will be ``/back/`` and the default path for your Ember app will be ``/``. If you want to override this, then you can set the ``ember_path`` and ``django_path`` as follows: .. code-block:: yaml # sites/my.sls sites: www.hatherleigh.info: package: hatherleigh_info profile: django ember: True ember_path: front django_path: back .. tip:: To set the ``django_path`` to the default (``/``): ``django_path: /`` .. note:: Don't append or prepend a ``/`` to the ``ember_path`` or ``django_path``. The Salt state files will take care of the ``/``. If you set an ``ember_path`` (other than ``/``), set the ``rootURL`` in the ``production`` environment (``config/environment.js``): .. code-block:: javascript if (environment === "production") { ENV.rootURL = "/front/" } Installation ============ Prerequisites ------------- Using ``pnpm`` (and not ``volta``), from https://www.clearthought.co.uk/getting-started-with-pnpm/: .. code-block:: bash curl -fsSL https://get.pnpm.io/install.sh > pnpm-install.sh # view the file to make sure you're happy running it on your computer sh ./pnpm-install.sh Update ``config.fish``: .. code-block:: bash # vim ~/.config/fish/config.fish set -gx PNPM_HOME "/home/patrick/.local/share/pnpm" set -gx PATH "$PNPM_HOME" $PATH .. tip:: Change ``patrick`` to your own user name. To install command line completion: .. code-block:: bash pnpm install-completion To use node 16: .. code-block:: bash pnpm env use --global 16 To use the current LTS version of node: .. code-block:: bash pnpm env use --global lts .. Using ``volta``:: .. .. curl https://get.volta.sh | bash .. # open a new terminal .. # to install the latest LTS release (version 16 for Ember) .. volta install node@16 .. .. Install ``pnpm``:: .. .. volta install pnpm .. .. You may also need to:: .. .. volta install yarn Installing ``ember-cli`` ------------------------ :: pnpm install -g ember-cli Creating a project ------------------ Run the following commands to create a project e.g. ember-first:: # ember new ember-first --lang en # to create an embroider project ember new ember-first --lang en --embroider --skip-npm --skip-git cd ember-first pnpm install pnpm start # or... #ember serve # or... npm start Cloning an existing project --------------------------- To clone an existing project e.g. ember-first:: git clone git@gitlab.com:proj-owner/ember-first.git cd ember-first npm install bower install ember server Components ========== Input ----- The following input attributes must be passed as arguments (i.e. do prepend ``@``) to the ```` component:: @checked @type @value From https://guides.emberjs.com/release/components/built-in-components/ .. tip:: Do not use ``on "change"``, use ``on "input"`` e.g. ``{{on "input" this.updateText}}``. .. _ember-error-handling: Error Handling ============== Configuration ------------- Django REST framework exception handler (from the :doc:`app-api` app):: REST_FRAMEWORK = {"EXCEPTION_HANDLER": "api.models.custom_exception_handler"} Exceptions and Responses ------------------------ For Ember to understand and handle an exception, we need to be using the ``custom_exception_handler`` (see above). e.g. if a user does not have permission to data, then ``raise PermissionDenied`` (``from rest_framework.exceptions import PermissionDenied``) .. warning:: Do **not** return an ``HttpResponseForbidden`` response as Ember will have no idea what happened. .. tip:: For an example, search for ``PermissionDenied`` in ``work/api.py`` To catch the forbidden error code in Ember: .. code-block:: javascript try { let process = yield this.store.findRecord("process", params.workflow_id, { reload: true }) return yield process } catch (e) { if (e.errors.firstObject.status === "403") { return yield undefined } else { this.kbMessages.addError("Cannot load workflow processes", e) } } Learn ----- .. tip:: We have two projects which can be used together to explore Ember data: 1. https://gitlab.com/kb/contact/ (on the ``2292-dramatiq`` branch) 2. https://github.com/pkimber/ember-data-error Background ---------- From `Force Ember Data to reload data from backend API`_ Ember Data's default strategy for requesting data records (either ``findRecord`` or ``findAll``): - If it is not loaded, load it - If it is already loaded, don't reload it. Instead, ``backgroundReload`` it What does this mean? - ``reload`` queries for new data pre-emptively, that is, it waits until the promise with new data resolves - ``backgroundReload`` returns the local (cached) record, and then queries for new data This has a big impact on error handling because returning the local (cached) copy of a record will probably succeed (so no exception thrown). If the ``backgroundReload`` query fails, then this is happening at a later date, away from your error handling code and the exception will not be caught. There is still an open issue for this: https://github.com/emberjs/data/issues/3809 For more information, search Ember Discord for ``backgroundReload``. Solution -------- To solve this issue, add the ``reload`` option to ``findRecord`` and ``findAll`` e.g:: let contact = yield this.store.findRecord("contact", 22, { reload: true }) Then we can ``catch`` any errors ... Ember Concurrency ----------------- :: @task *doStuff() { try { let contact = yield this.store.findRecord("contact", 22, { reload: true }) this.manager = contact } catch(e) { console.log("catch, doStuff .........................................") console.log(e) } } Ember (without Concurrency) --------------------------- If you are not using Ember ``concurrency``, then the ``error`` handler in a ``Route``, should catch any errors e.g:: @action error(error, transition) { console.log("Before, contacts.js ...................................") console.log(error) console.log(transition) console.log("After, contacts.js ....................................") return false } .. _ember-data-adapter: Ember Data ---------- Our adapter (extends the ``DRFAdapter``) can be found in ``app/adapters/application.js`` for our projects. .. note:: I tried moving the adapter to ``@kb/ember-addon``, but the project doesn't seem to find it. Packages ======== Peer Dependencies ----------------- .. note:: I had so many issues with this one on ticket https://www.kbsoftware.co.uk/crm/ticket/6312/ Some things to check... Check ``auto-install-peers=false`` and fix any issues arising: .. code-block:: bash pnpm config list 6312-peer-dependencies ✖ ✱ ◼ auto-install-peers=false To fix ``V1 ember addons are resolving as incorrect peer dependencies``: I moved dependencies in ``package.json`` from ``dependencies`` to ``devDependencies`` and ``peerDependencies``. I used the exact version e.g. ``4.12.3`` rather than the ``^4.12.3``. Check all dependencies have the exact same version in addons and the project. Update Packages --------------- To update one package (e.g ``kb-base-ember-addons``):: npm i @kbsoftware/kb-base-ember-addons@latest Use ``ncu`` (``npm-check-updates``) to finalise versions before releasing for deployment. Run all the tests and check it by running on a local server. https://www.npmjs.com/package/npm-check-updates:: npm i -g npm-check-updates Then type:: ncu ... inside a folder with a ``package.json``. This shows you what is out of date. And typing:: ncu -u ... will update all the versions in the ``package.json`` file. So you then run:: npm i ... which will upgrade as per the new ``package.json`` Testing ======= .. note:: We don't need to define Mirage models, `Auto-discovery of Ember Data models`_ .. _`Auto-discovery of Ember Data models`: http://www.ember-cli-mirage.com/blog/#auto-discovery-of-ember-data-models .. _`Force Ember Data to reload data from backend API`: https://emberigniter.com/force-store-reload-data-api-backend/ .. _digital ocean tutorial: https://www.digitalocean.com/community/tutorials/how-to-install-node-js-on-ubuntu-16-04