Blog Post

Blog
4 MIN READ

Menu Component in Practice

JackLacava's avatar
JackLacava
Icon for OneStream Employee rankOneStream Employee
8 months ago

One of the highlights of OneStream 8.5 was the introduction of the Menu Component. This Dashboard component provides a new powerful way to address common navigational needs. Let's have a look at how it works.

If you create the new Menu Component in your Maintenance Unit, you will quickly notice that it has very few properties. That's because its configuration will actually come from an attached Data Adapter, which must produce a set of tables containing all menu items and their configuration.

The format of such tables has to be somewhat precise, matching what the component expects. For this reason, the best way to produce them (at least while you familiarize yourself with this mechanism) is to create a Dashboard DataSet using a couple of utility classes built for this specific task. 

Create a Dashboard DataSet from the Business Rule page or in an Assembly

The first thing we will do, in our rule, is to create an XFMenuItemCollection object. This represents our menu, which we will populate with items and eventually return (as a DataSet) at the end of the function. 

Public Function Main(ByVal si As SessionInfo, ByVal globals As BRGlobals, ByVal api As Object, ByVal args As DashboardDataSetArgs) As Object 
	Try 
		Select Case args.FunctionType 
		Case Is = DashboardDataSetFunctionType.GetDataSet 
			If args.DataSetName.XFEqualsIgnoreCase("MainMenu") Then ' create the menu object Dim menu As New XFMenuItemCollection()

Menu items will be created by instantiating objects of type XFMenuItem. These objects will hold all the configuration properties for the item, including the font and colors that it will use.
There are a few different constructors you can use, to specify all sorts of properties; the one used here is the shortest one!

' create top-level item 
' XFMenuItem(string uniqueName, string headerText, string foreground, string background, bool isBold, bool isItalic, bool isEnabled, bool isSeparator, string parameterValue) 
Dim parentMenuItemOne As New XFMenuItem("1", "Parent", _ 
	"White", "SlateGray", False, False, True, False, Nothing) 
' create items for the second level 
Dim childMenuItemOne As New XFMenuItem("1.1", "Child 1", _ 
	"Black", "White", True, True, True, False, Nothing) 
Dim childMenuItemTwo As New XFMenuItem("1.2", "Child 2", _ 
	"Black", "White", True, True, True, False, Nothing) 
' create item for the third level 
Dim grandChildMenuItemOne As New XFMenuItem("1.1.1", "Grandchild 1", _ 
	"White", "SlateGray", True, True, True, False, Nothing)

Most of the properties are self-explanatory, but you might wonder what "parameterValue" is. That's the value that will be pushed into the Bound Parameter specified on the actual component later on, so that Actions or other components can pick it up. We will come back to this later.

Now we need to define the relationships between items. We do that by manipulating the .Children property of each parent item, which must be a list containing the children (duh!) items. 

' create the hierarchy by adding children to direct parents as a List 
' attach 1.1.1 as a child of 1.1 
childMenuItemOne.Children = New List(Of XFMenuItem) From {grandChildMenuItemOne} 
' attach 1.1 as a child of 1 
parentMenuItemOne.Children = New List(Of XFMenuItem) From {childMenuItemOne} 
' you can also manipulate the list once created. 
' attach 1.2 as a child of 1 
parentMenuItemOne.Children.Add(childMenuItemTwo)

In a similar way, top-level items are added to the list contained in the .MenuItems property of our XFMenuItemCollection instance.

' add item 1 as a top-level members of the menu 
menu.MenuItems.Add(parentMenuItemOne)

Before we return the resulting menu, if you are dealing with dynamically-generated structures with a lot of members, you might want to perform a safety check and purge extra members:

While menu.IsAboveMaxMenuItemLimit(si) 
	menu.MenuItems.RemoveAt(menu.MenuItems.Count - 1) 
End While

Last, we use the .CreateDataSet method of our menu object to return the DataSet.

' generate the dataset and return it 
Return menu.CreateDataSet(si)

Now that we have the rule, we can create a DataAdapter to execute it.

Data Adapter configuration

Notice how, when testing it, it produces two tables: one with item properties, and one with their relationships.

Items tableRelationships table

Now that we have an Adapter, we can create the Menu Component and attach the Adapter to it.

Create Menu componentSet a NameAttach the adapter

You can then assign it to a Dashboard and preview it, after you save it.

Attach Menu to DashboardResulting Menu


This is fun but a bit pointless! We want menus so that the user will actually choose something and we'll get the result of that choice. In order to do that, we need to specify the Bound Parameter. Whenever the user selects an item, the "parameterValue" associated with that item will be pushed into the specified Parameter; we can then reference that Parameter in an Action or extender rule, to trigger something like navigating to a website. Note that the Parameter doesn't need to exist! OneStream will just create one for you in the background.

Specify a Bound ParameterPreview the Dashboard in Design Mode - the parameter appears!

Then we place an Action on our Component, referring to the Parameter.

Set Action on Menu Component

The last step is to go back to our rule and specify a different parameterValue for "leaf" items, so that the Parameter will contain something.

Dim childMenuItemTwo As New XFMenuItem("1.2", "Main Page", _ 
	"Black", "White", True, True, True, False, "https://www.onestream.com") 
' create item for the third level 
Dim grandChildMenuItemOne As New XFMenuItem("1.1.1", "OneCommunity", _ 
	"White", "SlateGray", True, True, True, False, "https://community.onestreamsoftware.com")

Et voilà! You can now execute the Dashboard and verify that it works!

 

Updated 8 months ago
Version 2.0

4 Comments

  • KH1's avatar
    KH1
    Contributor II

    Thank you, Jack, for the demo and clarification on this new Menu Component.
    - Saw Genesis is using a Menu Component.
    - If it is helpful, pls find more info as linked below.
    - Menu Component - Design Guide

  • FW's avatar
    FW
    New Contributor II

    Thanks Jack!! Is this working on workspaces using DataSet services?

    • JackLacava's avatar
      JackLacava
      Icon for OneStream Employee rankOneStream Employee

      Yes. The traditional DataSet rule was used here for simplicity of exposition, but it should work fine with the service-based version too.

  • victortei's avatar
    victortei
    New Contributor III

    That's great stuff! The menu is clean and intuitive—perfect for a landing page! Great job!