Workspace / UI Builder - Add Action, Modal & Related Lists

Andy Smith2
Tera Contributor

Hi Folks

We are having a tough time right now trying to deliver a very common design pattern. A great example of the design pattern is the new Risk Workspace which we believe is built using the Now Experience / UI Builder combination rather than the original Workspace stack.

find_real_file.png

In this exemplar, we have:

  • A parent object, in this case a Test template
  • The details of the Parent record are displayed as a /record Page with the familiar Related Lists as Tabs
  • We have a Content References related list which lists the related items
  • We want to use the Add and Remove related list action buttons to manage the related items.

When clicking the Add button, the following modal is presented:

find_real_file.png

We're struggling to work out what is driving this Add modal and how to configure it.

Some working examples show that it is implemented as a UXF Client Action, others show it as Implemented as a bespoke UI Component (e.g. BCM). There doesn't seem to be a generic Now Experience component that we could use and simply configure for our own data relationships.

So, I have a few questions on this topic:

1) Can someone from the Product team(s) advise on how list-based modals should be implemented (e.g. bespoke component, UXF action, other)?

2) Is there any documentation that could be shared on "How to" build these commonly occurring interfaces?

3) Is there any plan to provide the Development community with a generic, re-usable interface, ideally one that can be configured with UI Builder? We're trying to avoid creating bespoke components only to find that a better/standard one is coming down the core product delivery pipeline.

4) At this risk of sounding greedy, could such a generic, re-usable component include a Search/Filter bar to avoid the need for users to page through potentially many pages to find and select the related record that they wish to Add.

Apologies for the long read - any help would be very much appreciated. 

Thanks in advance

Andy

 

15 REPLIES 15

Michael Fry1
Kilo Patron

Those related list ui actions are configured under Workspace Experience (app) > Related List Actions. 

2 - you're referring to common workspaces? If yes, start building in App Engine Studio

Not sure I can't answer your other questions.

Andy Smith2
Tera Contributor

Thanks for your reply, Michael, and apologies for the delay in responding. 

We've made some progress on this ....

It's taken us into territory that required an understanding of extension points and payload content definition... which my technically exceptional colleague, Dave, has identified. 

I know that Dave has documented what he's discovered and done .. I'll share it here in the hope it might help someone else who might be trying to do the same thing !

Many thanks

Andy

David Hubbard
Tera Guru

So here is how I have managed to configure Add/Remove M2M functionality within the standard UI Builder "Record" page.

Firstly I think the underlying technology used here is "Multi-Record Associator" (MRA) which appears:

a) to be a "Workspace" feature (there is a key list of "Component Attributes" in 2b - which we will come back to) and

b) to be wrapped in Now Experience and accessible via an "mra" routing.

Secondly I worked this out by looking closely at ServiceNow's GRC (Risk Management) application which is a built with Now Experience and we have installed on our VEN instance.

For a TL:DR here are the tables involved

  • Payload Definition
    • sys_declarative_action_payload_definition
    • This is a template definition for the structure of the event data - for this the MRA attributes are required.
  • Action Assignment
    • sys_declarative_action_assignment
    • Holds the event payload specific content for template fields
  • Event Mapping
    • sys_ux_addon_event_mapping
    • Issue the specific routing to MRA component

Steps

1. Define your M2M table - which simply has references to each side of the relationship

For the "Add Button"

2. Define the "Payload Definition" template - which can be used commonly for all M2M Related Lists

sys_declarative_action_payload_definition

find_real_file.png

{
  "label": "{{label}}",
  "userGivenTable": "{{userGivenTable}}",
  "table": "{{table}}",
  "parentRecordSysId": "{{parentRecordSysId}}",
  "relatedListName": "{{relatedListName}}",
  "hideSelectAll": "{{hideSelectAll}}",
  "parentFieldName": "{{parentFieldName}}",
  "referencedFieldName": "{{referencedFieldName}}",
  "extensionPoint": "{{extensionPoint}}",
  "view": "{{view}}",
  "columns": "{{columns}}",
  "type": "{{type}}"
}

As noted above these are MRA attributes

3. Add an Action Assignment

sys_declarative_action_assignment

This is linked to a) the M2M table and b) to the payload definition (above) and the needs to provide the actual values for the payload.  Luckily none of these here are dynamic!

Note: UXF Client action - linked (via "Specify Client Action") to the "Payload Definition" (above) - the name of this threw me for a while as it is not really an "action", just a template for the Attributes/Payload.

find_real_file.png

 

Obviously the values here will need to adjust to your tables

4.  Add an Event Mapping

sys_ux_addon_event_mapping

Now I confess here I did an "Insert and Stay" on a GRC entry which gave me this

find_real_file.png

Basically

  • the event fired is "RECORD#OPEN_MODAL" on the "Record" Macroponent
    • careful if you have cloned the "Record" Page as you may see multiple listed
  • with payload indicating - "route" = "mra"
    • Somewhere in Now Experience the "Multi-Record Associator" lives - but I haven't found a page for it!
  • and field data mapped from the Declarative Action.

The full content of the Target Payload Mapping for copying is below.

For the "Remove" button - this is a little simpler as only one entry required

5.  Add a "Remove" Action Assignment

sys_declarative_action_assignment

This is a "Server Script" with a "current.deleteMultiple()" 

find_real_file.png

Hopefully with those the "Add" and "Remove" buttons will appear on related list AND load the MRA selector as a Modal.

As Andy has noted - the is a limitation with this approach as the MRA does not include any filtering/search capability so this may not be appropriate for selection from long lists.

Target Payload mapping

{
  "type": "MAP_CONTAINER",
  "container": {
    "route": {
      "type": "JSON_LITERAL",
      "value": "mra"
    },
    "size": {
      "type": "JSON_LITERAL",
      "value": "lg"
    },
    "fields": {
      "type": "MAP_CONTAINER",
      "container": {
        "label": {
          "type": "EVENT_PAYLOAD_BINDING",
          "binding": {
            "address": ["label"]
          }
        },
        "userGivenTable": {
          "type": "EVENT_PAYLOAD_BINDING",
          "binding": {
            "address": ["userGivenTable"]
          }
        },
        "table": {
          "type": "EVENT_PAYLOAD_BINDING",
          "binding": {
            "address": ["table"]
          }
        },
        "parentRecordSysId": {
          "type": "EVENT_PAYLOAD_BINDING",
          "binding": {
            "address": ["parentRecordSysId"]
          }
        },
        "parentFieldName": {
          "type": "EVENT_PAYLOAD_BINDING",
          "binding": {
            "address": ["parentFieldName"]
          }
        },
        "referencedFieldName": {
          "type": "EVENT_PAYLOAD_BINDING",
          "binding": {
            "address": ["referencedFieldName"]
          }
        },
        "extensionPoint": {
          "type": "EVENT_PAYLOAD_BINDING",
          "binding": {
            "address": ["extensionPoint"]
          }
        },
        "view": {
          "type": "EVENT_PAYLOAD_BINDING",
          "binding": {
            "address": ["view"]
          }
        },
        "columns": {
          "type": "EVENT_PAYLOAD_BINDING",
          "binding": {
            "address": ["columns"]
          }
        },
        "type": {
          "type": "EVENT_PAYLOAD_BINDING",
          "binding": {
            "address": ["type"]
          }
        },
        "hideSelectAll": {
          "type": "EVENT_PAYLOAD_BINDING",
          "binding": {
            "address": ["hideSelectAll"]
          }
        },
        "relatedListName": {
          "type": "EVENT_PAYLOAD_BINDING",
          "binding": {
            "address": ["relatedListName"]
          }
        }
      }
    },
    "params": {
      "type": "JSON_LITERAL",
      "value": {}
    }
  }
}

 

I'm trying this out, and got my button to show but it seems like there's some disconnect with the UX Event Mapping triggering the modal. I grabbed the sys_id from the page, has anyone else come across this?