Skip to content

POC Report: WebComponents

Stéphane Brunner edited this page Sep 27, 2021 · 43 revisions

Lit element / HTML

TODO

Integration with AngularJS

The attributes are a little bit renamed:

ng-on-close-panel="mainCtrl.ngeoAuthActive = $event.detail" => Code called, then the close-panel event is dispatched from the component.

ng-prop-login_info_message="mainCtrl.loginInfoMessage" => set the property loginInfoMessage of the WebComponent with custom object.

Refer to ngOn and ngProp in the AngularJS documentation for full details.

Store RXJS

A store, not a state. Mainly based on https://rxjs.dev/api/index/class/BehaviorSubject, a multicasted observable with a default value. But There are other "Subject" possibilities.

Works well and without bad surprise. Easy to access, easy to set. Light to implement.

The code must be simple. One set function should emit one thing.

The integrity of a stored value must be well checked by the store.

RXJS offer a lot of operators to play with Observable (see https://rxmarbles.com). From experience, it's better not to use too much of them (the code becomes quickly hard to follow and to change).

Using observable allows use to remove our old events and centralize the state of the application.

I18n

Evaluate i18next and lit-localize Choice for i18next because with lit-localize we can’t translate text out of the component, and we need to translate some part of the HTML like the page title.

Translate the tag content in the HTML:

<title data-i18n="Alternative Desktop Application">GeoMapFish</title>

Translate a tag attribute in the HTML:

<button data-i18n="[tooltip]Draw and Measure"/>

Translate just a string in the HTML: Not possible

Translate just a string in the JavaScript(WebComponent):

import i18next from 'i18next';
html`${i18next.t("Loading themes, please wait...")}`

Plural in the JavaScript(WebComponent):

import i18next from 'i18next';
const i18nextConf = {count: themes.length};
html`${i18next.t("Loading {{count}} themes, please wait...", i18nextConf)}`

But this can't be used because it breaks the English translating who actually is in the sources... Same issue for context: https://www.i18next.com/translation-function/context

Config

The configuration will be dispatched by RXJS, and be fully typed, see src/state/config.ts.

Usage:

import configuration, {Configuration} from 'ngeo/store/config';

this.subscriptions_.push(
  configuration.getConfig().subscribe({
    next: (configuration: Configuration) => {
      // Use the configuration
    },
  })
);

TypeScript

We choose TypeScript to write the new component as it's largely accepted by lit-element, lit-element itself is written in TypeScript. Other motivation is that we get some limitations in typing in the JSdoc.

Translate JavaScrypt to TypeScript, see: https://github.com/camptocamp/ngeo/blob/poc_2.7/docs/codeshift.md

Service migration

TODO

Simplified API / Separate build

We provide the following element throw a Singleton available in window, then we can access to the in a separate build. In this way, by default the HTML page will be compiled by the ngeo build (not modifiable in the project).

The states are exposed to be able to use the out of the script (currently: user, config, OpenLayer map).

Component extension

TODO

Example / StoryBook

We will use StoryBook for the new examples. StoryBook is more than providing the example, with that, we can also do test and review with Chromatic It make a little documentation of a web component. It will also a base for the tests.

Tests

Finally, Cypress is implemented. It has a good end-to-end tests as good unit tests possibilities, embeded ui, good cli... and gives a good feeling (Even if the doc is not so clear if you don't use React).

Testing models and services are mandatory.

As we use Storybook, we don't need the (beta) extension to test components, we can use "the standard way to test" on Storybook pages. Using Chromatic, we have a good check on examples. Therefore, testing our component with Cypress is not so useful. But If the evolution of the examples make them more complex, like including a real authentication for the auth component, we should test that with Cypress, via the example. Otherwise, we should use Cypress for more end-to-end tests directly on the apps.

The alternatives would have been Jest, Web Test Runner...

Clone this wiki locally