You may have different types of users who should see different data and Apps in Onit. For example, you may want to restrict users in the Finance group to only seeing certain Apps while users in the HR group should see a different set of apps. You can use a Group Preferences App to manage this.
Each Record in a Group Preferences App represents a group which can hold a set of preferences and properties, some of which revolve around Suites. Once set, group-level settings will automatically filter down to related records in a User Preferences Provider App (usually named User Profiles). Using this approach, each Record in the User Profiles App represents a user while each record in the Group Preferences App represents a group the two apps are connected using a parent/child relationship and field-level data is pushed from the group to its users via Actions and calculated fields.
There are three Suite elements that are commonly defined at the group-level:
- The user’s default Suite.
- The homepage that the user sees when they log in. This homepage is technically referred to as a Suite navigation item, which must live within the user’s default Suite. Normally this is set to be a Suite Dashboard which contains Widgets (as seen in the following screenshot).
- A set of navigation items and action items that the user sees in their navigation list (as seen in the following screenshot). This is typically a list of Apps and Suite Dashboards that the user should be able to access.
In the diagram below we have three example groups: Admin, Regular, and Restricted. In this scenario, Jim, for instance, would only see the Suite elements explicitly set on the Admin Record in the Group Preferences App.
In this tutorial we will explain how to create and configure both a Group Preferences and User Profiles App to control which Suite elements users can see.
Before We Start…
- This tutorial does not cover how to create or configure Suites. It only covers how to assign users/groups to pre-built Suite.
- Though this tutorial is primarily interested in Suites, Group Preferences and User Profiles Apps can be used to “decorate” groups/users with any custom preferences/properties that you wish, which may have nothing to do with Suites. For example, for Onit workflow purposes, maybe you need to store address information for groups of users (street name, city, state, country, etc.). Instead of having to set these values for each individual user, you could create one Group Preferences Record for each physical office.
- Records in the Group Preferences App are a completely different concept in Onit than are Groups. It may be helpful to think of Group Preferences Records as groups that store preferences/properties while Onit Groups control security.
- The name of the apps Group Preferences and User Profiles is not important. While these are the names most commonly used by Onit app builders, you can name these apps whatever you like.
- This tutorial will assume that your environment already has a User Profiles app that has been defined as a User Preferences Provider as explained in this tutorial.
- In many Onit environments (such as our standard ELM and CLM products), much (if not all) of the configuration described in this tutorial already exists. Even so, if you are working in one of these environments it’s important that you understand this configuration so that you work around and customize it.
- The fields in the User Profiles app are the fields that actually control Suite preferences. These are “magic” Fields, in the sense that if you name these fields following the instructions in this tutorial then they will be treated differently than normal fields by the Onit platform. The Fields that exist in the Group Preferences app do not technically control any Suite preferences on the backend. They are only recommended as a nicety, allowing you to define settings at the group-level that then filter down to the user-level.
Creating the Group Preferences App
The Group Preferences App will be the parent App to User Profiles.
- Create a stand-alone App named Group Preferences.
- In the Wizard for your Group Preferences App navigate to the Fields tab.
- We will use the default name Field to capture the group’s name. Change this field’s label to Group Name.
- Create a new text Field named default_suite_name. This Field will hold the display name (not the actual name) of the group’s default Suite.
- Create a new text Field named default_navigation_item. This Field will hold the display name (not the actual name) of the groups’ default Suite navigation item (which must live in the default Suite named above).
- Create a new text Field named suite_navigation_items. This Field will hold a JSON object that controls which Suite navigation items and Suite action items are visible to the group.
The required JSON syntax will be covered later in this document.
-
Create a HasMany Field named users. This Field will point to the User Profiles App.
- In the Inverse Relation Field property type group.
- Note: Your User Profiles App must have a matching BelongsTo field that points back to your new Group Preferences app.
- Choose User Profiles as the Target app.
Guarding Group Preferences Against Bad JSON
The Field suite_navigation_items is brittle. If the entry there is missing as small a thing as a comma or a quotation mark, the system won't process it correctly. The user will see an error page instead of the UI. When a user logs in, the UI tries to load their suite navigation options, to improve performance when navigating to the suite; unfortunately this means that a tiny error in suite_navigation_items for a group leaves the users in that group unable to do anything at all. Therefore it is critical to ensure that this Field never contains bad JSON. Here's how to put a guard in place.
- Navigate to the Conditions node in your Group Preferences App.
- Create a new Condition named Bad JSON. This will run the contents of suite_navigation_items through a Liquid filter named parse_json, capture the output, and check to see if there was an error. The Liquid should look like this:
{% capture json_parse_try %}{% assign js = suite_navigation_items | parse_json %}{% endcapture %}{% if json_parse_try contains 'Liquid error' %}true{% endif %}
- Save your condition. We will assign this condition to a Business Rule shortly.
- Navigate to the Action node in your Group Preferences App.
- Create a new Action of the type Throw Error, named Error on bad JSON. In the Error Message section, put the message:
Suite Navigation Items contains invalid JSON.
- Navigate to the Business Rules node.
- Create a new Transaction Updated Business Rule named Don't allow save of bad JSON.
- Under Condition select the one you created above, Bad JSON.
- Under Action likewise, Error on bad JSON.
- Save the Business Rule.
Configuring the User Profiles App
If necessary, make the following changes to your User Profiles app.
In most cases, the fields mentioned below are hidden in the user interface. This is because it is typically not helpful to see the values of these fields at the user-level, since they are normally set at the group-level. That said, this is not a requirement; these fields can be displayed at both the user- and group-level.
- As mentioned above, create a BelongsTo Field named group that references the Group Profiles app. In the Target App dropdown choose Group Preferences.
- Create a text Field named default_suite_name.
- Enter `true` for Hidden condition.
- Check the Read only box.
-
On the Advanced tab, check the Calculated box and choose Liquid for the Calculation Type. In the Script Field type
{{group.p_default_suite_name}}
. This Liquid will evaluate to the inherited default Suite name.
- Create a text Field named default_navigation_item.
- Enter `true` in for Hidden condition.
- Check the Read Only box.
- On the Advanced tab, check the Calculated box and choose Liquid for the Calculation Type.
-
In the Script Field type
{{group.p_default_navigation_item}}
. This Liquid will evaluate to the inherited default navigation item.
- Create a text Field named suite_navigation_items.
- Enter `true` for Hidden Condition.
- Check the Read Only box.
- On the Advanced tab, check the Calculated box and choose Liquid for the Calculation Type.
-
In the Script Field type
{{group.p_suite_navigation_items}}
. This Liquid will evaluate to the inherited Suite navigation items and action items.
Keeping Group Preferences and User Profiles in Sync
Once your User Profiles and Group Preferences Apps have been set up, we now have to create a couple Actions, a Condition, and a Business Rule to keep them in sync. This configuration will only update User Records when a change to the Group Preference's Suite Navigation Items or Default Navigation Item property has been changed. We will configure the sync this way to prevent unnecessary recalcs. Without this configuration any updates made to an existing group would not be pushed down to any users.
- Navigate to the Conditions node in your Group Preferences App.
- Create a new Condition named Changes to Suite Preferences. This condition will control when User Records should be updated. In this case we only want the Records to update when there has been a change in the Group Preference Record's suite navigation items or the default navigation item property. The condition should look like the following:
{% for c in atom.changed_values %}{% if c.field_name contains 'suite' or c.field_name contains 'item' %}true{% break %}{% else %}false {% endif %}{% endfor %}
- Save your condition. We will assign this condition to a Business Rule shortly.
- Navigate to the Actions node in your Group Preferences App.
-
Create a new Action of the Recalculate Single Transaction type named Update Users. This Action will force a recalculation of all fields for the users when appropriate.
- Click Ok to save your Action.
- Navigate to the Business Rules node.
-
Create a new Transaction Updated Business Rule named Update Users.
- Under Action choose Update Users.
- Under Condition choose Changes to Suite Preferences.
- Click Ok to save your Business Rule.
- Make sure that your new Business rule shows in the list below the JSON guarding rule you created above. Validation of the JSON must take place before the JSON is pushed out to the users!
Creating Groups
Now that your Group Preferences and User Profiles Apps are configured, create a Record in the Group Preferences App for each group that you want to support. In our example, we’ll start by creating a Record for a group of users in our company’s Finance Department. Enter the following values into the Record:
- For Group Name enter Finance Department.
- For Default Suite Name enter Finances. This value must exactly match the display name of the Suite that the user should see.
- For Default Navigation Item enter Finance User Home. The value of this Field must exactly match the name (not the display name) of a navigation item within the default Suite.
- Suite Navigation Items: Provide a JSON object that will determine which navigation items and action items this group will see. The JSON object must have the following format:
{"Default Suite Name":{"nav-items":["Navigation Item 1","Navigation Item 2","Navigation Item 3"], "action-items":["Action Item 1","Action Item 2","Action Item 3"]}}
The quote marks must be straight quotes. Some editors will automatically turn your quote marks into ‘smart’ or ‘curly’ quotes, which will break the JSON. Your JSON should have no whitespace between values.
Ensure every navigation item listed in your JSON object is an existing navigation item in your Suite. The name (not the display name) of the navigation item must be exactly the same as the value used in the array. In our Finance Department example, the JSON object will be:
{"Finance User Home":{"nav-items":["Finance User Home","split","Matters","Invoices","Tasks","Logout"],"action-items":["Add Matter","Add Contact"]}}
Or without the action items:
{"Onit":["Matter Management Home","Matters","Documents","Invoices","Tasks","Split", "Contacts","Timekeepers","Vendors","Split1","Logout"]}
The top-down order of the items in the navigation menu (from an end-user’s perspective) is based on their left-to-right order in the JSON.
An error in the JSON you provide will completely destroy the UI for any user who is unlucky enough to be a member of that group. They will be left unable to do anything at all. Be very careful here, especially if the group you're editing contains the system administrator user. If you haven't put the Business Rule in place to guard against it (see Guarding Group Preferences Against Bad JSON) make sure to do so.
It's possible to control more than one suite in the JSON. Simply put them together within the curly braces, separated by a comma. Using the examples above, that would look like this:
{"Finance User Home":{"nav-items":["Finance User Home","split","Matters","Invoices","Tasks","Logout"],"action-items":["Add Matter","Add Contact"]},"Onit":["Matter Management Home","Matters","Documents","Invoices","Tasks","Split", "Contacts","Timekeepers","Vendors","Split1","Logout"]}
The Finance Department User Group Record should look like the following:
Once you submit the Record, the Finance Department Group will be created.
- Navigate to your User Profiles App to assign users to the group.
- In your User Profiles App, choose a user’s Record that you would like to assign to the Finance Department group.
- Click Edit and choose Finance Department from the Group dropdown (this is the BelongsTo field that points to the Group Preferences app).
- When you are done click Update.
- The user should now be assigned to the Finance Department User Group. When they log in they should see the Finance User Home navigation item, have Finance User Home, Matters, Invoices, Tasks, and a Logout link as navigation items, and Add Matter and Add Contact as action items.