Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
cancel
Showing results for 
Search instead for 
Did you mean: 
deno
Advisor
Advisor
In this blog post, you will learn how to create your first application using Fundamental Library - more specifically with Fundamental Library for Angular and Fundamental Library Styles). You can also use a working variant of the application can be found here.

We will use a few components(mainly button and alert), which should it will look like this:



You would be able to trigger different alerts by clicking on the buttons.

Prerequisites



Create your First Angular Application


We will be using Angular CLI command line interface to create a new angular application from scratch.

The first step is to decide where you want to create the application and open a terminal into that directory. Let's create a new application my-cool-ngx-app with the command:
ng new my-cool-ngx-app



Then, we go in the folder of the newly created application and run it:
cd my-cool-ngx-app
ng serve



You can test whether the application is properly running by opening a browser tab at http://localhost:4200/, which should look like this:



We will delete the content of the generated application:

  • Open the application with your IDE. The folder structure will look similar to:




  • Open and delete the content of the file app.component.htmland save it


Bring Fundamental Libraries


In the previous section, we created a new Angular application with Angular CLI, we ran and tested it. We also deleted the template content generated with the CLI.

In this section, we will focus on bringing Fundamental Library for Angular. This will require very few steps:

Go to the folder of the application in your terminal and run the command:
ng add @fundamental-ngx/core

It will ask you to add an Animation, choose Y:



This will do a few things:

  • Add @fundamental-ngx/core package to your direct dependencies into your package.json and it will install it.

  • Add path of icon font and 72 font files into angular.json styles property. This will include those files as the published assets, so the application can use them.


Create the Application


The only thing you need to do now is to import and use components from Fundamental Library for Angular (Core). Let's import modules for alert and buttonin app.module.ts:


import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import {
ButtonModule,
AlertModule
} from '@fundamental-ngx/core';

import { AppComponent } from './app.component';
import {
BrowserAnimationsModule
} from '@angular/platform-browser/animations';

@NgModule({
declarations: [
AppComponent
],
imports: [
AlertModule,
ButtonModule,
BrowserModule,
BrowserAnimationsModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }

We can now add some content of the application in app.component.html:
<div class="wrapper">
<button fd-button
[glyph]="'action'"
(click)="openFromComponent()">Opeb from Component</button>
<button fd-button
[glyph]="'action'"
(click)="openFromTemplate(template)">Open from Template</button>
<button fd-button
[glyph]="'action'"
(click)="openFromString()">Open from String</button>
<button fd-button
[glyph]="'sys-cancel'"
[options]="'emphasized'"
(click)="alertService.dismissAll()"
[disabled]="!alertService.hasOpenAlerts()">Dismiss All</button>
<button fd-button
[glyph]="'palette'"
(click)="toggle()">Change Theme</button>
</div>

<!-- Defining a template to open -->
<ng-template let-alert #template>
<div>{{alert.data.firstLine}}</div>
<div>{{alert.data.secondLine}}</div>
<button fd-button
[fdType]="'positive'"
[options]="'emphasized'"
[compact]="true"
(click)="alert.dismiss('Data passed back')">
Click to dismiss
</button>
</ng-template>

We are using a few buttons that will trigger different types of alert(component, template, string) and one more button for switching the themes. For that reason, we will create a new file alert-example.component.ts, which will be used to be opened as an alert content:
import { Component } from '@angular/core';
import { AlertRef } from '@fundamental-ngx/core';

@Component({
selector: 'fd-alert-content',
template: `
<div>{{ref.data.label}}</div>
<div>It will stay open when the mouse is hovered inside.</div>
<div>Injecting AlertRef allows you to call
<code>dismiss()</code>
on the alert or access passed data.</div>
`
})
export class AlertContentComponent {
constructor(public ref: AlertRef) {}
}

We are using data that can be passed from the component triggering the alert. In our example this is the property label.

As a last step, we will add some logic in app.component.ts:
import { Component } from '@angular/core';
import { AlertContentComponent } from './alert-content.component';
import { AlertService } from '@fundamental-ngx/core';

@Component({
selector: 'fd-alert-component-as-content-example',
templateUrl: './alert-component-as-content-example.component.html',
styleUrls: ['alert-component-as-content-example.component.scss']
})
export class AlertComponentAsContentExampleComponent {

constructor(public alertService: AlertService) { }

openFromComponent() {
this.alertService.open(AlertContentComponent, {
type: 'warning',
minWidth: '500px',
mousePersist: true,
duration: 7500,
data: {
label: 'This alert was opened by providing a component as content!'
}
});
}

openFromString() {
const alertContent = 'This is the content! The alert is not dismissible, but will disappear after 7500ms.';
this.alertService.open(alertContent, {
type: 'information',
minWidth: '500px',
dismissible: false,
duration: 7500
});
}

toggle(){}

openFromTemplate(template): void {
const alertRef = this.alertService.open(template, {
type: 'success',
duration: -1,
minWidth: '500px',
data: {
firstLine: 'This alert passes data to the template.',
secondLine: 'It also has [duration]="-1" and will not disappear automatically.'
}
});

alertRef.afterDismissed.subscribe((data) => {
// Do something after closing, receive data
// You can also manually close this alert using alertRef.dismiss()
});
}
}

The final version of app.module.ts should look like this:
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import {
ButtonModule,
AlertModule
} from '@fundamental-ngx/core';
import { AlertExampleComponent } from './alert-example.component'

import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';

@NgModule({
declarations: [
AppComponent,
AlertExampleComponent
],
imports: [
AlertModule,
ButtonModule,
BrowserModule,
BrowserAnimationsModule
],
providers: [],
bootstrap: [AppComponent],
entryComponents:[AlertExampleComponent]
})
export class AppModule { }

The goal of this blog post was to introduce some of the packages from Fundamental Library.

Check out the other blog posts related to Fundamental Library.
7 Comments
dominik_augustin
Explorer
0 Kudos
Hi Mladen,

 

I'm still kind of missing the big picture, how such an application (be it angular, vue, or whatever works with HTML-elements) might / should play together with the gateway.

Guidlines on OData models & client libraries, "smart" forms / tables, ...

Or how that might be integrated into the FLP?

Any ressources or plans on that, you might be allowed to share?

 

Kind Regards

Dominik
deno
Advisor
Advisor
0 Kudos
Hi dominik.augustin,

Your questions are valid ones and we are considering this seriously. One direction we are exploring is using metaUI and luigi. If you have ideas or suggestions, feel free to share. We are open for a discussion.

We have applications that are not on top of OData yet but still have to be consistent with Fiori.

best regards,

Mladen

 
former_member186905
Participant
0 Kudos
Hi Mladen,

My question goes into a similar direction as Dominik's: What about using the SAP UI5 theme designer in order to style also apps using one of the SAP Fundamental libraries?

My background is not so much in building S/4-hosted UI5 apps, but I'm mainly building side-by-side extensions. However, in order to be able to use both e.g. SAP Fiori Element based apps and fundamental-ngx based ones in one and the same system landscape, having a common theme (even if not 100% matching, but good enough) is a must-have from my point of view.

Is there already a way to achieve this?

Thanks and kind regards,

Valentin
deno
Advisor
Advisor

Hi Valentin,

Thank you for your question.

The components in fundamental library are using the theme designer’s theming parameters(css variables). So if your application is connected with the theming services and you get custom theming parameters then your application based on fundamental-ngx will be restyled. We have an internal demo where we included 2 applications(a ui5 demo app and a fundamental-ngx application under luigi) and when the user changes the theme through the shellbar both applications get re-themed.

 

cheers,

Mladen

alfonsoarmenta
Explorer
Hi Mladen,

the library looks very good but often I find the documentation a bit lacking especially when one is not familiar with the Fiori Design guidelines.

For example, the Combo Box component documentation does not show how to change the matching strategy.

Recently the default strategy in the library has changed from 'contains' to 'starts with'.

Likely because 'starts with' is closer to the default in Fiori which is 'starts with element'?

Unfortunately the documentation doesn't show how to change this strategy.

So from my point of view up until version 0.24 I had a nicely working combobox that behaves in one way but on version 0.27 the combobox has changed and the documentation does not show how to change the behaviour back.

Would be nice to have a forum where one could post questions like this about the components where the documentation may be lacking.

(By the way, if you know how to change the default matching strategy for the Combo Box component, I'd love to see it!)
fkolar
Explorer
0 Kudos
Hi dominik.augustin

One part of this are UI components, how we render this or that, and another side is how we represent our state on the UI, how we connect to our micro-services, how we cache data on the client side, etc..

Let's separate those two.

We do have more requirements that works with REST API and there is a harmonization in progress to make Rest API and OData compatible with respect to features. According to the SAP Technological Guidelines.

There is also another stream to introduce StateManagement layer and it is designed in such way that you would be able to provide your own implementation if needed. Not only rest, but maybe graphQL or even OData. But default is going to be REST.

Thanks,

Frank

 

 

 
deno
Advisor
Advisor
hi alfonsoarmenta,

thank you for the feedback! We are working hard on the documentation and the plan is to improve it even more. Your feedback will help us identify concrete areas to improve.

the combobox undergone some improvements as we migrated from popper.js to angular CDK.

There are multiple ways to engage with the teams. One of then is through our slack . You can also open issue or start a discussion on our repo.

I took the initiative to open an issue from you. Feel free to update or provide more information.

cheers,

Mladen