Converting Nuxeo LTS2021 Web UI JavaScript components to HTML components for import in a nuxeo-project-bundle.html

Alex Protopopescu
Nuxeo Open Kitchen
Published in
7 min readNov 7, 2022

Unbundled (original) Nuxeo LTS2021 Web UI JavaScript components are defined in JS files ready to be bundled with Webpack into the Nuxeo Web UI JS bundles. They have “import” statements which bring in the necessary components & behaviors.

If you want to convert these into HTML components ready to be imported (<link rel=”import”>) into a nuxeo-*project-name*-bundle.html and deployed in the UI, you will find that the “import” statement paths do not exist anymore (because all those imported components/behaviors) have been included in the Nuxeo Web UI bundle and their addressing has been changed.

We will take an in-depth look at Example B from the previous article “How to overwrite Nuxeo Web UI bundled JS components in Nuxeo LTS2021”, in which we aim to overwrite nuxeo-document-import and all its dependencies.

Summary

Prerequisites

  • Deploy the solution to patch CustomElementsRegistry from the previous article;
  • Assume you have Nuxeo Web UI v3.0.15 deployed in your project.
  • switch your Node version to one lower than 15. e.g. on OSX brew install node@14; brew unlink node; brew link --overwrite node@14
  • Clone the “nuxeo-web-ui” repository https://github.com/nuxeo/nuxeo-web-ui
  • git checkout v3.0.15, install dependencies with npm install
  • This will give you access to all nuxeo-ui-element & nuxeo-elements for the 3.0.15 release.

Overwriting “nuxeo-document-import” component

There is no TL;DR.

To overwrite nuxeo-document-import, you will have to also overwrite nuxeo-document-create-popup, because the former is included directly in the latter.

And you will have to add/copy in Nuxeo.DocumentCreationBehavior, because it is missing from the deployed Nuxeo Web UI bundle — it is only imported into the (original) bundled nuxeo-document-import (and a few other components), but it is not made available to all UI components.

Thus the following three files will have to be converted from JS to HTML — use the links to navigate back and forth:
1. ./elements/nuxeo-document-creation/nuxeo-document-creation-behavior.jsview conversion process;
2. ./elements/document/nuxeo-document-import.jsview conversion process;
3. ./elements/nuxeo-document-create-popup/nuxeo-document-create-popup.jsview conversion process.

First off start by copying each JS file’s content into a corresponding HTML file between <script></script> tags, then we will take a look at what the conversion implies for each one.

1. nuxeo-document-create-behavior

Because nuxeo-document-import imports DocumentCreationBehavior locally and this behavior is not made available by Nuxeo Web UI bundle to all UI components, this behavior will have to be to be added/copied in.

Source for original nuxeo-document-creation-behavior.js component.
Source for converted new-nuxeo-document-creation-behavior.html component.

Most imported components/methods/behaviors may be found under the Nuxeo and Polymer objects, let’s go through how the imports addressing was fixed, one by one:

  • import { config } from ‘@nuxeo/nuxeo-elements brings in config which may be found in Nuxeo.UI.config on a deployed Web UI;
  • import { FormatBehavior } from ‘@nuxeo/nuxeo-ui-elements/nuxeo-format-behavior.js’ brings in FormatBehavior which may be found in Nuxeo.FormatBehavior on a deployed Web UI;
  • import { RoutingBehavior } from ‘@nuxeo/nuxeo-ui-elements/nuxeo-routing-behavior.js’ brings inRoutingBehavior which may be found in Nuxeo.RoutingBehavior on a deployed Web UI;
  • Lastly, the behavior is exported as const DocumentCreationBehavior, but we want to make it accessible to all UI components after import and we will add it to the Nuxeo object. Thus instead of export const DocumentCreationBehavior = [ ... ]we will add it as
var Nuxeo = Nuxeo || {};
Nuxeo.DocumentCreationBehavior = [ ... ]
  • after the imports addressing has been fixed in the code, delete the import statements.

2. nuxeo-document-import

Source for original nuxeo-document-import.js component.
Source for converted new-nuxeo-document-import.html component.

Most imported components/methods/behaviors may be found under the Nuxeo and Polymer objects, let’s go through how the imports addressing was fixed, one by one:

  • import { IronResizableBehavior } from ‘@polymer/iron-resizable-behavior/iron-resizable-behavior.js’ brings in IronResizableBehavior which may be found in Polymer.IronResizableBehavior in a deployed Web UI, as the path implies;
  • import { NotifyBehavior } from ‘@nuxeo/nuxeo-elements/nuxeo-notify-behavior.js’ brings in NotifyBehavior which may be found in Nuxeo.NotifyBehavior in a deployed Web UI, as the path implies;
  • import { UploaderBehavior } from ‘@nuxeo/nuxeo-ui-elements/widgets/nuxeo-uploader-behavior.js’ brings in UploaderBehavior, which may be found in Nuxeo.UploaderBehavior;
  • import { html } from ‘@polymer/polymer/lib/utils/html-tag.js’ brings in html which may be found in Polymer.html in a deployed Web UI, as the path implies;
  • import { DocumentCreationBehavior } from ‘../nuxeo-document-creation/nuxeo-document-creation-behavior.js’ wants to bring in DocumentCreationBehavior, but this is not available in the deployed Web UI, that is why we initially added/copied it in Nuxeo.DocumentCreationBehavior in step 1;
  • import.meta may not be used in a HTML component, in this case you may safely remove this;
  • all the other imported components are already made available by the underlying deployed Web UI bundle;
  • after the imports addressing has been fixed in the code, delete the import statements.

3. nuxeo-document-create-popup

Because nuxeo-document-import is imported directly into nuxeo-document-create-popup this latter element will have to be overwritten too, or else it will not use the previously overwritten nuxeo-document-import

Source for original nuxeo-document-create-popup.js component.
Source for converted new-nuxeo-document-create-popup.html component.

Most imported components/methods/behaviors may be found under the Nuxeo and Polymer objects, let’s go through how the imports addressing was fixed, one by one:

  • import { html } from ‘@polymer/polymer/lib/utils/html-tag.js’ brings in html which is available in Polymer.html in the deployed Web UI;
  • import { NotifyBehavior } from ‘@nuxeo/nuxeo-elements/nuxeo-notify-behavior.js’ brings in NotifyBehavior which is available in Nuxeo.NotifyBehavior;
  • import { I18nBehavior } from ‘@nuxeo/nuxeo-ui-elements/nuxeo-i18n-behavior.js’ brings in I18nBehavior which is available in Nuxeo.I18nBehavior as the path implies;
  • import ‘../document/nuxeo-document-import.js’ brings in nuxeo-document-import, which we have overwritten in step 2;
  • all the other imported components are already made available by the underlying deployed Web UI bundle;
  • after the imports addressing has been fixed in the code, delete the import statements.

4. Import the new components

Import all the newly created HTML components into your “nuxeo-*project-name*-bundle.html” in the proper order. I will assume the components are created in ui/custom-elements/.

<link rel="import" href="custom-elements/new-nuxeo-document-creation-behavior.html">
<link rel="import" href="custom-elements/new-nuxeo-document-import.html">
<link rel="import" href="custom-elements/new-nuxeo-document-create-popup.html">

Now when you drag and drop / import files from the import dialog into Nuxeo Web UI, your newly imported nuxeo-document-import (defined in new-nuxeo-document-import.html) will be used, and you may customise it as you see fit.

More details

If you are creating a new component based on an original one, you do not necessarily need to deploy the CustomElementsRegistry patch from the previous article, because you are not actually overwriting a component.

The process described in this article works for converting JS component files to HTML component files with the aim of overwriting them, as well as with the aim of creating new custom elements based on the original ones. e.g. base a HTML custom-results element on the original JS nuxeo-results.

To this extent here are a few more useful details for converting a component:

  • check out its original JS definition and see what dependencies it has and if those dependencies are already made available to all UI elements by the deployed Nuxeo Web UI, or if you need to convert and import some dependencies yourself. See the case of DocumentCreationSuggestion;
  • if your aim is to overwrite an existing component (instead of creating a spinoff), check out in the original Nuxeo We UI JS definitions where your component is used and how it is imported, if it is only imported locally in some other component B, then you will have to convert and import the caller component B as well;

As you have previously seen, most JS components have “import” statements which bring in other components, methods and behaviors, and these have to be addressed when converting the components to HTML, the most common correspondents for these are: config => Nuxeo.UI.config,debounce => Polymer.Debouncer.debounce, timeOut => Polymer.Async.timeOut, idlePeriod => Polymer.Async.idlePeriod, flush => Polymer.flush, html => Polymer.html, mixinBehaviors => Polymer.mixinBehaviors

You will find most of these already defined by Nuxeo Web UI in the Nuxeo & Polymer objects (take hints in which one by looking at the import path). You may easily examine the Nuxeo & Polymer objects by opening your browser’s Dev Console, writing Nuxeo. or Polymer. and the autocomplete will do the rest for you. Or set a debugger in your components to check how these objects look at that particular point in code.

The same thing is valid for behaviors, some will be in Nuxeo object, some in Polymer object, depending on their import statements. Exceptions exist where behaviors are not available to all UI components and you will have to convert and import them yourself.

I’m sure that all these tips & tricks will make converting original Nuxeo Web UI JS components to HTML components or creating custom spinoff HTML components off of them a breeze!

Follow & stay tuned for more!

--

--