I previously wrote a post about using UI Actions on the Record View in Workspace, and received some questions about actions in the list view. As I started writing this, I realized there is so much to cover with Declarative Actions, so decided to break this up into multiple parts. I'll start with a summary of what Declarative Actions are, then go into a use case using a Related List Action Assignment to add and remove records.
Declarative Actions allow developers to add functionality such as buttons or icons to Workspace lists, forms, fields, and related lists. By using Declarative Actions you can add buttons or icons that perform an action on the screen/record you're currently on rather than having to navigate to another screen. To my knowledge List UI Actions do not work in Workspace, as there are only two options in UI Actions for Workspace at the moment: Workspace Form Button, Workspace Form Menu, so Declarative Actions have to be used for any action taken on lists.
Declarative Action Model Definitions
The Action Model field on a Declarative Action Assignment determines where the functionality will be placed. Action Models are found in the sys_declarative_action_model_definition table. The field is read only on form and list view, so make sure you go through the appropriate module under Workspace Experience > Actions & Components.
List view - Only buttons can be added to lists using the List Action Model. Honestly, doing server scripts from here will be much easier than trying to launch modals, as I'm assuming most of the out-of-the-box components aren't really configured for lists (I see interceptor, and template selector in my PDI) so custom components will need to be created here for anything that isn't server side in my opinion.
Record View - There are a couple of Action Models for the record view:
Field Decorator (i.e. pop-up/macro next to field)
Related List Action (New, Add, etc. which I'll focus on in this article)
Contextual Side Panel/Form Side Panel (Agent Assist, Templates, etc.)
Form Related Items (Displays between Details and Related Lists as a tab and can display information from related tables on the open record) an example would be Install Base on an Account record.
There are some other models listed in the Declarative Action Model Definition table such as EVAM, Playbook, Playbook Card, Playbook Stage, and UXE but I won't go into those right now, without looking into it at all, I believe those are reserved more for the new Now Experience Workspaces.
There's three different action types that can be used for the list and record Action Models and are defined in the Implemented as field:
UI component - Component in Contextual Side Panel/Form Side Panel such as Agent Assist, Templates, Attachments, or placing custom components there. Can also be used to display icons in fields, forms, lists, or related lists to perform actions. This is where you'll have to create your own component if not using one provided out-of-the-box.
Client action - Client-side action such as opening a record, opening a URL, etc. Per the documentation there are a set number of client actions and new ones cannot be created, so I'm assuming custom components would need to be used instead.
Server script - Executes a server-side script, such as creating/deleting a record, re-assigning a record, etc.
Declarative Action Assignments
The sys_declarative_action_assignment table is where we'll mainly be working as most of the other tables are read-only and locked down by ServiceNow. Everything that I discuss below will be done on an Action Assignment record. I'll touch base on different fields on the form as I go through different use cases.
Adding and Removing Records in a Related List
I decided to play around with some Related List Actions for this article since being able to add records to related lists is a common use case. In the Platform UI, we're used to the New and Edit buttons that are present when adding a related list to a form. There can be controlled by right clicking on the list header and using List Control to configure if the buttons show, what roles can use them, and what conditions they should show on, however these buttons do not translate over to the Workspace UI automatically, and cannot be configured from List Control.
Declarative Actions will need to be created instead of using List Control. There are some Global Declarative Actions out there already, i.e. New on Related Lists so it's worth poking around your PDI to see how ServiceNow is using them. There's a couple of fields to be aware of when using Related List Action Assignments, I'm sure I've missed some fields and will try to capture them and their use cases in future parts:
Action Payload - Can be used to fire an internal event when the action is triggered. An example is the Create New action that sends the following payload:
Record Conditions (Server Condition) - Conditions that must be met before the action displays. OOTB examples seem to be pointing to Active = true for things such as Agent Assist/Templates. I tried this on a Closed incident and it did remove the Add button so, it seems like this the 'Condition Builder' way of controlling when the action shows versus the 'scripting' way. What's interesting is when I tried it on State is not Closed, or Priority is not 1, I didn't have the same behavior of Active = true, so this needs more investigation.
Script Condition (Server Condition) - Conditions for when the button displays. In my example I wanted to hide the Add button if the Incident that the Scoped Order related list was on was in state of 6,7,8 (Resolved/Closed/Canceled). Since my action runs off the Scoped Order table and not the Incident table, I had to use parent.state:
parent.state != 6 && parent.state != 7 && parent.state != 8
Required Roles (Server Condition) - Roles and access to view the action, these are based off ACLs. So you can set explicit roles, or just say this requires write access without defining a role and the ACLs will be checked accordingly.
Server Script - Executes when action triggers. Per the documentation this uses the same environment and variables as UI Action server scripts.
Client Conditions (Client Condition) - Some of the OOTB examples point to isNewRecord is false, etc. I definitely need more information on this one as it's not very clear and may just not fit in with my use case. I did notice if I put something in like parentTable is not incident that all of my buttons disappeared, New, Add, and Remove.
Confirmation Required - Asks the user to confirm before running server scripts. This is a very nice feature and looks like this:
You may have seen the Add button already in the Affected CIs related list, etc. ServiceNow displays a component which displays a list of records the user can choose from to add.
For a proof of concept, I added the Incident reference field under Related Records on my Scoped Orders table. Under the Workspace view on the Incident table, I added Scoped Orders > Incidents related list.
I do have the New button added automatically, which I may want to remove if I didn't want users creating new Scoped Orders from Incidents. I'd like to allow users to Add (or Edit in Platform UI terms) existing Scoped Orders to this related this. This is where I need to create an Add button.
The ServiceNow Product Documentation does provide a walkthrough on this, which I used. Their example is using an m2m (many-to-many) table, so I decided to make one using an o2m (one-to-many) relationship by linking Scoped Orders to one Incident, i.e. one Incident can have many Scoped Orders, but a Scoped Order may only have one Incident.
ServiceNow has broken down Action Assignments into multiple modules for ease of use under Workspace Experience > Actions & Components.
I'm creating a Related List Action on my Scoped Order table, so I'll click that module and click New. The product documentation gives a pretty good explanation of the fields, so here's a quick screenshot of what I did:
The Action Label can be named anything, same as the Action Name but I'm assuming we don't want to duplicate Action Names. Since I'm copying OOTB functionality I'm using the sn-multi-record-associator component. My related list is on my Scoped Orders table, and I limited this to just Agent Workspace.
One field to note is the Record Selection Required which requires to select existing records from the Related List, which was the opposite of what I needed to do. I need to be able to select records to add to that related list, so I left it unchecked. I can see where it would be helpful on other functions though.
I had to switch to the Advanced View in order for the Component Attributes section to show, allowing me to define the Action Attributes needed for my action.
Action Attributes control how the component works. It uses GraphQL which I'm not going to pretend to be the expert on right now. Here's a great video from Nathan Firth in its usage on the Service Portal. Let's dissect these attributes:
Label - The title of your modal/pop-up, I found out that SN will add the word 'Add' automatically for you
Extension Point - This is what really controls the records that appear there. If you leave it blank or 'DEFAULT' it allows all records to show. You can actually create queries (think Reference Qualifiers) by using Extension Points. Check out the ProblemRelatedListChangeRequestItemFilter Script Include to see how the PROBLEM_CHANGE_REQUEST_QUERY_FILTER extension point is used in add_change_requests_to_problem Action Assignment.
User Given Table - The table you want to select records from in the related list. For example this would be your m2m table, or if using o2m it would be the table used for your many, i.e. Scoped Orders in this case because one Incident can have many Scoped Orders.
Hide Select All - Prevent users from selecting all of the records.
Referenced Field Name - I think this applies more to m2m than o2m. This is the field on the m2m you want to get the records from, so in ServiceNow's example it would be the location field on the task_location table. For my example I played with putting incident in that field, and leaving it blank and it didn't make a difference.
Type - This is what tells the component if this is a m2m or o2m relationship. There are only two choices for this, m2m or o2m.
Parent Field Name - The reference field you want to populate when adding records. This seems a little misleading in its title since it says Parent. I noticed for my association to work, I had to put in incident so that the Incident would link to the Incident field on the Scoped Order record since I'm using o2m. If using an m2m table it would be the field you're wanting to link to, for example 'task'.
Columns - The columns you want to show in your modal. See below about views.
View - ServiceNow says you can leave this blank, but for fun I didn't add any columns and chose my Workspace view and it worked, so it seems like it's an either/or situation with columns and view.
So here's what it looks like in Workspace, the button is on the related list, pops up the modal, allows users to select records and add, appears in the related list, and populates the reference field on the corresponding record(s), in my case Incident under Related Records on the Scoped Order. Note: One thing I noticed is that if a Scoped Order already has another Incident related to it, it won't show up as an option in the pop-up.
Now we need to give our users the option to remove. This is a little easier but there are some things to configure. To remove, all we need is a Server Script Action Assignment, as we can let the user select which Scoped Orders to remove right from the related list. I created this Action Assignment on my Scoped Orders table, since it's the table being used for my related list.
Server Script - This is what executes. For the o2m relationship, I just wanted to clear out the Incident field, not delete any records, but there are some examples of current.deleteRecord() occurring in m2m tables.
Script Condition - The conditions that must be met before the action displays. I left this blank for my example. This also applies to the above example for adding, etc. but I wanted to discuss it here since the name is a little misleading. To me it sounded like conditions that must be satisfied before the script runs, not conditions that must be satisfied in order for the button to show.
Here's what it looks like in Workspace:
I hope this provided an overview of what Declarative Actions are and are not. A lot of the real power is housed on the Record View in Workspace rather than lists but this was the same in the Platform UI as well. It pays to keep it simple with server scripts and re-using out-of-the-box components, but I'm sure there are going to be times where custom components are needed. I'll expand more on List Actions, Field Decorators, Form Side Panel Components, and Form Related Items in future parts to this mini-series. I encourage you to play around in your PDI and add fields to your list/form views just to see what they do. As always, feel free to comment if there's something I missed or need to correct.