MergeAndCenterColumnHeaders in Cube Views
Hi, Anyone on Version 8 who's actually tried to use this 'enhancement' feature in Cube Views? We requested this on Ideastream a long time ago with a lot of support. I can see this command is now available in the header format dialog; however, it would appear that the only thing it does is change the header from left justified to center view. There does not seem to be a way to actually 'merge' column headers, despite the fact that it's called "MergeAndCenter". Even the system documentation appears to confirm this behavior. Someone please tell me I'm missing something here and it actually is possible to merge column headers, because we really really wanted this feature. Thanks643Views2likes10CommentsMastering Dashboard Load Events, Component Actions and Advanced Parameter Handling
For those of us creating Dashboard solutions in OneStream, there are a couple of Services for us to master, that provide us with total control over how Dashboards load, Component actions, refreshes and Parameter Handling, this blog is going to touch upon two of these, namely the Dashboard Service and Component Service, in the Service Factory. Dashboard Service Type Component Service Type The History: A quick history lesson on what we are covering here, before Workspace Assemblies, this functionality already existed (and still does), in a Dashboard Extender Business Rule. Business Rule Types 1) Load Dashboard Function Type 2) Component Selection Changed Function Type We would call each function type using syntax like this this e.g. {YourBusinessRuleName}{YourMethodName}{} The key difference in that the On Load event is called specifically from a Dashboard itself (usually this will be the Top-Level Dashboard). Whilst the Component Selection Changed events are called directly from the Dashboard Component e.g. We can still utilise functionality this way, but this blog will focus on execution via the Dashboard and Component Services, in the Service Factory, of a Workspace. We will also focus on DashboardExtenderArgs, the XFLoadDashboardTaskResult and the XFSelectionChangedTaskResult objects in this blog and convey how powerful they can be for Dashboard Developers. Note: This blog will use C# examples, but you will see the syntax is nearly identical to the VB.Net equivalent. Dashboard Extender Args: Before we jump into the example, I want to talk a little bit about DashboardExtenderArgs, in the context of both Services. One of the things that is most graceful about the Dashboard and Component Services is DashboardExtenderArgs. In the context of these two services, we can use DashboardExtenderArgs in a couple of different ways, in addition to simply using the values passed in directly to our method(s) using args.NameValuePairs, which is a Dictionary<string, string>. In the Dashboard Service, we can retrieve a different Dictionary<string, string> of all the KeyValuePairs from the prior run e.g. the last time the Dashboard was run using args.LoadDashboardTaskInfo.CustomSubstVarsFromPriorRun. We can then use these to set Default values for initial Dashboard invocation (more to come on this later in the Dashboard Service section). Whereas in the Component Service, we can retrieve yet another Dictionary<string, string> of all the KeyValuePairs associated with your dashboard parameters already resolved by using args.SelectionChangedTaskInfo.CustomSubstVarsWithUserSelectedValues. What this means effectively is you no longer need to pass in NameValuePairs when calling a Dashboard Extender rule, in the same way that we do with a Data Set or XFBR rule, for example e.g. {WS}{YourMethodName}{Key1=[|!prm_YourParam1!|], Key2=[|!prm_YourParam2!|]} As you can see below, from our perspective both are dictionaries of KeyValuePairs related to Dashboard Parameters; but the Key we use with this dictionary (to lookup the Value) is the actual parameter name and all resolved parameters appear in this dictionary. That’s the main difference and the reason it is so useful. {WS}{YourMethodName}{} The Dashboard Service: In terms of setup and execution, the Dashboard Service is simple. We use it to set default Parameter values when a Dashboard loads for the first time. This is important if we want to set default values or we are using nested parameters, for example where we have dependencies that must be resolved at initial run time. We typically set this on the Top-Level dashboard, because we only expect it to fire the first time a Dashboard is run (see IF statement below). It is not generally a good idea to set this on an embedded dashboard (not Top Level), so that we do not lose control over Parameter actions. To call the Dashboard Service we need to set Load Dashboard Server Task to Execute Dashboard Extender Business Rule (Once). - ChangeCustomSubstVarsInDashboard We can then use the XFLoadDashboardTaskResult object to ChangeCustomSubstVarsInDashboard e.g. set to True and then set our default NameValuePairs in the ModifiedCustomSubstVars Dictionary. This is a way to ensure Parameters have values that we can control when a Dashboard is run, for the first time. We will see this approach again, later in this blog in the Component Service. The Component Service: As you can see, the Dashboard service is simple, but effective, but the real fun starts when we start to look at what we can do after the initial run using the Component Service. This is the Service that enables us to have full control over what happens within a set of Dashboards, after they have been run for the first time e.g. catching the result from a Dashboard Component Parameter e.g. a Combo Box, to impact the result of another Dashboard Component e.g. a Cube View, etc. So, let’s start by looking at a Dashboard Component itself to understand how we can interact with the Component Service. On every Dashboard Component object there is a configurable Action section e.g. see next image. We can configure all of this with a no-code approach… But if we want to guard against certain conditions, we can extend this functionality by using the Component Service. This is important because we can perform the same functionality from the Component Service for the User Interface Actions and the Navigation Actions. Please note, we cannot replicate Save, POV and Server Task Actions using the Component Service XFSelectionChangedTaskResult object. Now let’s move onto the most powerful of all the objects in the blog, the humble XFSelectionChangedTaskResult object, in terms of what it does and how it can be used for targeted and refined Dashboard / Parameter actions. XFSelectionChangedTaskResult: The XFSelectionChangedTaskResult object is the object returned from this service to the dashboard interface. Please observe most controls are set to False by default. Next, we will deconstruct each of these properties. You’ll notice they come in pairs with a Boolean switch for each and they can be used together and interchangeably. It should also be noted that generally we always set the IsOk property to true when returning this object. To call the Component Service we need to set Selection Changed Server Task to Execute Dashboard Extender Business Rule (General Server). - ShowMessageBox The first properties we will cover here are exclusive to the Component Service and not available directly via a Dashboard Component. This is to return a message to the dashboard; once the task is complete or to return a validation message, etc. We would then set the ShowMessageBox control property to true and pass a string to the Message property e.g. Hello World. The result would look something like this example, where a dialog is returned to the UI with the message displayed - ChangeSelectionChangedUIActionInDashboard Next, probably one of the most powerful attributes of the XFSelectionChangedTaskResult object is the ChangeSelectionChangedUIActionInDashboard properties. This replicates the User Interface Actions we can configure on a Dashboard Component But we can use it here in the Component Service to override what the Component does based on a condition, for example. Let’s say that we want to test that one of the variables passed in as actually populated and if not, we do nothing. So, this ability gives us total control over Dashboard and Parameter actions, once we are in the Component service. That said, it is important to still use the Dashboard Component itself for the original actions to make the solution transparent and readable. Just because we can perform most functions at the code level; doesn’t mean it’s necessarily the best approach from a design and maintenance perspective, for example. Remember to Keep It Simple. - ChangeSelectionChangedNavigationInDashboard Next, we have the Navigation Actions. Here, again we can replicate the same actions inside the Component Service as we can on the Dashboard Component itself. Again, here we have options to guard Navigation Actions, if for example a Parameter Value that is required, has not been resolved by the Dashboard UI itself; we can set the XFSelectionChangedNavigationType to return NoAction, like we did in the example above. The next two attributes we cover are broadly similar and both are related to Parameter Dictionaries, but each has a different use case and are usually accompanied by a Dashboard Action such as a Refresh. Input Value Parameters Over Literal Value Parameters: Parameter examples shown here are largely for Input Parameters e.g. Parameters that use Parameter Type Input Value. These are generally favoured (instead of Literal Value Parameters) because they observe the User’s Session; as opposed to Literal Value Parameters, where the value persists for all users and are therefore not particularly safe to use when we expect > 1 user to interact with our Dashboard and Get / Set Parameter Values. - ChangeCustomSubstVarsInDashboard Typically, the reason why we use the ChangeCustomSubstVarsInDashboard approach is to ensure a parameter and its value reach the target Dashboard being refreshed by this Component Action. So, they provide the ability to manipulate the values assigned to a Dashboard (like example below) or reinforce a targeted set of Parameter passes from a source Component Action to a target refreshed Dashboard (which is sort of the name of the game when it comes to robust Dashboard Development in OneStream). As you can see ModifiedCustomSubstVars is simply a Dictionary<string, string>, where the Key is the full Parameter Name and the Value is the value assigned to that Parameter. Together they form the KeyValuePairs that the Dashboard consumes. - ChangeCustomSubstVarsForLaunchedDashboard The key difference with ChangeCustomSubstVarsForLaunchedDashboard is that here, specifically we are passing a Dictionary<string, string> directly to the Dialog Dashboard that is being opened. This is important because the Dialog usually sits outside the Main Dashboard, often in a separate group and has no concept of these Parameters. An example of how we would set this up via the Dashboard Component is below… … and by calling the Component Service we can pass KeyValuePairs directly to the Dialog. Here we can stipulate this on a parameter-by-parameter basis e.g. like above, but where we set default parameter values or we can simply pass all the resolved parameters to the Dialog using a simple trick like below. Tailor Your Approach: Now that we have deconstructed what each element of the XFSelectionChangedTaskResult object does, how to use it and which Parameter Types work best for this approach. Let’s now look at blending some of these techniques together in a real-life use case. For the purposes of this blog, I have created some very simple components and two parameters to demonstrate how to pass parameter values around correctly through these Actions (a common use case). This is the Workspace and everything underneath used for this demonstration… Blog Workspace example We are using the Dashboard Service, the Component Service and the Service Factory, in our Assembly. In main Dashboard a_A_Blog, we have set the On Load function. We also have some components e.g. We have a Text Box for Inputs... That uses a single Input Value Parameter e.g. prm_YourParamName1. We also have an Open Dialog button (see below), please observe User Interface Actions below. The other important thing to observe here is we set the Dashboard we want to Refresh after the Dialog action here e.g. at the point of Opening the Dialog, instead of attempting this using the Component that closes the Dialog. In the Dialog that we open e.g. a_dlg_A_Blog, we have another Text Box This one uses a different Input Value parameter e.g. prm_YourParam2 And we also have an Execute Save Button. This sits inside the Dialog and will close the Dialog, once complete. Please also observe that for both Component Service calls, we are not passing in any NameValuePairs to either method, since we can get these from DashboardExtenderArgs, as demonstrated earlier in this blog. Now, that we have gone through the Dashboard setup, and before we look at the Code; let us review the simple Dashboard UI. Now let’s look at the code. For the Open Dialog button. We can see that we can get all the Parameters we need from DashboardExtenderArgs. We enable ChangeCustomSubstVarsForLaunchedDashboard (since our button is opening a Dialog) and we set the value of the parameter that is being passed to the Dialog. In real life, this is common to set defaults or pass existing values to be used by Dialog dashboards. So, we open the Dialog using the Button and set the value of the parameter in the Text Box in the Dialog (prm_YourParam2) to be null and guard against the first input parameter being empty e.g. we do nothing when this condition occurs. When the Dialog is open, then we can input a new value in the Text box in the Dialog e.g. against prm_YourParam2 and click the Save button. This triggers our OnExecuteSave method, where we take the value assigned to prm_YourParam2 and update the original prm_YourParam1 value with the new value e.g. UpdatedValue. When we close the Dialog, it invokes the refresh that we had set on the Open Dialog Button User Interface Actions and we can see the updated result when the Dialog is closed and the main Dashboard is refreshed. Now that we know how to control Dashboard Actions and handle parameter passes effectively, we can build more sophisticated Dashboard Solutions with targeted refreshes, guarded actions and parameter handling like a professional.120Views2likes0CommentsReturning text from a BR# inside GetDataCell — possible?
I'm building a cube view column that shows combined annotations from descendants. I'm calling an Finance Cell Service BR from inside GetDataCell so I can pass dashboard params needed for the logic. GetDataCell(T#|CVTime|:BR#[BRName=..., FunctionName=CombinedComment, Flux_ID = {fluxID}]:U8#{ud8}):Name({ud8} Combined). I need to the UD8 POV member because that distinguishes what type of comment it is (CMvsPM, CQvsPQ, CMvsPYM, Ect...). The BR returns a String, but GetDataCell expects a numeric amount so the text doesn't render in the cell. Pointing the column at V#Annotation doesn't help either. Has anyone gotten BR-returned text to display in a GetDataCell with full POV/param context? Thanks, Ben84Views0likes1Comment- 38Views0likes1Comment
Genesis Upgrade
Hi all, I’m currently upgrading instances of Genesis-created workspaces and ran into an issue. The workspace named "Genesis" was upgraded successfully. However, the ones with different names are failing and returning the error below. For example, one of the affected workspaces is named "Landing Page." I’m not sure if the naming is related to the issue, but it’s the main difference I’ve noticed so far. Has anyone encountered something similar or knows how to resolve this? I’d really appreciate any guidance.Solved65Views0likes2CommentsIssue in Web Content and File Viewer component to directly open a HTML file in a browser
Dear community, I currently have an html document which is located in the file Explorer under "Documents/Public" folder. I am trying to get this HTML document to be presented into the components, embedded in a dashboard. However, with either a Web Content component or a File Viewer component (which will pinpoint to this specific file in Application Database File, as soon as I open the dashboard, it will load the html page into my default browser... I am using OS v8.1 ... is it a known bug or the expected behaviour ? What is even more strange, directing the Full File Name to a URL will correctly open a document in a dashboard ... Regards,3.2KViews0likes12CommentsEvent Listeners / Custom Control in a Dynamic Dashboard
Hello, To standardize the look and feel of my dashboards, I would like to create a reusable dashboard template for a toolbar. The Menu component seems well suited for this purpose. However, some actions (for example, Save) cannot be defined at the menu item level and are only available at the menu component level. As a workaround, I am using Event Listeners: each menu item sends a parameter value, which is then used as the Event Listener name. This allows me to have one menu item that performs a Save action, another that launches a business rule, another that opens a dialog, etc. This approach works fine until the Custom Control dashboard is embedded in a Dynamic Dashboard. The issue can be easily reproduced by embedding the dashboards described in this blog post into a dynamic dashboard. Any help or guidance would be greatly appreciated. Thanks in advance.77Views0likes2CommentsDynamic Cube Views and Workspaces
Dear community, I was reading the documentation about cube view services, which implies that the dynamic cube views that are accessible by Dynamic Cube View Services need to be in the same workspace. Do you know if this is mandatory to have dynamic cube views in the same workspace (as it seems a like a real issue in production) or is there a workaround to address dynamic cube views that are outside of the assembly's workspace ? Many thanks,83Views0likes3Comments