Framework Guidelines to Develop Home Widgets¶
Overview¶
IFS Home widgets are developed independently from the IFS client framework, ensuring minimal code dependencies on the core application. Widgets are organized into libraries based on their respective product areas, and each widget library can contain multiple widgets. These libraries are packaged as Node modules and published to Bitbucket, where they are then referenced as dependencies within the client framework’s package.json
file.
Although the development of widgets is separate from the client framework, the delivery of new widgets or updates to existing ones must be incorporated into a client framework release to be provided to customers. This ensures compatibility and streamlined integration within the IFS Cloud environment.
Fig 1. Technical Architecture
Widget Base Library¶
This is a base library that includes useful components, directives, and services which makes the widget development process easier. This also includes a schematic which can be used to generate new libraries without worrying about the boilerplate code and configurations.
Link | |
---|---|
Artifacts | https://bitbucket.org/ifs-pd/ifs-cloudhome-base |
Source Code | https://bitbucket.org/ifs-pd/ifs-cloudhome-base-source |
Widget Libraries¶
These libraries contain the widget artifacts that are integrated as Node packages within the IFS Cloud client framework. Each library consists of a set of widgets grouped according to defined criteria. Currently, widgets are categorized into libraries based on their associated product area. It is recommended to follow this same structure when developing new widgets to ensure consistency and ease of integration.
Example:
Product Area | Link |
---|---|
Asset Management | https://bitbucket.org/ifs-pd/ifs-cloudhome-widgets-asset |
HCM | https://bitbucket.org/ifs-pd/ifs-cloudhome-widgets-hcm |
Framework | https://bitbucket.org/ifs-pd/ifs-cloudhome-widgets-framework |
Widget Workspace¶
This is the repository where the widget-related code should be included, either in an existing widget library or in a new library. This also includes a Testground application which can be used for testing the widgets before integrating with the IFS client framework. This workspace is already configured with the Widget base library and IFS Design system packages (Granite Tokens, Granite Icons, Granite component, Granite Kendo Components).
Link | |
---|---|
Work Space | https://bitbucket.org/ifs-pd/ifs-cloudhome-workspace |
Widget development process¶
Getting Started With Widget Development¶
Initial Steps¶
- To get started with widget development, clone the Workspace repository. Run the Testground app with the included sample widgets.
npm install
ng serve
Note : This library can be used as a reference to understand how to use base framework functionalities such as communicating with backend, navigation, configuration and handling translations, as well as to see how the IFS Design system elements including as granite components, granite icons and granite tokens can be used for widget development.
Creating a New Library / Widget¶
-
Create a new Library Project : Use the schematics provided by
@ifsworld/cloud-home-widget-base
to generate a new library project. -
Run
npm run schematics:add-widget
and follow the cli instructions.
Provide :
- Library Name
- Widget Name
-
Widget Size
and it will generate all the boilerplate code. (Refer the Widget Naming section)
Note : To add another widget to the same library, run the same command but give the existing library name when asked.
$ npm run schematics:add-widget
> ifs-cloud-home-widgets-workspace@0.0.0 schematics:add-widget
> schematics @ifsworld/cloud-home-widget-base:add-widget
? Library Name? @ifsworld/widgets-asset
? Widget ID? RecentDocumentsWidget
? Widget width? Half | Full
? Widget height? Medium | Dynamic
? Does the widget has configuration? Yes | No
Add Widgets to the Testground app¶
To add the new widgets to the Testground app, add the widget selector, component and metadata to widgetMetadata object in projects\widget-testground\src\app\widget-meta\widget-metadata.ts
See how sample widgets are added and follow the same structure.
Naming Conventions¶
Library Name¶
Please use the following naming pattern when creating a new library in the workspace,
<Widget namespace>/<Widget library name prefix>-<Product area name>
- Widget namespace : Use the namespace '@ifsworld' for all widget libraries
- Widget library name prefix : Use the prefix 'widgets'
- Product area name : Name / Identifier of the product area that the widget library belongs to
Examples:
- @ifsworld/widgets-fnd
- @ifsworld/widgets-hcm
- @ifsworld/widgets-asset
Widget ID¶
Every widget must have a unique ID, so the following naming pattern must be followed when creating the ID for the widget,
<Unique widget identifier><Widget suffix (same for all widgets)>
- The first part of the widget is the unique name of the widget
- Use the common suffix "Widget" at the end of the widget ID
Examples:
- TimeReportingShortcutsWidget
- RecentDocumentsWidget
Client and Projection Files Connected to a Widget¶
In some cases, a .projection
file is used to create the data structures and data sets required to get data into the widgets. Also, a .client
file can be used to utilize marble field translations for widget translation needs (Please refer to the Translations
section for more details on enabling translations for the widgets). It is recommended to create new client and projection files for each widget to include the widget-related code.
A widget can be connected to one projection only. Through this projection, the widget can communicate with the IFS backend through Get, Post, Patch, Delete requests or odata functions and actions. If there is a connected projection in the widget metadata, projection grants are checked for the current user at IFS Application startup. The widget will be available to the user only if the projection is granted.
Projection name¶
The name of the projection file should be the same as the widget ID with the common suffix Handling
at the end to make the file consistent with the other projection files in the system in general.
Example:
- Widget ID : RecentDocumentsWidget
- Projection : RecentDocumentsWidgetHandling.projection
Client name¶
The name of the client file should be the same as the widget ID.
Example:
- Widget ID : RecentDocumentsWidget
- Projection : RecentDocumentsWidget.client
Widget Metadata¶
Widget metadata includes important metadata related to the widget.
export const RecentDocumentsWidgetMetadata: Metadata = {
id: 'RecentDocumentsWidget',
title: 'WidgetTitle', //translation key
description: 'WidgetDescription', //translation key
width: WidgetWidth.Full,
height: WidgetHeight.Dynamic,
keywords: ['test', 'widget','framework'],
projection: 'RecentDocumentsWidgetHandling',
icon: 'education',
translations: {
type: WidgetTranslationType.MarbleClientMetadata,
client: 'RecentDocumentsWidget',
list: 'TranslationsList',
defaultTranslations: translations
},
config: [
{
id: 'input-1',
type: WidgetConfigInputType.Text,
value: 'Default Name',
},
{
id: 'input-2',
type: WidgetConfigInputType.Number,
value: '37',
}
]
};
Property | Description |
---|---|
id | Unique identifier for the widget, use the guidelines shown in the previous section when defining the widget Id |
title | Property name that contains the translatable text for the widget title (in Marble client file or default translations file) |
description | Property name that contains the translatable text for the widget description (in Marble client file or default translations file) |
width | Width of the widget (Full or Half), default value is Full |
height | Height of the widget (Medium or Dynamic), default value is Dynamic |
keywords | Keywords useful to search for the widget |
projection | The Marble projection file connected with the widget that contains the data structures/sources |
translations | Used to define the details related to translations |
config | Used to define the details related to widget configurations |
Translations¶
Property | Description |
---|---|
type | Type of source for translations. Either Marble client metadata (WidgetTranslationType.MarbleClientMetadata) or JSON file in the code |
client | Marble client file name that contains the translations for the widget |
defaultTranslations | Name of the default translations JSON file inside the code structure. The recommended name is 'translations.json' |
Config¶
Best Practices¶
Committing Code Changes¶
Commit Message Format¶
semantic-release uses the commit messages to determine the consumer impact of changes in the codebase. Following formalized conventions for commit messages, semantic-release automatically determines the next semantic version number, generates a changelog and publishes the release.
Use the provided commitzen configuration in the project to add new commits. It will make sure that the commits are in the correct format which helps semantic release to figure out the next release version. Use command npm run commit
Don't Use Manual Commits¶
- For a patch release use
fix
- For a minor release: use
feat
- For a major release use
feat
and add an additional comment when asked for BREAKING_CHANGE?
Publishing widget artifacts¶
The process of publishing the widget artifacts as node packages depends on whether a widget artifact library (Bitbucket repository) is already available to publish the widget into, or whether you need to create a new repository for your product area to publish the widget artifacts.
If the widget library exists, then you don’t need to do anything, in particular, to publish the widgets, committing the code with the proper commit messages above and merging the code to the master branch of the workspace repository will trigger the automated pipeline to publish the widget artifacts into the proper widget library.
If it is required to create a new widget repository to publish the widget artifacts, then follow the below guidelines to create a new repository.
Tasks :
- Create artifacts repository and repo name to
publish.sh
- Add new library to
package.json
build script - Add library to
lerna.json
publish.sh
should be given execute access in the pipeline
Package releases are automated after the above configurations. Semantic release (npm: semantic-release ) which utilizes the semantic versioning spec (Semantic Versioning 2.0.0 ) is used for package versioning.