diff --git a/packages/toolpad-app/src/appDom.ts b/packages/toolpad-app/src/appDom.ts index fb4d87e7f3d..10d089f34ae 100644 --- a/packages/toolpad-app/src/appDom.ts +++ b/packages/toolpad-app/src/appDom.ts @@ -2,6 +2,7 @@ import { generateKeyBetween } from 'fractional-indexing'; import cuid from 'cuid'; import { NodeId, + NodeReference, ConstantAttrValue, BindableAttrValue, BindableAttrValues, @@ -106,7 +107,7 @@ export interface QueryNode extends AppDomNodeBase { readonly params?: BindableAttrValues

; readonly attributes: { readonly dataSource?: ConstantAttrValue; - readonly connectionId: ConstantAttrValue; + readonly connectionId: ConstantAttrValue; readonly query: ConstantAttrValue; readonly transform?: ConstantAttrValue; readonly transformEnabled?: ConstantAttrValue; @@ -803,3 +804,10 @@ export function createRenderTree(dom: AppDom): RenderTree { nodes: filterValues(dom.nodes, (node) => frontendNodes.has(node.type)) as RenderTreeNodes, }; } + +export function ref(nodeId: NodeId): NodeReference { + return { $$ref: nodeId }; +} +export function deref(nodeRef: NodeReference): NodeId { + return nodeRef.$$ref; +} diff --git a/packages/toolpad-app/src/runtime/ToolpadApp.tsx b/packages/toolpad-app/src/runtime/ToolpadApp.tsx index aa6d50e4e60..a0efcc0200b 100644 --- a/packages/toolpad-app/src/runtime/ToolpadApp.tsx +++ b/packages/toolpad-app/src/runtime/ToolpadApp.tsx @@ -235,7 +235,7 @@ function RenderedNodeContent({ node, childNodes, Component }: RenderedNodeConten const handler = () => { const { page } = action.value; if (page) { - navigateToPage(page); + navigateToPage(appDom.deref(page)); } }; diff --git a/packages/toolpad-app/src/server/data.ts b/packages/toolpad-app/src/server/data.ts index 57529e014f0..ce40dfe1b47 100644 --- a/packages/toolpad-app/src/server/data.ts +++ b/packages/toolpad-app/src/server/data.ts @@ -391,7 +391,10 @@ export async function execQuery( ); } - const connectionParams = await getConnectionParams

(appId, query.attributes.connectionId.value); + const connectionParams = await getConnectionParams

( + appId, + appDom.deref(query.attributes.connectionId.value), + ); const transformEnabled = query.attributes.transformEnabled?.value; const transform = query.attributes.transform?.value; diff --git a/packages/toolpad-app/src/toolpad/AppEditor/BindingEditor.tsx b/packages/toolpad-app/src/toolpad/AppEditor/BindingEditor.tsx index ea44cd66763..6ccd72e513f 100644 --- a/packages/toolpad-app/src/toolpad/AppEditor/BindingEditor.tsx +++ b/packages/toolpad-app/src/toolpad/AppEditor/BindingEditor.tsx @@ -186,7 +186,10 @@ function NavigationActionEditor({ value, onChange }: NavigationActionEditorProps const handlePageChange = React.useCallback( (event: React.ChangeEvent) => { - onChange({ type: 'navigationAction', value: { page: event.target.value as NodeId } }); + onChange({ + type: 'navigationAction', + value: { page: appDom.ref(event.target.value as NodeId) }, + }); }, [onChange], ); @@ -206,7 +209,7 @@ function NavigationActionEditor({ value, onChange }: NavigationActionEditorProps sx={{ my: 3 }} label="page" select - value={value?.value?.page || ''} + value={value?.value?.page ? appDom.deref(value.value.page) : ''} onChange={handlePageChange} disabled={!hasPagesAvailable} helperText={hasPagesAvailable ? null : 'No other pages available'} diff --git a/packages/toolpad-app/src/toolpad/AppEditor/PageEditor/QueryEditor.tsx b/packages/toolpad-app/src/toolpad/AppEditor/PageEditor/QueryEditor.tsx index 2f20ae14fdb..b1603279440 100644 --- a/packages/toolpad-app/src/toolpad/AppEditor/PageEditor/QueryEditor.tsx +++ b/packages/toolpad-app/src/toolpad/AppEditor/PageEditor/QueryEditor.tsx @@ -127,7 +127,7 @@ function ConnectionSelectorDialog({ open, onCreated, onClose }: DataSourceSel const queryNode = appDom.createNode(dom, 'query', { attributes: { query: appDom.createConst(dataSource.getInitialQueryValue()), - connectionId: appDom.createConst(connectionId), + connectionId: appDom.createConst(appDom.ref(connectionId)), dataSource: appDom.createConst(dataSourceId), }, }); @@ -180,7 +180,7 @@ function QueryNodeEditorDialog({ } }, [open, node]); - const connectionId = input.attributes.connectionId.value; + const connectionId = appDom.deref(input.attributes.connectionId.value); const connection = appDom.getMaybeNode(dom, connectionId, 'connection'); const dataSourceId = input.attributes.dataSource?.value; const dataSource = (dataSourceId && dataSources[dataSourceId]) || null; @@ -189,7 +189,9 @@ function QueryNodeEditorDialog({ setInput((existing) => update(existing, { attributes: update(existing.attributes, { - connectionId: newConnectionId ? appDom.createConst(newConnectionId) : undefined, + connectionId: newConnectionId + ? appDom.createConst(appDom.ref(newConnectionId)) + : undefined, }), }), ); @@ -380,7 +382,7 @@ function QueryNodeEditorDialog({ diff --git a/packages/toolpad-core/src/types.ts b/packages/toolpad-core/src/types.ts index db955d0c741..c3f91b3fe64 100644 --- a/packages/toolpad-core/src/types.ts +++ b/packages/toolpad-core/src/types.ts @@ -6,6 +6,10 @@ export type NodeId = Branded; export type BindingAttrValueFormat = 'stringLiteral' | 'default'; +export interface NodeReference { + $$ref: NodeId; +} + export interface BoundExpressionAttrValue { type: 'boundExpression'; value: string; @@ -40,7 +44,7 @@ export interface JsExpressionAction { export interface NavigationAction

{ type: 'navigationAction'; value: { - page: NodeId; + page: NodeReference; parameters?: BindableAttrValues

; }; }