DOC
widgets are developed using Angular framework and Clarity HTML/CSS framework. If you are not familiar with Angular development here are some useful links:
Most of DOC
Widgets can be customized by implementing custom GeneWidgetControllers. These controllers let you override part of the Widgets default behaviors, such as titles, buttons, menu items, data loading, etc.
When a project is created, the web modules contains samples of custom GeneWidgetControllers for the different widgets under the following folder web/src/app/module/sample-controllers
.
For example, it is possible to override the colors generated to represent entities. This can be done by registering an implementation of GeneColorPalette associated to an entity type, or by setting the color hint for entities by specifying the corresponding business key. In the following example, a custom color is set for one Plant, and will be used in tables, instance pickers and charts (provided that the category field is set to Plant instance). More examples are available in SampleControllersModule.
colorService.setEntityColorHint('Plant', [ {fieldName:'plantId', fieldValue:'Paris'}, {fieldName:'country.id', fieldValue:'FRA'}, ], '#765fb6');
When we need to write a custom widget controller, we need to check a few things. First, the widget needs to support custom widget controllers. This capability it declared in the widget Manifest.
export interface GeneWidgetManifest { ... /** * When true the widget supports providing custom controllers */ supportsCustomController?: boolean; }
When a Widget is compatible with custom Controllers, it usually provides a specific interface to override some of its specific behaviors (in addition to standard title, buttons and menu items customizations). The corresponding interface can be found in the Widget documentation or declaration.
Here is a list of compatible widgets and their controller classes:
GeneKpiComponent (using GeneKpiController controller class)
GeneTableComponent (using GeneTableController controller class)
GeneChartComponent (using GeneChartController controller class)
GeneNavigationButtonComponent (using GeneNavigationButtonController controller class)
GeneDataExplorerComponent (using DefaultWidgetController controller class)
GeneJobDetailsComponent (using DefaultWidgetController controller class)
GeneJobListComponent (using DefaultWidgetController controller class)
GenePivotTableComponent (using DefaultWidgetController controller class)
GeneScenarioListComponent (using DefaultWidgetController controller class)
GeneScenarioTimelineComponent (using DefaultWidgetController controller class)
GeneWorkspaceListComponent (using DefaultWidgetController controller class)
Note: All widgets inheriting from GeneBaseDataWidget are supporting custom controllers implementing DefaultWidgetController, with a minimal customization of title, buttons and menu items.
For example, the GeneTableComponent exposes a specific controller interface: GeneTableController.
/** * This component provides a configurable paginate table component wrapping an ag-grid. * * ... * * The widget is compatible with Views and Dashboard and compatible with custom GeneWidgetController mechanism * using GeneTableController interface. */ export class GeneTableComponent<T extends GeneEntity> extends GeneBaseDataWidgetComponent<GeneTableWidgetConfiguration, T[], GeneTableController<T>>
/** * This interface describes a GeneTable controller that allows to override parts of the *DOC
Table behavior. * * @param T GeneEntity type being loaded by the GeneTable instance. */ export class GeneTableController<T extends GeneEntity> extends DefaultWidgetController<GeneTableComponent<T>> { /** * This method allows to override a single ColDef used by the currentDOC
Table configuration, * to configure, for example, some custom renderers, editors. * * This method is being called each time the gene-table configuration is refreshed. * * @param column ag-grid column definition, the instance that is being bound to ag-grid * @param field optional associated field of the entity * @param editionMode current table edition mode */ customizeColumn?: (column: ColDef, field?: GeneField) => void; /** * This method allows to define additional columns. * * This method is being called every timeDOC
Table configuration changes and columns * get recomputed. * * Adding additional ColDef with ValueGetter is a solution to implement computed columns. * * Note that additional columns are not editable. * * @param editionMode current table edition mode. * @return additional ColDef columns to be displayed. */ additionalColumns?: (editionMode: GeneEditionMode) => ColDef[]; /** * This method allows to override any of the available ag-grid settings of the GridOptions generated by the Gene-Table component. * * Note that some settings may conflict with the GeneTable component internal implementation. * * @see www.ag-grid.com/javascript-grid-reference-overview/ * @param options GridOptions instance bound to the internal ag-grid component. */ customizeGridOption?: (options: GridOptions) => void; /** * This method allows to override default Data Grid column order in all modes. * * This method is being called each time the Data Grid configuration is refreshed or edition mode changes. * * @param columns the sorted columns to display. * @param editionMode the current Gene-Table edition mode. * @return the modified sorted columns to display */ processColumns?: (columns: ColDef[], editionMode: GeneEditionMode) => ColDef[]; /** * This method allows to override the data loading process. * * @param configuration current GeneTable configuration * @param currentContext the context to be used to load the data, which is by default the current application context (current selected scenarios and filters). * @param pageNumber page to request, starting from 0 * @param pageSize max number of elements to fetch in the page * @param agGridSort current ag-grid user defined sorts * * @return data page */ loadData?: (configuration: GeneTableWidgetConfiguration, currentContext: GeneContext, pageNumber: number, pageSize: number, agGridSort: AgGridSort, agGridFilters: AgGridFilterModel) => Observable<Page<T>>; /** * This method allows to perform some processing to the data before they are being displayed in the Data Grid. * For example, you can enrich T type with additional information. This is a way to implement processed fields. * * This method is being called by GeneTable when the data are being loaded. * * @param data the data to display in the Data Grid. * @return the processed data. */ processData?: (data: T[]) => Observable<T[]>; }
This custom controller interface let us, override parts of the features, and in the following example we will provide two things:
Use custom colors for rows coloring
An extra button to refresh the data
/** * A Sample Table Controller to customize rows color and provide a refresh button */ export class SampleCustomColorsController extends GeneTableController<GeneEntity> { constructor(private widget: GeneTableComponent<GeneEntity>) { super(widget); } // Customize rows coloring // See www.ag-grid.com/javascript-grid-row-styles/ for more details customizeGridOption = (options: GridOptions) => { options.getRowStyle = (params) => { if (params.node.rowIndex % 2 === 0) { return { background: '#FF8888' }; } else { return { background: '#d1f1da' }; } }; } // Customize the toolbar buttons customizeToolbarElements = (toolbarElements: GeneToolbarElement[]) => { return of(toolbarButtons.concat([ { id: 'refresh', type: 'button', icon: 'refresh', label: 'Refresh', title: 'Refresh Data', clickHandler: (button, $event) => this.widget.requestLoadData(), }])); } }
Once we have a controller ready, we need to register it in the application GeneCustomWidgetFactoryService, so it will be available when we configure the corresponding widget.
Registration of the Controller is done through the controller module.
export class SampleWidgetsModule { constructor(customWidgetFactory: GeneCustomWidgetFactoryService) { // Register a Custom Controller for GeneTableComponent customWidgetFactory.registerCustomWidgetController(GeneTableComponent.MANIFEST, 'SampleCustomColorsController', (widget: GeneTableComponent<GeneEntity>) => new SampleCustomColorsController(widget)); } }
When using the web client application, you can now configure GeneTable widgets to use the custom controller through the configuration wizard.
![]() |