Create menu with form prompt as inputs and outputs

Prerequisites

Modules

Checkout branches

git checkout origin/osp-alarms-configuration .
git checkout origin/osp-web-configuration .
git checkout origin/osp-scripts-configuration .
git checkout origin/osp-collections-configuration .

Description

The tutorial guides you through the creation and utilization of menus that shows you the different usages of forms prompts. This tutorial assumes you are already familiar with the concepts of dashboards, alarms table widgets and menus. This tutorial will focus on the creation of different menus, showcasing forms prompts. if you are not familiar with some of these concepts, you can follow this other example first.

We will make use of an input form prompt to create and edit an entry of a collection and link this entry to the alarm. Then, once the collection and alarm are bounded together, we will use an output form prompt to display to the user the content of the collection.

In this tutorial, we will be creating alarms reports, a simple collection that contains a description and other information that we will be retrieving directly from the alarm.

Steps

1. Create a menu to create an new report using a form prompt input

The first case demonstrated here is how to use a form prompt input in order to ask the user to complete a form, which will be used to create a new report.

1.1 Create the reports collection and form

This part assume you have a basic knowing of collections. If not, feel free to follow this example before.

First, we need to define the collection and the related form we will be using. The alarm_reports collection contains:

  • no: auto-incremented number

  • description: description (string)

  • alarm.location: the location of the alarm

  • alarm.summary: the summary of the alarm

Here are the different files we need to define this collection.

root/collections/reports/schema.collections

{
    "moduleId": "modules.collections.collections-1",
    "collectionName": "alarm_reports",
    "indexes": [
        {
            "name": "no",
            "index": "{'no': 1}"
        },
        {
            "name": "description",
            "index": "{'description': 1}"
        }
    ],
    "filters": [
        {
            "id": "all",
            "query": "{}"
        }
    ],
    "autoIncrementFields": ["no"]
}

root/collections/reports/schema.ospp

{
    "schema": {
        "type": "object",
        "properties": {
            "no": { "type": "integer" },
            "description": { "type": "string" },
            "alarm": {
                "type": "object",
                "properties": {
                    "location": {"type": "string"},
                    "summary": {"type": "string"}
                }
            }
        },
        "required": ["description"]
    },
    "filters": [
        {
            "id": "all",
            "name": "All"
        }
    ]
}

root/collections/reports/schema.web

{
    "moduleId": "modules.web.web-1",
    "name": "Alarms reports",
    "displayedProperty": "description",
    "views": [
        {
            "id": "default",
            "name": "Default",
            "reorderable": true,
            "sort": [
                {
                    "field": "no",
                    "direction": "desc"
                }
            ],
            "columns": [
                {
                    "name": "Number",
                    "field": "no",
                    "position": 0
                },
                {
                    "name": "Description",
                    "field": "description",
                    "position": 1
                }
            ]
        }
    ]
}

After, we need a to define a form for this collection. We will be using this form as well for the prompts of our menu.

root/collections/reports/form/form.web

{
    "moduleId": [
        "modules.web.web-1"
    ],
    "name": "Alarms reports",
    "description": "",
    "bindings": {},
    "rights": [],
    "schema": "root.collections.reports",
    "ui": {
        "type": "VerticalLayout",
        "elements": [
            {
                "type": "HorizontalLayout",
                "elements": [
                    {
                        "type": "Control",
                        "scope": "#/properties/no",
                        "label": "Report No."
                    },
                    {
                        "type": "Control",
                        "scope": "#/properties/description",
                        "label": "Description"
                    }
                ]
            },
            {
                "type": "Control",
                "scope": "#/properties/alarm",
                "label": "Alarm infos"
            }
        ]
    },
    "initialValue": {
    },
    "submit": {
        "destination": "Request",
        "type": "Deferred"
    }
}

1.2 Create a script to update the alarm after the report is created

We will be using a script to update the alarm after the report is created. We add to the additional data of the alarm the id of the report to keep a trace of which report is associated to this alarm.

To do so, we can get the report id by getting collectionId which is passed into the script alongside the other inputs.

root/scripts/manual/detached.scripts

{
    "moduleId": "modules.scripts.scripts-1",
    "accessedValues": [],
    "scheduledExecutions": [],
    "sourceFile": "root/scripts/manual/new_report.js"
}

root/scripts/manual/new_report.js

main()

function main() {
    const params = trigger.parameters;
    const colId = params[0]["collectionId"];
    const alrId = params[0]["alarmId"];

    alarms.editAdditionalData(alrId, {collectionId: colId})
}

1.3 Define the menu to create the report using a prompt

We setup the prompt with :

  • formId: id of the form we created before

  • formSave: set as true in order to create the report automatically when the user submit the form. Alternatively, you can disable this and create yourself the report in the script, using the form data transmitted as form.

  • data: initial data passed to the form. With this, we can set the values of alarm location and summary in the form by retrieving these from the alarm directly.

When the user completes the form and submit it, the report should be created automatically and, in our script, we modify the alarm to append the report id.

root/alarms/menus/menu.web

        {
            "label": "Manually generate report",
            "icon": "note_add",
            "context": [
              {
                "type": "AlarmTable",
                "action": "root.alarms.actions.run_script",
                "condition": "${alarms.selected}.length === 0 && !${alarms.clicked}.additionalData?.collectionId",
                "scopes": ["Click"],
                "input": {
                    "scriptId": {
                        "expression": "'root.scripts.manual'"
                    },
                    "form": {
                        "prompt": {
                            "type": "FORM",
                            "formId": "root.collections.reports.form",
                            "formSave": true,
                            "labels": {
                                "title": "Alarm report",
                                "message": "Please fill the following form",
                                "save": "Save",
                                "cancel": "Cancel"
                            },
                            "data": {
                                "alarm": {
                                    "location": {"extract": "alarms.clicked.location", "as": "string"},
                                    "summary": {"extract": "alarms.clicked.summary", "as": "string"}
                                }
                            } 
                        }
                    },
                    "alarmId": {
                        "extract": "alarms.clicked._id",
                        "as": "string"
                    }
                }
              }
            ]
        },

Here an example on how it looks :

../../_images/input-form-prompt.png

2. Create a menu to edit the report using a form prompt input

By passing collectionId in the prompt, we can load the report previously generated and allow the user to modify it directly. Upon saving, the report is automatically updated (because of formSave as true). Therefore, this menu doesn’t need any action.

root/alarms/menus/menu.web

        {
            "label": "Update alarm report",
            "icon": "note_add",
            "context": [
              {
                "type": "AlarmTable",
                "condition": "${alarms.selected}.length === 0 && !!${alarms.clicked}.additionalData?.collectionId",
                "input": {
                    "form": {
                        "prompt": {
                            "type": "FORM",
                            "formId": "root.collections.reports.form",
                            "collectionId": {
                                "extract": "alarms.clicked.additionalData.collectionId",
                                "as": "string"
                            },
                            "formSave": true,
                            "labels": {
                                "title": "Alarm report",
                                "message": "Please fill the following form",
                                "save": "Save",
                                "cancel": "Cancel"
                            }
                        }
                    }
                }
              }
            ]
        },

3. Create a menu to automatically create a report and display it to the user using a form prompt output

Here, we create the report automatically in a script, without any input from the user. Then, we use an output form to display the generated report.

To do so, we can either:

  • Return the report id at the end of the script and use it to set the collectionId of the output. If you want to generate multiple reports and open them all at once, you can pass an array of ids as collectionId.

  • Return an object with the data we want to display in the form. This works too if the data we want to display is not from a collection.

In this example, we pass the full data object as following:

root/scripts/auto/new_report.js

main()

function main() {
    const params = trigger.parameters;
    
    const alrId = params[0]["alarmId"];
    const location = params[0]["location"];
    const summary = params[0]["summary"];

    const resInsert = collections.insert("root.collections.reports", {"description": "Auto generated", "alarm": {"location": location, "summary": summary}});

    alarms.editAdditionalData(alrId, {collectionId: resInsert.content.documentId});

    const resGet = collections.get("root.collections.reports", resInsert.content.documentId);

    execution.reportResult("OK", {data: resGet.content});
}

root/alarms/menus/menu.web

        {
            "label": "Automatically generate report",
            "icon": "note_add",
            "context": [
              {
                "type": "AlarmTable",
                "action": "root.alarms.actions.run_script",
                "condition": "${alarms.selected}.length === 0 && !${alarms.clicked}.additionalData?.collectionId",
                "scopes": ["Click"],
                "input": {
                    "scriptId": "root.scripts.auto",
                    "alarmId": {
                        "extract": "alarms.clicked._id",
                        "as": "string"
                    },
                    "location": {"extract": "alarms.clicked.location", "as": "string"},
                    "summary": {"extract": "alarms.clicked.summary", "as": "string"}
                },
                "output": [
                    {
                        "operation": "form",
                        "input": {
                            "formId": "root.collections.reports.form",
                            "formSave": false,
                            "data": {
                                "extract": "result.content.data",
                                "as": "object"
                            },
                            "labels.title": "Alarm reports",
                            "labels.message": "",
                            "labels.save": "Save",
                            "labels.cancel": "Close"
                        }
                    }
                ]
              }
            ]
        }

Add this example in your configuration

You can directly use the following command to add this example into your configuration:

git checkout origin/example-dashboard-menus-form-input-prompt-collection .