diff --git a/datajunction-ui/src/app/pages/AddEditNodePage/NodeQueryField.jsx b/datajunction-ui/src/app/pages/AddEditNodePage/NodeQueryField.jsx index 0309682d7..7c83f03be 100644 --- a/datajunction-ui/src/app/pages/AddEditNodePage/NodeQueryField.jsx +++ b/datajunction-ui/src/app/pages/AddEditNodePage/NodeQueryField.jsx @@ -232,8 +232,9 @@ export const NodeQueryField = ({ djClient, value }) => { djNodeHoverTooltip({ getStatus: key => tableStatusRef.current[key], getKnownCatalogs: () => knownCatalogsRef.current, + fetchNodeDetails: name => djClient.node(name).catch(() => null), }), - [], + [djClient], ); return ( diff --git a/datajunction-ui/src/app/pages/AddEditNodePage/djNodeBadges.js b/datajunction-ui/src/app/pages/AddEditNodePage/djNodeBadges.js index a01daa95e..b0e9b93fa 100644 --- a/datajunction-ui/src/app/pages/AddEditNodePage/djNodeBadges.js +++ b/datajunction-ui/src/app/pages/AddEditNodePage/djNodeBadges.js @@ -274,11 +274,23 @@ export function renderTooltipDom(status, refKey) { return wrap; } +// Cache of node-detail fetches so re-hovering the same chip doesn't refetch. +// Lives at module scope (one editor + dom = one cache) — small enough that +// not bothering with an LRU. +const nodeDetailsCache = new Map(); + /** * Hover tooltip extension. Pairs with djNodeBadges so the same - * `getStatus` source of truth drives the popover content. + * `getStatus` source of truth drives the popover content. Additionally + * lazy-fetches the full node (columns, description, mode, version) on + * hover via `fetchNodeDetails`, and re-renders the tooltip in place + * when the promise resolves. */ -export function djNodeHoverTooltip({ getStatus, getKnownCatalogs }) { +export function djNodeHoverTooltip({ + getStatus, + getKnownCatalogs, + fetchNodeDetails, +}) { return hoverTooltip( (view, pos) => { const hit = refAtPos(view, pos); @@ -299,9 +311,46 @@ export function djNodeHoverTooltip({ getStatus, getKnownCatalogs }) { pos: hit.from, end: hit.to, above: true, - create: () => ({ - dom: renderTooltipDom(status || { refType: 'source' }, hit.key), - }), + create: () => { + const baseStatus = status || { refType: 'source' }; + const dom = renderTooltipDom(baseStatus, hit.key); + + // Lazy-fetch the full node so we can show columns + description. + // The validateNode dep object only carries {name, type, status}. + if ( + fetchNodeDetails && + baseStatus.kind !== 'invalid' && + baseStatus.kind !== 'registering' + ) { + const cached = nodeDetailsCache.get(hit.key); + const promise = cached || fetchNodeDetails(hit.key); + if (!cached) nodeDetailsCache.set(hit.key, promise); + + Promise.resolve(promise) + .then(full => { + if (!full) return; + const richDom = renderTooltipDom( + { + ...baseStatus, + node: { ...(baseStatus.node || {}), ...full }, + }, + hit.key, + ); + if (dom.parentNode) { + dom.parentNode.replaceChild(richDom, dom); + } else { + // Tooltip already detached — swap children so future refs + // see the rich content. + dom.replaceChildren(...richDom.childNodes); + } + }) + .catch(() => { + // Soft-fail — leave the bare header tooltip in place. + }); + } + + return { dom }; + }, }; }, { hoverTime: 150 }, diff --git a/datajunction-ui/src/app/pages/AddEditNodePage/index.jsx b/datajunction-ui/src/app/pages/AddEditNodePage/index.jsx index e8a81e2ae..7fa46cfe4 100644 --- a/datajunction-ui/src/app/pages/AddEditNodePage/index.jsx +++ b/datajunction-ui/src/app/pages/AddEditNodePage/index.jsx @@ -544,28 +544,6 @@ export function AddEditNodePage({ extensions = {} }) { ) : ( )} - {Object.entries(extensions).map( - ([key, ExtensionComponent]) => ( -
- { - if (!submitHandlers.includes(onSubmit)) { - if (prepend) { - submitHandlers.unshift(onSubmit); - } else { - submitHandlers.push(onSubmit); - } - } - }} - /> -
- ), - )}
@@ -579,6 +557,29 @@ export function AddEditNodePage({ extensions = {} }) {
+ {Object.entries(extensions).map( + ([key, ExtensionComponent]) => ( +
+ { + if (!submitHandlers.includes(onSubmit)) { + if (prepend) { + submitHandlers.unshift(onSubmit); + } else { + submitHandlers.push(onSubmit); + } + } + }} + /> +
+ ), + )} +