Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(devtools-core): Render ST's Visualizer to Include Root Field's Allowed Types #23573

Draft
wants to merge 10 commits into
base: main
Choose a base branch
from

Conversation

jikim-msft
Copy link
Contributor

@jikim-msft jikim-msft commented Jan 16, 2025

Description

26472

The current visualization generation logic in DefaultVisualizers.ts treats the root of the shared tree as a node and thus omits information that should be included in the root of the ST visualizer. Since the root field is allowed to have multiple types (i.e., different schema or primitive types), this information should be rendered in the tooltip of the visualizer.

This PR changes how the visualizer renders the allowed types in the tooltip

Example Schema

const config = new TreeViewConfiguration({
			schema: [RootNodeOne, RootNodeTwo, builder.string, builder.number],
		});

Before
Screenshot 2025-01-15 at 16 38 24

After
Non-Leaf Node
Screenshot 2025-01-15 at 17 10 51

Leaf Node
Screenshot 2025-01-15 at 17 11 59

@github-actions github-actions bot added the base: main PRs targeted against main branch label Jan 16, 2025
@@ -1730,6 +1730,380 @@ describe("DefaultVisualizers unit tests", () => {
expect(result).to.deep.equal(expected);
});

it.only("SharedTree: Renders multiple allowed types in SharedTree's root field", async () => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will be removing only() (and the one below), once we agree on the structure of the visualization (especially adding the root layer).

allowedTypes: concatenateTypes(treeSchema.allowedTypes),
},
fields: {
root: await visualizeSharedTreeNodeBySchema(treeView, treeSchema, visualizeChildData),
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Initially thought of replacing this with visualizeVerboseNodeFields() which iterates through tree.fields.

However, a leaf node in the root of the field can not have type VerboseTreeNode from exportVerbose() which is the expected type of visualizeVerboseNodeFields().

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe @CraigMacomber can offer some recommendations around typing here?

Copy link
Contributor

@CraigMacomber CraigMacomber Jan 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

consider also note (and test) that the root can be optional, and undefined. There is error thrown in that case above this: this case should also be fixed.

I think the fix that makes sense here is to handle the root using the same code which handles fields of objects. Both have a field schema, and the same set of things that could be in the content or schema. The document root really is the same as an object node field: they use the same types and implementation.

Factor out a function from the object node handling code which takes in a field schema and its content, then call that with treeView (up on line 268) instead of all this logic.

visualizeChildData,
);
const sf = new SchemaFactory(undefined);
const schemaName = Tree.is(treeView, [sf.boolean, sf.null, sf.number, sf.handle, sf.string])
Copy link
Contributor

@Josmithr Josmithr Jan 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to special-case primitives here? Can we not just use Tree.schema(treeView).identifier?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TreeNodeApi.schema accepts either a TreeNode or a TreeLeafValue.

If TreeView is a non-leaf node (thus has a type of VerboseTree), I believe we should use type to get its metadata.

}) {}

class RootNodeTwo extends builder.object("root-node-two", {
childField: builder.optional(RootNodeTwoItem),
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

builder.optional added to ensure rendering undefined object.

if (treeView === undefined) {
throw new Error("Support for visualizing empty trees is not implemented");
return {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Initializing the view with view.initialize({}) will render:

Screenshot 2025-01-17 at 11 59 20

tree: VerboseTree,
treeSchema: SimpleTreeSchema,
visualizeChildData: VisualizeChildData,
isRootField?: boolean,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Josmithr

Interested in your thoughts of this optional parameter. This is to display all the allowed types of the "first" rootfield when it is populated by the leaf-node.

Copy link
Contributor

@Josmithr Josmithr Jan 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This shouldn't be needed. Fundamentally, there is no difference between the root field and any other.

Where we're using it below - does this not recreate the same issue we're trying to fix? E.g., if the root field allows number | string, but the tree is of type number, won't that just display "number" when we want "number | string"?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, excuse me, I was reading the code backwards. I think the change creates the problem for non-root fields?

Shouldn't we just always call concatenateTypes(treeSchema.allowedTypes)?

@jikim-msft jikim-msft requested a review from Josmithr January 17, 2025 23:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
base: main PRs targeted against main branch
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants