Ribbon Workbench vs. Power Fx Command Buttons

Power Fx command bar buttons (Commanding V2) is the latest exciting feature to be released into preview by the Power Platform team! Check out Casey's blog post and my first look video where I show how amazingly easy it is to add complex functionality to your model-driven command bars!

The Ribbon Workbench marked its 10-year anniversary this year and so it's fitting that the new Power Fx command buttons for model-driven apps have been released. This exciting new feature is part of the continued journey of converging the goodness of both model-driven apps and canvas apps into a single app that gives the best of both worlds! In this post, I'll identify some of the differences in functionality. This initial release provides the foundation for Power Fx and as you'll see there are still gaps - but I am confident that the functionality will be developed over the coming months.

Key Design differences

The Ribbon Workbench (and the underlying RibbonXml that supports it) has many legacy components that are baggage from the days when there was a Ribbon rather than a command bar. Things like Groups, Tabs & Templates have no meaning in the command bar as we see it today. For this reason, the new Power Fx command buttons have greatly simplified the model for customizing the model-driven app command bar.

Here are some of the key differences in the design:

  • Buttons, Commands & Visibility Rules are linked - In the Ribbon Workbench, you would create a button and then associate it with a command. With Power Fx commands, the button, command, and visibility rules are all linked together as a single unit.
  • Localized Labels are part of the solution translations - In the Ribbon Workbench, button label translations were part of the RibbonXml, whereas with Power Fx commands you can use the standard export/import translations feature for the solution to provide translations.
  • Customizations are deployed via separate solution components - In the Ribbon Workbench, your command buttons were deployed via the entity/table solution component. With Power Fx commands, you add the Component Library to your solution to deploy command buttons. At this time, the Component Library must be shared with the users separately to the model-driven app.
  • No need for a solution import - Since the Power Fx commands are deployed using Component Libraries, there is no need for the lengthy export/unpack/update/rezip/import cycle that happens when you publish from inside the Ribbon Workbench. This makes working with the Power FX Command buttons much quicker!
  • Power Fx solution packager required to see command details - When exporting the solution that contains the Command Component Libraries, the expressions are inside the .msapp files. To see the details, you will need to use the new Power Fx Solution Packager functionality to extract into yaml files and add this to source control. The great news is that canvas app unpacking/packing is now included in the PAC CLI.

You can still use JavaScript Commands!

Possibly one of the most important features of the new commanding feature is that you can still call your existing JavaScript for commands (but not Enable rules at this time). Why is this important? Because it makes the path to migrate to Version 2 commands easier where the functionality is not yet possible in Power Fx expressions.

Common Requirements

The following table shows common requirements that I find needed when customizing the command bar using the Ribbon Workbench. You'll see that there are still gaps that will require the Ribbon Workbench for the time being - but these will be addressed over time.

Common Requirement Ribbon Workbench Commanding V2
Hide existing OOTB button Hide Action Not yet available
Move existing OOTB button Customize Button and Drag to the new location Not yet available
Change label/icon of existing OOTB button Customize Button and edit properties Not yet available
Change command of existing OOTB button Customize Command and edit actions Not yet available
Pass CommandValueId to JavaScript Context when the same command is used on multiple buttons Set CommandValueId property Not applicable since the command is not separate from the button
Update a form value and then save the record Ribbon Workbench 'QuickJS' Smart Button or custom JavaScript.
The PrimaryControl Parameter provides the event context which can be used to access the form context.
Patch(Accounts,Self.Selected.Item,{'Credit Hold':'Credit Hold (Accounts)'.Yes});
Note: The form is automatically saved and refreshed!
Update/Create a related record Ribbon Workbench 'QuickJS' Smart Button or custom JavaScript that uses the WebApi and then calls refresh on the formContext provided by a PrimaryControl parameter. Update Related Record:
Patch(Accounts,Self.Selected.Item,{'Description':"edit"});

Create related record (An additional data source must be added to the component library )

Patch(Tasks,Defaults(Tasks),{Regarding:Self.Selected.Item,Subject:Concatenate("Test",Text(Now()))});
Note: The form is automatically refreshed!
Add buttons to a flyout button Use the Flyout or SplitButton toolbox control with a MenuSection Not yet available
Dynamically populate a flyout button (e.g. from a WebApi call) Use the PopulateQueryCommand with a Custom JavaScript Action Not yet available
Add buttons to the Application Ribbon so that they appear in multiple locations (including the global command bar) Add the Application Ribbon to the solution loaded into the Ribbon Workbench. The entity type can be used in a EntityRule to show buttons for multiple entities. Not yet available
Run a command on multiple selected records on a grid Use a Custom JavaScript Command that accepts SelectedControlSelectedItemIds as a parameter - and then iterate over the array, performing an action for each.

New! To apply an update to multiple selected records use something similar to:

ForAll(Self.Selected.AllItems As ThisRecord, Patch(Accounts, ThisRecord, { 'Credit Hold':'Credit Hold (Accounts)'.Yes }));
Display a blocking wait spinner whilst a long-running task is in progress Use showProgressIndicator inside Custom JavaScript. Not yet available in Power Fx command expressions
Run a Workflow on the current record Ribbon Workbench 'Run Workflow' Smart Button or custom JavaScript. Trigger a workflow on change of a form field change
Run a Report on the current record Ribbon Workbench 'Run Report' Smart Button or custom JavaScript. Use a Custom JavaScript function
Run a flow on the current record Ribbon Workbench 'Run Webhook' Smart Button or custom JavaScript. Use a Custom JavaScript function - but watch this space!
Open a dialog from a button Ribbon Workbench 'Open dialog' Smart Button linked to a Canvas App Use a Custom JavaScript function - but watch this space!

Visibility Rules

Perhaps the biggest gap in functionality at this time is in the area of visibility rules:

Common Requirement Ribbon Workbench Commanding V2
Show button only for a specific Form Use a Custom JavaScript Enable Rule or add the RibbonXml to the FormXml Not yet available
Show button only for a specific App Use a Custom JavaScript EnableRule that returns true for specific app unique names Commands are added to specific apps.
One button cannot be shared between apps at this time.
Show a button only for Web or Outlook client Use the CrmClientType Rule Not yet available
Show a button only when online/offline Use the CrmOfflineAccessStateRule Not yet available
Show a button based on the user's security privileges Use the RecordPriviledgeRule or MiscellaneousPrivilegeRule Not yet available
Show a button based on certain entity metadata (e.g. IsActivity) Use the EntityPropertyRule in a Display Rule Not yet available
Show a button only for existing or read-only records. Use the FormStateRule in a Display Rule Not yet available
Show a button only when a single record is selected in the grid Use the SelectionCountRule inside an EnableRule Visibility Expression:
CountRows(Self.Selected.AllItems)=1
Show a button based on a form field value ValueRule inside an EnableRule. refreshRibbon must be called inside the onchange event of the form field. Visibility Expression:
Self.Selected.Item.'Credit Hold'='Credit Hold (Accounts)'.Yes

NOTE: refreshRibbon still must be called if you want the button to show/hide when the field is changed.
Show a button only when a related record column has a specific value Use a Custom JavaScript EnableRule that performs a WebApi query. Self.Selected.Item.'Parent Account'.'Credit Hold'='Credit Hold (Accounts)'.Yes
Show a button when a form value matches a complex expression Use a Custom JavaScript EnableRule that performs a WebApi query or uses the provided formContext. StartsWith(Self.Selected.Item.'Account Name',"a")
Show a button when there are a specific number of related records matching a query Use a Custom JavaScript EnableRule that performs a WebApi query. CountRows(Self.Selected.Item.Contacts)>0
Note: This does not seem to work consistently at this time and gives a delegation warning.

Summary

I will come back to this page and update it as new features are unlocked. You can also read more in the official documentation. As you'll see from the tables above, there are some gaps (especially with Enable/Display rules) but I have no doubt that they will be filled 'in the fullness of time'. The ease at which you can create complex Power Fx expressions to perform logic that would have previously required some complex JavaScript is very exciting and will unlock many scenarios that were previously off-limits to low-code app makers.

@ScottDurow

Pingbacks and trackbacks (1)+

Comments are closed