Reports

Overview

Reports provide a way to generate dynamic documents based on templates (which can be made available to other modules).

Capabilities

Capability

Support

Comment

Generate report to PDF format

Supported feature

See how to generate report

Generate report to CSV format

Supported feature

See how to generate report

Generate report to plain text format

Supported feature

See how to generate report

Using asset into template

Supported feature

See how to include assets

Usable from script

Not supported feature

This feature is currently not supported. In case of interest please contact us at info@swissdotnet.ch

Direct downloading from frontend

Supported feature

See downloading from web

Generating content for module communication

Supported feature

Examples

Define a report with a FTL template

Overview

A report is a global term to identify any content generated by associating a FreeMarker Template Language (FTL) template and a data source. Then, the report generated can be used as the source content to generate a file. This implies that a report doesn’t represent an actual file but only his content.

External tools

Note

A template must be a valid FTL template. If any structural issues exist within the template, they will be detected when trying to push your configuration.

Generating report

Reports are defined by two entities :

  • template.reports : this entity is the main part of a report. It provides all the metadata for the report and the link to the actual FTL template

  • template-name.ftl: FTL template file. FTL tags can be used to define loops, condition, data mapping and so on. These tags allow to make dynamic template that can generate reports with dynamic data.

Reports are generated by using action, triggered either by an user interaction by referencing these actions in a menu.web or automatically based on a value changes or a script execution.

Action: Generation request

Use an action with a type as GENERATE_REPORT to generate a report. The payload must contain :

  • templateId: the id of the template used. This reference a template.reports file, not to a FTL template.

  • name: Name of generated report. Be aware that every space in the name is replace by “_”. The current date is automatically appended at the end of the name to differentiate the different generated reports.

  • data: Data source to generate the report with. The structure of the data must be in accordance with the template.

If the action request is successful, the returned result object will contain a content property with the generated report. A report is composed of these properties:

  • result.content.template: template id used for the report

  • result.content.name: name of the report

  • result.content.format: type of media generated (PDF/CSV/PLAIN)

  • result.content.report: contains the PDF generated data in base64. Only contains something if format is PDF

  • result.content.parsed: contains the parsed version of the template. This represents the template after all data were merged in

Download from frontend

A menu output called download can generate a file based on any content you provide to it. Menu outputs can be used after an action was send. Therefore, you can follow the generation request action by an download output and feed this output with the result from the action.

For a download output, you need to provide the following inputs:

  • content: source content for the file to be generated. From an generation request action, you can retrieve result.content.report if the format of the report is PDF and result.content.parsed for any other type of report.

  • format: media type of the file. From an generation request action, you can retrieve result.content.format.

  • filename: name of the file when downloading. From an generation request action, you can retrieve result.content.name to use the name of the report, or use any other name.

Example

Action: download pre-generated report

Use an action with a type as DOWNLOAD_REPORT to fetch an existing report. Downloading a report only returns the report data. In order to actually download the report into a file, you will need to use the download output, like explained for the generation request action.

The payload of this action must contain :

  • documentId: Id of the database document representing the report.

Warning

You have to provide the id of the database element representing the report, which implies that you have to retrieve this information first. Therefore, this action is meant to be used inside a menu.web referenced by a ReportsList widget.

If the action request is successful, the returned result object will contain a content property with the generated report. A report is composed of these properties:

  • result.content.template: template id used for the report

  • result.content.name: name of the report

  • result.content.format: type of media generated (PDF/CSV/PLAIN)

  • result.content.report: contains the PDF generated data in base64. Only contains something if format is PDF

  • result.content.parsed: contains the parsed version of the template. This represents the template after all data were merged in

Example :

{
    "label": "Download",
    "icon": "file_download",
    "context": [
        {
            "type": "ReportsList",
            "action": "root.reports.actions.download",
            "condition": "${reports.selected}.length === 0",
            "input": {
                "documentId": {
                    "extract": "reports.clicked.documentId",
                    "as": "string"
                }
            },
            "output": [
                {
                    "operation": "download",
                    "input": {
                        "content": {
                            "extract": "result.content.parsed",
                            "as": "string"
                        },
                        "format": {
                            "extract": "result.content.format",
                            "as": "string"
                        },
                        "filename": {
                            "extract": "result.content.name",
                            "as": "string"
                        }
                    }
                }
            ]
        }
    ]
}

Accessing resources

In order for the module to generate a report based on a template, it must have access to them. Then, all your FTL templates files (and any other assets used inside a template) must be part of the module resources. To do so, you must define the resources inside the module.resources file.

Assets usage

When adding an asset into a template (images,fonts,…), the asset must be part of the module resources. Then, when using them in a template, you need to use the relative path to the asset from the configuration directory as its source. For example, if you have an image called logo.png in the root/template/images directory, then the source must be root/template/images/logo.png, no matter where the template is in the configuration. The source can’t be an absolute path.

Custom OnSphere template API

Customs methods were implemented to simplify operations that you will most likely use in every template. All of these methods are accessible via an OSP object that is part of the template data.

Getting severity

This returns an object containing the severity.ospp and severity.reports files content. To have access to this method, you need to create a severity.reports file alongside the targeted severity.ospp.

To call this method inside a FTL template :

${osp.getSeverityById("root.alarms.severity.clear")}

This returns an object with (values with * cannot be empty):

  • name*: The name of the severity

  • description*: A description of the severity

  • severity*: The numerical value associated with this severity

  • fallback*: If set to true this severity will be used as fallback for any invalid/unknown severity

  • fgColor: The color of the text for alarms of this severity as an hex string

  • bgColor: The color of the background for alarms of this severity as an hex string

  • fgHiColor: The color of the text for alarms of this severity when selected as an hex string

  • bgHiColor: The color of the background for alarms of this severity when selected as an hex string

Get severity by severity

This method is similar to the precedent one but instead of using the severity id to find it, you can use its numerical value. To have access to this method, you need to create a severity.reports file alongside the targeted severity.ospp.

To call this method inside a FTL template :

${osp.getSeverityBySeverity(200)}

This returns an object with (values with * cannot be empty):

  • name*: The name of the severity

  • description*: A description of the severity

  • severity*: The numerical value associated with this severity

  • fallback*: If set to true this severity will be used as fallback for any invalid/unknown severity

  • fgColor: The color of the text for alarms of this severity as an hex string

  • bgColor: The color of the background for alarms of this severity as an hex string

  • fgHiColor: The color of the text for alarms of this severity when selected as an hex string

  • bgHiColor: The color of the background for alarms of this severity when selected as an hex string

Get Filter by Id

This returns an object containing the filter.ospp and filter.reports files content. To have access to this method, you need to create a filter.reports file alongside the targeted filter.ospp.

To call this method inside a FTL template :

${osp.getFilterById("root.alarms.filter.all")}

This returns an object with (values with * cannot be empty):

  • name*: The name of the filter

  • description*: A description of the filter

Get view by Id

This returns an object containing the view.ospp and view.reports files content. To have access to this method, you need to create a view.reports file alongside the targeted view.ospp.

To call this method inside a FTL template :

${osp.getViewById("root.alarms.view.default")}

This return an object with (values with * cannot be empty):

  • name*: The name of the view

  • description*: A description of the view

  • liveColumns*: The column to show on the live table

  • historyColumns*: The column to show on the history table

Convert timestamp in nanoseconds to a full date and time representation

This returns a date from an timestamp in nanoseconds. Every date or time in OnSphere is expressed in nanoseconds. You can use this method and the built-ins for dates values from FTL to handle dates as you want.

To call this method inside a template:

${osp.convertNanoToDatetime(alarm.firstTimestamp)}

This returns a date as a string that you might want to transform into a date.

${osp.convertNanoToDatetime(alarm.firstTimestamp)?datetime.xs}

You can use the built-ins functions:

Date and time: ${osp.convertNanoToDatetime(alarm.firstTimestamp)?datetime.xs}
Date: ${osp.convertNanoToDatetime(alarm.firstTimestamp)?datetime.xs?date}
Time: ${osp.convertNanoToDatetime(alarm.firstTimestamp)?datetime.xs?time}

Retrieves data from analytics module

This returns the result of the given query with the given query filters. These parameters can be easily retrieved from a Chart widget and by using a menu to generate the report while passing the widget context, which contains chart.query (string) and chart.queryFilters (array of filters).

To give a report those parameters using a Chart widget menu:

"type": "Chart",
"action": "root.reports.osp.actions.generate",
"condition": "true",
"input": {
    "template": {
    "expression": "'root.reports.osp.templates.csv'"
    },
    "data.query": {
    "extract": "chart.query",
    "as": "string"
    },
    "data.queryFilters": {
    "extract": "chart.queryFilters[*]"
    }
}

To call this method inside a template:

${osp.analyticsQuery(queryId, queryFilters)}

This returns the result of the query grouped by fields name, in the form of a map like {[key = fieldname]: [value = array of points for this field]}.

Retrieves entries from a collection

You can retrieve entries from a collection based on a schema and a list of ids.

To gather those information from a Collection table, you can extract them like:

"data.schema": {
  "extract": "schema",
  "as": "string"
},
"data.documents": {
  "extract": "rows.selected[*]._id"
}

To call this method inside a template:

${osp.collectionsListById(schema, documents)}

This returns directly the list of entries.

You can retrieve the historic with every entry as well by using a different method that requires a schema and a list of ids as well.

${osp.collectionsListByIdWithHistory(schema, documents)}

This returns the list of entries with a property history which contains the full historic (list).

Get an user preferences attribute value for a given user and attribute name

This returns either the value associated with the given attribute for the given user or the user given when the attribute is not found or any other error occurs. A defaultValue can be given (not mandatory) as a return value if the given attribute doesn’t exist for the user or if any other issues occurs.

To call this method inside a template:

${osp.getUserAttribute(user, attribute, defaultValue)}