How to: Use Javascript Expression for hiding irrelevant UUX Actions
Goal
As described in the article Actions, the UUX provides the sophisticated mechanism for determining the availability of the Action for current execution context. Besides the standard mechanism (present also in Classical Console) of filtering Action based on selected objects Configuration Items and their States, the UUX also introduced a way of additional filtering. using the Javascript Expression, which already has no limitation, and allows solve any Use Case. The Article demonstrates how not trivial use cases could be resolved relying on this feature
Use Case
Display "Accept" action for the selected Incident(-s), only for members of the Recipient Role of the selected Incident(-s).
Step 1: Prepare data in Grid
Javascript Expression Filtering is executed on the last step of the Action validation procedure (after Audience, Configuration Item, and State check), and fully relies on data already present in Browser (on Client). Therefore you need to make sure that the property used in the expression is really present.
To implement the Case, we need has the information that the interactive user is a member of the Incident Recipient Role. As far as default Incident Grid does not keep such data, we need to extend the related DataQuery.
- From the Incident Dataset View, click "CONFIGURE" to follow to Dataset View object, and from there open related Data Query for editing
- Add New Column to the Data Query, which for each Incident in a resultset, keep the information about the membership of the current user in Recipient Role
Column Expression:
CASE WHEN EXISTS(SUBQUERY(SPSSecurityClassRole as R, R.ID,
R.T(SPSScRoleClassBase).ID = base.RecipientRole and R.Members.ID = CURRENTUSERID())) THEN 1 ELSE 0 END
Name: CurrentUserInRole
Title Type: No Title (the column is not designed to be displayed)
Display: Hidden (the data be present only in JSON, but is not displayed in the Grid)
- Assure its works.
First of all, make sure the data for the just configured column are present in the response, and they are right. For that, open Network tab in Browser Development Tools (F12), and refresh the Incidents page.
Filter the requests to find the web service which returns data for the Incidents Grid (WidgetList/GetData).
Step 2: Edit "Accept" Action
1. In Administration/User Interface/Actions area, please open object associated with the Action "Accept" for editing.
2. Define the Javascript Expression, to allow the Action only for Objects where the property "CurrentUserRole" is set.
Javascript filtering Expression: $object.CurrentUserInRole == 1
3. Check the Action Filtering is working
Open the Incidents, and assure the action "Accept" present only for Incidents where the current user is a member ("MDM Administrators")
Step 3: Extend Incident Preview Data Model
For the sake of the performance, the Action evaluation mechanism is working always with the present data. What means in the case when filtering is taking place in grid (or multiple selected objects view) the data model behind is one (based on DataQuery contract), but in case of Preview, the data model behind is absolutely different and based on Preview Data Model (defined in Layout designer). To make Action filtering working fine for both cases, we need to extend the solution.
1. Open Incident Preview in Layout Designer
2. Add Extra Property for existing Property "Recipient Role" of the SPSActivityTypeIncident data source
3. Define the name and the ASQL expression for the new Extra Property
CASE WHEN EXISTS(SUBQUERY(SPSSecurityClassRole as R, R.ID, R.T(SPSScRoleClassBase).ID = base.ID and R.Members.ID = CURRENTUSERID())) THEN 1 ELSE 0 END
4. Assure the Incident Preview data model contains the defined Property
Step 4: Adjust "Accept" Action Javascript Filter to support filtering in Previews
Set new expression to Accept Action Javascript Filtering Expression, which confiders both cases, as Grid as Preview
$object.CurrentUserInRole == 1 || ($object.SPSActivityClassBase != undefined && $object.SPSActivityClassBase.CurrentUserInRole == '1')