AppEngine Plugin User Interface
Node.js version 20.11 or higher is required in development environment.
Web User Interface is built using the SAP UI5 Framework. It is a modern enterprise-ready UI framework. AppEngine offers a set of libraries to simplify development of UI5 applications and to manage user authentication, translations.
Parts of AppEngine UI5 Application
- Launchpad - A UI5 application that displays all applications available to the user. It serves as a container for running all plugins within AppEngine.
- @computec/uicore - Provides foundational classes for developing AppEngine UI5 applications, essential for plugins operating within the AppEngine Launchpad.
- @computec/common - A set of common controls, services and helpers that helps to build UI5 applications.
- @computec/templating - A set of controls designed to simplify view generation.
Requirements for AppEngine UI5 Plugin
AppEngine Launchpad can run any UI5 application as long as below requirements are met:
-
The
computec.appengine.uicore
library is required (withcomputec.appengine.common
as an optional addition). These libraries can be included in the manifest.json file.{
...
"sap.ui5": {
...
"dependencies": {
...
"libs": {
"computec.appengine.uicore": {},
"computec.appengine.common": {}
}
}
}
...
} -
The plugin must extend
computec.appengine.uicore.UIComponent
, which serves as the foundation for AppEngine UI5 applications. This component ensures user authentication, facilitates access to AppEngine UI services, manages translations, and more. UIComponent itself is an extension ofsap.ui.core.UIComponent
.import UIComponent from "computec/appengine/uicore/UIComponent";
/**
* @namespace ct.vehone
*/
export default class Component extends UIComponent {
...
public static metadata = {
manifest: "json",
};
...
} -
To enable proper navigation within the AppEngine Launchpad, the plugin must utilize either
computec.appengine.uicore.plugin.m.PluginRouter
orcomputec.appengine.uicore.plugin.f.PluginRouter
. These extendsap.m.routing.Router
andsap.f.routing.Router
, respectively. The desired router can be specified in the manifest.json file.{
...
"sap.ui5": {
...
"routing": {
"config": {
"routerClass": "computec.appengine.uicore.plugin.m.PluginRouter",
"viewType": "XML",
...
},
...
}
}
...
}
Crating Simple Ui5 Application for AppEngine
The easiest way to start new AppEngine UI Plugin project is by using the CT AppEngine Plugin Project template from CompuTec.AppEngine.Templates.
dotnet new ctaeaeproject --RoutePrefix CTVehOne
This command will create a new project with the basic structure for the AppEngine UI5 Plugin. The plugin ID will be derived from the parent folder name, but you can specify a different one using the --name parameter. If the command is executed inside the CT.VehOne folder, the following structure will be created:
Structure
CT.VehOne -CustomViews - folder for custom views
- Jobs - folder for background jobs
- Properties - folder for configuration files
- Translations - folder for translations
- www
- src - source code of UI5 application
- assets - additional file like css, images etc.
- controller - folder for controllers
- view - folder for views
- Component.ts - UI5 Component extending computec.appengine.uicore.UIComponent
- manifest.json - UI5 manifest already configured for AppEngine
- additional configuration - files like .eslintrc, etc.
- package.json - npm configuration file
- ui5.yaml - UI5 configuration file
www.code-workspace
- Visual Studio Code workspace file for easy development with recommended extensions and debug configuration in place
- src - source code of UI5 application
Build
In order to build UI5 application you need to run below command in www folder:
npm install
npm run build
For development it is recommended to use npm run watch:ts
command that will start UI5 application in watch mode - any change in src will trigger transpilation of typescript files.
If in your dev.config.json file you have set MapWwwAppFolder
to true then each browser request will get data from www/webapp folder instead of build path. Thanks to this you will see changes in your www ui5 application immediately after saving file.
Translations
In order to use Message Translations that are defined in backed you need to specify source of translations in manifest.json. This way ui5 will use this enpoint as translation provider. You can find this endpoint in openAPI documentation in swagger. Patter for this enpoint is as follows: plugins/{RoutePrefix}/I18n/i18n.properties
. RoutePrefix can be found in manifest.json
{
...
"sap.app": {
...
"i18n": "plugins/CTVehOne/I18n/i18n.properties",
...
}
...
}
Attaching Odata Endpoints to AppEngine
Adding an OData model to a plugin is straightforward. You can do this within the component by calling the attachSLOdataModel function. In the example below, we are attaching the OData ProcessForce endpoint with the alias PF. From this point on, you can bind controls using the path PF>/.....
Multiple endpoints can be defined with different aliases. Note that the alias "AE" is reserved for the AppEngine OData endpoint, which is already included in the application.
this.attachSLOdataModel("odata/ProcessForce/", "PF");
AppEngine Custom Views endpoint
This binding is one-way only; it is not possible to update data using this endpoint. Additionally, it does not currently return metadata for the selected table, view, or custom view.
There are tow types of CustomViews endpoints:
-
Simple - It is an endpoint that returns data from selected table or view. The "DataSource" parameter should specify the name of the database table or view. It is a read-only endpoint but allows the usage of OData v4 features like $filter, $orderby, $top, $skip, $select, $groupby etc.
/odata/CustomViews/Simple(DataSource={DataSource})
-
Custom - It is an endpoint that returns data from the selected custom view declared in plugin. The "Id" parameter should specify the ID of the custom view. It is q read-only endpoint but allows the usage of OData v4 features like $filter, $orderby, $top, $skip, $select, $apply etc.
/odata/CustomViews/Custom(Id={Id})
Crating Custom View in Plugin
Custom views are highly useful when there is a need to display data from multiple tables or views. To create a Custom View, you must add a JSON file named {anyName}.customview.json
inside the CustomViews directory. This file needs to be set to be copied to the output directory in the project file. To apply this for all CustomViews
files, add the following code to the project file:
<None Update="CustomViews\Vehicles.customview.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
Below is an example of Custom View Definition:
{
"Id": "Vehicles",
"Description": "Vehicles List",
"Source": {
"Hana": "Select \"ItemCode\", \"ItemName\" from \"OITM\"",
"MsSql": "Select ItemCode, ItemName from OITM"
}
}
Binding Custom View
Since CustomViews is an OData v4 endpoint, it can be bound to UI5 controls such as tables or lists. Below is an example of binding a database table to a UI5 table control using the CustomViews.Simple endpoint:
...
<Table items="{
path: 'AE>/CustomViews/Simple(DataSource=\'@CT_VO_OVMD\')'
}"/>
...
<items>
<ColumnListItem type="Navigation"
press="onItemPress">
<cells>
<Text text="{path: 'AE>U_Type', type: 'sap.ui.model.odata.type.String'}"/>
...
</cells>
</ColumnListItem>
</items>
</Table>
To bind to CustomViews.Custom declared in the plugin, you need to provide the correct ID, which consists of {RoutePrefix}:{CustomViewId}
. Below is an example of binding a database table to a UI5 table control using the CustomViews.Custom endpoint:
...
<Table items="{
path: 'AE>/CustomViews/Custom(Id=\'CTVehOne:Vehicles\')'
}"/>
...
<items>
<ColumnListItem type="Navigation"
press="onItemPress">
<cells>
<Text text="{path: 'AE>ItemCode', type: 'sap.ui.model.odata.type.String'}"/>
...
</cells>
</ColumnListItem>
</items>
</Table>
CustomViews are a powerful tool that enables the display of data from any database source without the need for creating dedicated backend controllers.
Since there is no metadata for the CustomViews endpoint, you must specify the correct path to the data in the binding and declare the expected type.
Filtering Custom Views
As mentioned earlier, CustomViews endpoints do not have metadata for the returned data, so we need to filter the data directly using the $filter parameter. Since UI5 cannot generate the filter string without metadata, the computec.appengine.common
library includes the FilterHelper function getODataFilterExpression, which generates the filter string for the filter. Below is an example of how to use it:
private _applyFilter() {
const filter = new Filter({
path: "ItemCode",
operator: FilterOperator.EQ,
value1: "A00001",
});
const filterString = FilterHelper.getODataFilterExpression(filter);
this._getVehiclesTableBinding().changeParameters({
$filter: filter,
});
}
Libraries provided by AppEngine
AppEngine offers a set of libraries for use in UI5 applications. These libraries are already included in AppEngine, so there's no need to add them to the build of your plugin. However, you can install them via npm to obtain the TypeScript definitions.
@computec/uicore
npm i @computec/uicore --save-dev
This base library is essential for all plugins running within the AppEngine Launchpad. It provides fundamental classes for building AppEngine UI5 applications, with the AppEngine UI5 component needing to extend the UIComponent class from this library. Additionally, it includes the PluginRouter, which should be specified in the manifest.json for proper navigation within the AppEngine Launchpad.
The library also offers several useful helpers, including:
- FormatterHelper with static translation methods
- ErrorHelper that helps in handling errors
- CustomViewHelper that helps in binding CustomViews endpoint
- OdataHelper that helps retrieving binded objects
@computec/common
npm i @computec/common --save-dev
This library offers a wide range of valuable controls, services, and helpers to streamline the development of UI5 applications. It includes common SelectDialog components, such as:
- ItemSelectDialog,
- WarehouseSelectDialog,
- UomSelectDialog,
- BusinessPartnersSelectDialog,
- DocumentTypeSelectDialog
- etc.
The library also provides numerous helpers, including:
- FilterHelper,
- StorageHelper,
- ValidationHelper,
- XLSXHelper,
- etc.
The library includes highly useful types based on SAP Business One field types, which automatically handle formatting according to SAP Business One settings:
- Quantity,
- Amount,
- Price,
- PriceCurrency,
- DateOnly,
- TimeOnly,
- etc.
This library also includes several base classes that can be extended to simplify the creation of new controls, dialogs, services, view models, and more.
For detailed information and examples, download the library and explore the example code and comments within.
Refer to the Example code for guidance on using the AppEngine UI5 Plugin.