Skip to content

Commit d833482

Browse files
committed
feat(ui): add custom hover provider for JSON field tooltips
1 parent 27b11b3 commit d833482

1 file changed

Lines changed: 90 additions & 0 deletions

File tree

‎ui/src/core/page-components/agent-detail/modals/edit-control/json-editor-language.ts‎

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1614,6 +1614,95 @@ export function setupJsonEditorLanguageSupport(
16141614
schemas: [],
16151615
});
16161616

1617+
const hoverDisposable = monaco.languages.registerHoverProvider('json', {
1618+
provideHover(model, position) {
1619+
if (model.uri.toString() !== context.modelUri) return null;
1620+
if (!context.schema) return null;
1621+
1622+
const text = model.getValue();
1623+
const offset = model.getOffsetAt(position);
1624+
const tree = parseTree(text);
1625+
const location = getLocation(text, offset);
1626+
if (!location.path.length) return null;
1627+
1628+
const rootSchema = asSchema(context.schema);
1629+
const activeEvaluator = resolveActiveEvaluator(
1630+
context,
1631+
tree,
1632+
location.path
1633+
);
1634+
const cursor = resolveSchemaAtJsonPath(
1635+
context,
1636+
activeEvaluator,
1637+
location.isAtPropertyKey ? location.path.slice(0, -1) : location.path
1638+
);
1639+
1640+
// For property keys, show the property's schema description
1641+
if (location.isAtPropertyKey) {
1642+
const propName = location.path[location.path.length - 1];
1643+
if (typeof propName !== 'string' || !cursor.schema) return null;
1644+
const propSchema = getSchemaAtProperty(
1645+
cursor.schema,
1646+
propName,
1647+
cursor.rootSchema
1648+
);
1649+
const desc = getSchemaDescription(propSchema);
1650+
const title = getSchemaTitle(propSchema);
1651+
if (!desc && !title) return null;
1652+
1653+
const word = model.getWordAtPosition(position);
1654+
const range = word
1655+
? new monaco.Range(
1656+
position.lineNumber,
1657+
word.startColumn,
1658+
position.lineNumber,
1659+
word.endColumn
1660+
)
1661+
: undefined;
1662+
1663+
return {
1664+
range,
1665+
contents: [
1666+
{
1667+
value: `**${title ?? propName}**${desc ? '\n\n' + desc : ''}`,
1668+
},
1669+
],
1670+
};
1671+
}
1672+
1673+
// For values, show the value's schema info
1674+
if (cursor.schema) {
1675+
const desc = getSchemaDescription(cursor.schema);
1676+
const title = getSchemaTitle(cursor.schema);
1677+
const enumVals = getSchemaEnumValues(cursor.schema);
1678+
if (!desc && !title && enumVals.length === 0) return null;
1679+
1680+
const parts: string[] = [];
1681+
if (title) parts.push(`**${title}**`);
1682+
if (desc) parts.push(desc);
1683+
if (enumVals.length > 0)
1684+
parts.push(`Values: \`${enumVals.join('` | `')}\``);
1685+
1686+
const word = model.getWordAtPosition(position);
1687+
const range = word
1688+
? new monaco.Range(
1689+
position.lineNumber,
1690+
word.startColumn,
1691+
position.lineNumber,
1692+
word.endColumn
1693+
)
1694+
: undefined;
1695+
1696+
return {
1697+
range,
1698+
contents: [{ value: parts.join('\n\n') }],
1699+
};
1700+
}
1701+
1702+
return null;
1703+
},
1704+
});
1705+
16171706
const disposable = monaco.languages.registerCompletionItemProvider('json', {
16181707
triggerCharacters: COMPLETION_TRIGGER_CHARACTERS,
16191708
provideCompletionItems(model, position) {
@@ -1635,6 +1724,7 @@ export function setupJsonEditorLanguageSupport(
16351724
const codeActionDisposable = registerConditionCodeActions(monaco, context);
16361725

16371726
return () => {
1727+
hoverDisposable.dispose();
16381728
disposable.dispose();
16391729
codeActionDisposable.dispose();
16401730
};

0 commit comments

Comments
 (0)