In this blog post I will be sharing a part of my own experience while planning in unified stories using scripting, before we start, I would like to clearly state that the findings and ideas you will be reading were used to workaround limitations imposed by dropdown lists in 2 specific planning use cases I personally encountered.
In both scenarios the customers preferred to use the app scripting capabilities to display a popup including dropdowns for the data action parameter values over using the data action trigger itself, so dropdowns were a must, the scenario was:
Planning on dimensions that have a huge number of members, this issue can be encountered on many dimensions, such as Cost Element, Cost Object, WBS Elements, etc. In this use case the dimension had around 3000 members.
This is when the findings below where observed. As the number of members in the getMembers() API call went up beyond the default value, time to display the popup also increased, until it caused an out of memory error to all the tenant open tabs inside the browser.
Number of members | Time until the popup appears |
Default (200) | ~3 Seconds |
500 | ~4 Seconds |
1000 | ~8 Seconds |
1500 | ~38 Seconds then out of memory error |
So basically, there was no way to supply the dimension with all the 3000 members that must be available for the users to plan on, having it as an input text area would also be a terrible idea as there wouldn't be a robust way to have a value help/suggestions list, or some method to validate the entry.
Filtering out only open WBS Elements, despite there being a property that flags the closed ones, the main problem was that since this is a planning scenario, we could not simply filter them out while importing the masterdata, the reason why is because if we assume that:
WBS Element "A" was active in June 2023, while loading the masterdata, it is not going to be filtered out as the WBS Status property value is "unassigned".
Now let us assume that same WBS Element "A" had the Status property value set as "Closed" and no longer "unassigned", what will happen in the dimension during that load? Nothing, because the filter is set on the Status to be "unassgined", hence it will exclude the "Closed" record it should have received, the masterdata on SAC for that dimension will not be updated with "Closed", so that WBS Element remains active in the model itself, which is wrong. We need a way to somehow filter them out on the story level.
Input Control + Masterdata Model!
Input controls received a new set of script APIs in Q2 2023, these allow us to set/getActiveSelectedMembers to an input control, however these APIs currently support active members only, if you attempt to display unbooked values, the getActiveSelectedMembers() will return undefined, this is a limitation that is mentioned in the tooltip description of the API. This will be later addressed by using a dummy masterdata model, forcing all the plannable members to be be active (have posted values).
Planning against only posted values in a planning model, in this case we do not need anything else, we assume that the input control was used only due to the performance degradations experienced as we increase the number of members loaded to a dropdown, or in case the dropdown causes an out of memory error. Setup should be:
Basic Setup
Planning against unbooked values, such as a mirrored dimension, for example Sender Cost Object and Receiver Cost Object, where all receivers are initially loaded as "unassigned".
In this scenario we need to:
Masterdata Model Structure
Remember, all we need from this input control is capturing the keys of all applicable members and passing them to data/multi actions of any other model as parameter inputs, the input control is ideal for this as it goes not fire a getResponse(Backend call) unless it is open, it buffers additional members as you scroll down or specifically search for a certain member, this is ideal for performance in the 2 use cases this blog post is about.
This section addresses Use Case 2. So far, there is no best practice on how to filter values before populating them to a dropdown list, there is more than one idea, none of them seemed to be performance efficient.
Let us assume we need the Cost Element input control to return all the cost elements but the ones belonging to controlling area "0001", in other words we need to exclude "0001", I was able to fulfill a similar requirement using 2 input controls, one based on the Controlling Area, this one will be excluding "0001", using its cascading effect, it will filter out those values on the main Cost Element input control, the Controlling Area input control can be set as hidden during runtime.
The ideal setup here would be that the input control is based on a dedicated masterdata model, as Linked Analysis on the property filter input control only should be allowed on all widgets, the main reason why we need it to be set to all, is that we are unable to only select other input controls after the "Only selected widgets" option is chosen, hence having a dedicated model is considered as an appropriate workaround in this scenario as the input controls from the same source will only be impacting each other. Cascading effect also needs to be enabled on both input controls.
Property filter setup
Comparison Point | Input Control | Dropdown List |
Populating members | Not needed | Needed using addItem() in a for loop |
Number of members | Unlimited (Buffer as you scroll or search) | Limit lies in the getMembers() API used to supply it with values, it will cause an out of memory error after 1000 members |
Navigation performance | Acceptable | Much faster after the values are supplied |
Value Help & Suggestions | Exist | Exist |
Backend calls | Only happen if the input control is either expanded, opened, or further scrolled down | Will anyway happen in order to load the list of values |
Filtering member using properties | Can be easily done provided that there is a masterdata model | Hard to be fulfilled |
Hierarchy support | Out of the box | Hard to be fulfilled |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
20 | |
11 | |
8 | |
8 | |
7 | |
7 | |
7 | |
6 | |
6 | |
6 |