Your first App

In this section we will introduce the MetaUI framework with with simple application where we generate User form with ability to view, edit and create. The final app should look like following picture.

User detali page

It is recomended to have practical expirience in writing Angluar application so you could understand all the key aspects of the framework and to be able to answer at the end of this tutorial "How do I start?" and "How do I do X in MetaUI?".

1. Create new Angular application

$ ng new my-metaui-app --style=scss
$ cd my-metaui-app/

Follow instruction on the screen given to you by ng new command.

This tutorial is made for Angular version 9. Make sure you have latest Angular CLI.

2. Add @ngx-metaui/rules to your app

  • Now let's use schematics and integrate MetaUI with the project.

$ ng add @ngx-metaui/rules

The ng addcommand prompts you to select UI library. We have two implementations that are already part of this project. Material, which implements material design angular library and Fiori which is another UI library implementation available from SAP.

Select Fiori.

Once this ng add command finishes you are fully configured to start some rule driven development. Besides updating standard project files such angular.json and package.json it also:

  • Imports MetaUI modules inside app.module.ts

  • Creates main Application.oss rule file

    • This is rule file similar to the src/styles.css just like having global styles in the project

  • Creates user-rules.ts to export the content of our rules to be later on imported inside our module.

src/app/app.module.ts
src/app/rules/Application.oss
src/app/rules/user-rules.ts
src/app/app.module.ts
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
BrowserAnimationsModule,
MetaUIRulesModule.forRoot({}),
FioriRulesModule.forRoot()
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule {}
src/app/rules/Application.oss
/**
* Module represent Global Top level application app rules. Modules are used in combination with
* <m-app> component.
*
* Application.oss is used for all global settings and OSS definitions
*/
module {
}
src/app/rules/user-rules.ts
/**
* Content of this file is automatically populated by oss compiler
*/
export {ApplicationRule} from './ts/Application.oss';

MetaUI has two parts the Rule Engine (MetaUIRulesModule) that glues everything and UI layer (FioriRulesModule)that brings in all the UI components. The .oss file extension stands for object style sheet just like you have cascading stylesheet and they are pretty similar.

src/app/rules is the main folder where are stylesheets are stored.

3. Generate User page

To speed up everything we will use generate schematics to create UserDetail page already setup with different editing modes:

  • Create

  • Edit

  • View

$ ng g @ngx-metaui/rules:mPage --modelClass=User --name=UserDetail

It will create following files:

src/app/user-detail/user-detail.component.html
src/app/user-detail/user-detail.component.ts
src/app/model/user.ts
src/app/rules/User.oss
src/app/user-detail/user-detail.component.html
<div class="page">
<h2>Object Detail</h2>
<button fd-button (click)="operation='create'">Create</button>
<button fd-button (click)="operation='edit'">Edit</button>
<button fd-button (click)="operation='view'">View</button>
<hr/>
<m-context [object]="object" [operation]="operation" layout="Inspect">
<m-include-component></m-include-component>
</m-context>
</div>
src/app/user-detail/user-detail.component.ts
import {Component, OnInit} from '@angular/core';
import {User} from '../model/user' ;
@Component({
selector: 'app-user-detail',
templateUrl: './user-detail.component.html',
styleUrls: ['./user-detail.component.scss']
})
export class UserDetailComponent implements OnInit {
object: User;
operation = 'view';
constructor() {
}
ngOnInit(): void {
this.object = new User('R0001', 'Frank Kolar',
'This is my user record', new Date());
}
}
src/app/model/user.ts
import {Entity} from '@ngx-metaui/rules';
/**
* This is generated class
*/
export class User implements Entity {
constructor(public uniqueName?: string, public name?: string,
public description?: string, public created?: Date) {
}
identity(): string {
return this.uniqueName;
}
getTypes(): any {
return {
uniqueName: String,
name: String,
description: String,
created: Date
};
}
/**
* Used by MetaUI to identify the name of the class once everything is minified
*/
className(): string {
return 'User';
}
toString(): string {
return this.name;
}
}
src/app/rules/User.oss
Defines basic object styles for Domain class User
class=User {
field=uniqueName {
label:"Id";
}
field=name {
label:"Name";
}
field=description {
trait:longtext;
}
zNone => *;
zLeft => uniqueName => name => description => created;
}
/*
Sample definition for operations edit and create
*/
class=User {
operation=(edit, create) {
zNone => *;
zLeft => name => description;
}
operation=(create) {
zNone => *;
zLeft => name => description => created;
}
}

There is always a .oss (rules file) per your domain class and once we have this we can create a meta context that takes our model and metadata to genare the UI. To get some basic understand of OSS syntax please check out next chapter.

4. Compile rules

Now we need to run following command to compile our sample rule. This just takes the rule file and turns it into typescript file so we can import it in the application.

$ npm run compile:oss

It will output following file:

src/app/rules/ts/User.oss.ts
src/app/rules/ts/User.oss.ts
/**
* This is generated file. Do not edit !!
*
* @formatter:off
*
*/
/* tslint:disable */
export const UserRule = '/* User rules.oss -- Meta-data rules. Generated file Default definition */ class=User { field=uniqueName { label:"Id"; } field=name { label:"Name"; } field=description { trait:longtext; } zNone => *; zLeft => uniqueName => name => description => created; } /* Sample definition for operations edit and create */ class=User { operation=(edit, create) { zNone => *; zLeft => name => description; } operation=(create) { zNone => *; zLeft => name => description => created; } } ';
/* tslint:disable */
/**
* @formatter:on
*
*/

5. Update app.component.html

Add our newly created component from step 3 to the main page app.component.htm

src/app/app.component.html
src/app/app.component.html
<app-user-detail></app-user-detail>

4. Run it

$ ng serve

Open up the page http://localhost:4200/.

Now you should see a simple form where UI is assembed on the fly, driven by our rule files, where you can switch between different operation mode, for each the UI a big different.