microsoft / microsoft/vscode-powerquery-sdk
Invoked Function UI (typed function in leaf Data column) not rendered in the new Power Query "Get Data" experience
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 92
- Forks
- 23
- PR merge metrics
- No merged PRs in 30d
Description
Environment
Connector type: Custom Power Query connector (.mez), OAuth 2.0 + PKCE, GraphQL backend
Host: Power BI Desktop (new "Get Data" / Navigator experience) vs. classic experience
Pattern: Multi-level navigation table (Project → Folder → Table), where the leaf item exposes a typed function so users can configure filters before data is loaded
Summary
Our connector builds a hierarchical navigation table. For leaf nodes (the selectable 3D model / metadata dataset), instead of placing a table in the Data column, we place a typed function created with Value.ReplaceType(...). The function's parameters are decorated with Documentation.FieldCaption, Documentation.FieldDescription, Documentation.AllowedValues, Documentation.SampleValues, Formatting.IsMultiLine, and Formatting.IsCode.
In the classic experience, this leaf function is rendered as an Invoked Function UI directly inside the Navigator, so the user can pick filter values (Revit Category/Family/Type, property selection, references) and then load.
In the new Power Query experience, the Invoked Function UI is no longer rendered in the Navigator. The user is instead dropped into Transform Data, where the navigation table shows Data=Function. The function can still be invoked manually, but this adds extra steps and degrades the UX.
Technical Details
1. Leaf Data column holds a typed function (not a table)
We return a function whose type is applied via Value.ReplaceType, so Power Query treats it as an invocable, documented function:
DisplayProperty = type function (
filter as (type text meta [
Documentation.FieldCaption = "Filter Revit Elements By",
Documentation.AllowedValues = {"None", "Category", "Family", "Type"}
]),
optional Parameter as (type text meta [
Documentation.FieldCaption = "Revit Parameter",
Documentation.SampleValues = {"category:Walls, Floors, Doors|family: Basic Wall"},
Formatting.IsMultiLine = true,
Formatting.IsCode = true
]),
optional input as (type list meta [
Documentation.FieldCaption = "Select Properties",
Documentation.AllowedValues = <dynamic list from the exchange>
]),
optional reference as (type list meta [
Documentation.FieldCaption = "Select Revit Reference Properties",
Documentation.AllowedValues = <dynamic list from the exchange>
])
) as table
in
Value.ReplaceType(DisplayFilteredTable, DisplayProperty)
Note that Documentation.AllowedValues here is computed at runtime from a metadata call to the exchange (the available property/reference names differ per model), which is exactly why we want it surfaced before load.
2. Two navigation-table builders — with and without preview delay
For normal (non-filter) leaves we use the documented helper with Preview.DelayColumn:
newTableType = Type.AddTableKey(tableType, keyColumns, true) meta [
NavigationTable.NameColumn = nameColumn,
NavigationTable.DataColumn = dataColumn,
NavigationTable.ItemKindColumn = itemKindColumn,
Preview.DelayColumn = itemNameColumn, // Table.ToNavigationTable
NavigationTable.IsLeafColumn = isLeafColumn
]
For the filter path (where Data is the typed function) we use a variant that omits Preview.DataColumn, so the function isn't eagerly previewed:
newTableType = Type.AddTableKey(tableType, keyColumns, true) meta [
NavigationTable.NameColumn = nameColumn,
NavigationTable.DataColumn = dataColumn,
NavigationTable.ItemKindColumn = itemKindColumn,
NavigationTable.IsLeafColumn = isLeafColumn // Table.ToNavigationTableNoPreviewDelay (no Preview.DelayColumn)
]
The filter leaf is emitted like this (function placed directly in Data, ItemKind = "Table"):
objects = #table(
{"Name", "Key", "Data", "ItemKind", "ItemName", "IsLeaf"},
{{ tableName, exchangeName, UI /* typed function */, "Table", "Table", true }}
),
Table.ToNavigationTableNoPreviewDelay(objects, {"Key"}, "Name", "Data", "ItemKind", "ItemName", "IsLeaf")
Questions
- Is the "typed function in the leaf
Datacolumn" pattern still supported in the new Power Query experience? Is it intentionally deprecated? - Has the behavior of
Preview.DelayColumn/ a navigation table withoutPreview.DelayColumn(ourTable.ToNavigationTableNoPreviewDelay) changed in the new experience? - Is there a recommended new pattern for collecting user inputs via
Documentation.AllowedValuesbefore data load, without pushing the filtering step into Transform Data? - If the Invoked Function UI in the Navigator is being deprecated, what is the recommended migration path for connectors that rely on it?
References -
- https://learn.microsoft.com/en-us/power-query/install-sdk
- https://learn.microsoft.com/en-us/power-query/helper-functions
- https://learn.microsoft.com/en-us/power-query/handling-transformations
- https://learn.microsoft.com/en-us/power-query/handling-navigation-tables
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the connector's leaf navigation-table construction, the Value.ReplaceType function metadata, and the Preview.DelayColumn or Table.ToNavigationTableNoPreviewDelay variants described in the issue. Review the linked navigation-table, helper-function, and transformation documentation, then compare classic and new Get Data behavior. Done means establishing whether this pattern is supported and documenting the recommended migration path if it is not.
Written by the indexing model from the issue text.
Assessment
- Domain
- developer-experience, tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100