Creation of UI package "from scratch"

Prerequisites: Before getting started, you need to install nodejs and @angular/cli

This instruction is aimed for information purpose only and to understand better the principle of package developing. To save your time, efforts and to avoid usual mistakes, we kindly recommend to use the project templates source-code generator provided by the platform.

This guide provides information on building a basic plugin for the mef.dev technical preview platform. The basic plugin does not contain any business logic implementation. Its purpose is to provide the necessary structure for a plugin to work within the platform. Note: Tested with the following versions of @angular/cli: 12.2.17, 13.3.8, 14.2.11, 15.2.8, 16.0.3

1. Creation Angular project

Create a standard Angular application:

Note: You need to enable routing during project creation or add routing manually later.

ng new <app-name>

2. Adding dependencies

@natec/mef-dev-platform-connector

In the project, you can use almost any additional libraries. However, to work on the platform, you need to use @natec/mef-dev-platform-connector, which provides essential functionality for working with the platform. To add the package, run the following command:

npm i @natec/mef-dev-platform-connector@14.0.0

Note. Important:Make sure the installed version of mef-dev-platform-connector matches the version of Angular on your computer (you can check it by running the ng v command). You can find the version compatibility table here.

ngx-build-plus

To build the plugin, we use the resources provided by ngx-build-plus.

ng add ngx-build-plus@^14.0.0

Note. The version of ngx-build-plus should also match the installed version of Angular. You can refer to the version compatibility table below

Angular / CLI ngx-build-plus
12 /12 ngx-build-plus@^12.0.0
13 /13 ngx-build-plus@^13.0.0
14 /14 ngx-build-plus@^14.0.0
15 /15 ngx-build-plus@^15.0.0
16 /16 ngx-build-plus@^16.0.0

3. Changing the base selector

When generating a project using @angular/cli, a base component AppComponent is generated with the selector app-root. We need to replace it with the selector of our plugin. This parameter is reserved within the platform when creating a plugin and is named FrontendPluginName. In the example below, the project name from package.json is used, but it's not mandatory. To make the change, follow these steps:

// src/app/app.component.ts
...
@Component({
selector:  'plugin-example', // 'app-root',
template:  '<router-outlet></router-outlet>', // <-- також замінюємо стандартний вміст
styleUrls: ['./app.component.scss']
...
})
// src/index.html
...
<body>
    <plugin-example></plugin-example>  <!-- <app-root></app-root> -->
</body>
...

4. Routing changes

For proper routing functionality, ALL actual paths should be contained within the children section.

Note: Otherwise, when navigating within the plugin, the ENTIRE path will be modified (including platform navigation). This won't render the plugin inoperable, but further use of the platform will be unpredictable!

Additionally, to ensure correct navigation, the base paths should be passed through the updatePluginsRoutes(Routes) method. More details can be found here.

As a result, the declaration of paths should look as follows:

// src/app/app-routing.module.ts
import { PlatformHelper } from  '@natec/mef-dev-platform-connector';
...
// const  routes: Routes = [];
const  routes: Routes = PlatformHelper.updatePluginsRoutes([
    {
        path:"",
        children:[
            // insert routes here
        ]
    }
]);
...

5. Creating of first component

NOTE! Implementing the layout in AppComponent is not recommended. For further application development, it is recommended to extract all functionality into a separate component structure. Example

To achieve minimal functionality, you need to create one component:

ng g c test

After that, import it and add it to the routing configuration:

// src/app/app-routing.module.ts
import { PlatformHelper } from  '@natec/mef-dev-platform-connector';
import { TestComponent } from './test/test.component';
...
// const  routes: Routes = [];
const  routes: Routes = PlatformHelper.updatePluginsRoutes([
    {
        path:"",
        children:[
            {
                path:"",
                redirectTo:"test",
                pathMatch:  'full',
            },
            {
                path:"test",
                component:  TestComponent
            }
        ]
    }
]);
...

6. Specification file version.json

To upload to the platform, the collection must include a specification file. It is generated by a script located at @natec/mef-dev-platform-connector. Firstly, you need to create a src/environments folder where the version.ts file will be generated.

To generate the specification file, you need to execute the following command:

npm explore @natec/mef-dev-platform-connector -- npm run generate-version-file

The result of executing this command is the generation of the environments folder and its contents, which include a set of files containing information about the plugin build.

To copy the generated file into the build output, you need to add the path to the new asset in the configuration file.

// angular.json
...
"architect": {
    "build": {
        "options": {
            ...
            "assets": [
                "src/favicon.ico",
                "src/assets",
                "src/version.json" // <---    
            ]
...

To modify the specification file before each build for publication, it is a good practice to set up npm scripts as shown in the example

The result of its operation can also be used within the application. Example.

7. Build and deploy

To build the plugin, you can use the following command:

 ng build --output-hashing none --configuration production --single-bundle --output-path dist

Afterwards, you can upload the contents of the dist folder to the platform.

Useful links

The instructions for registering a plugin on the platform can be found in the following link: https://mef.dev/uk/dev_guides/upload_ui_plugin.md