Skip to content

Conversation

@max-mrgrsk
Copy link
Contributor

@max-mrgrsk max-mrgrsk commented Nov 13, 2025

Closes: #8577

datum-short.mp4

To do

Style Parameters Added:

  1. src/lang/modifyAst/gdt.ts - code mod
  2. src/lib/operations.ts - feature tree edit flow
  3. src/lib/commandBarConfigs/modelingCommandConfig.ts - review validation
  4. src/machines/modelingMachine.ts - event and state
  5. src/lib/toolbar.ts - icon and button
  6. src/components/layout/areas/FeatureTreePane.tsx - datum name is a value getValueDetail()
  7. src/components/CommandBar/CommandBarBasicInput.tsx - fixed 1Password interference
  8. src/lang/modifyAst/gdt.spec.ts - unit tests
  9. e2e/playwright/point-click.spec.ts - e2e tests
  10. src/components/layout/areas/FeatureTreePane.spec.ts feature tree test for getValueDetail()

Review Validation

similar to flatness, thanks @pierremtb

  • Checks engine connection
  • Applies AST modification
  • Mock executes via mockExecAstAndReportErrors() to validate generated code
  • Catches invalid parameters/selections before they reach app state
  • User cannot submit if validation fails

Quote Stripping & Validation

The || '' fallback in operations.ts enforces validation:

  • Edit mode: Extracts "A" from KCL + strips to A + shows in UI
  • Extraction fails: Returns '' + validation catches it with clear error message
  • No silent defaults
  • Command bar default: Schema has defaultValue: 'A' so UI always shows usable value

Notes for separate PR

  • Refactor all optional style related parameters into separate function for better reusability and maintaining all the upcoming features in gdt
  • Enable context menu on hover
  • You can trick the validation within the argument and select 2 faces
  • Can we actually see mockExec, that happens in the review phase?
  • Default plane and position should be normal to the face

Introduces addDatumGdt to create a gdt::datum call for a selected face in the AST. Ensures only one face is annotated, updates the AST with tagged face, and appends the annotation at the end of the AST body.
Added unit tests for the addDatumGdt function to verify correct datum annotation on cap, wall, and chamfer faces. Tests ensure proper tagging and GDT annotation insertion for each face type.
Added tests to verify that addDatumGdt fails when multiple or no faces are selected, ensuring proper error handling for invalid face selection scenarios.
Adds a check to ensure the datum name is a single character in the addDatumGdt function. Returns an error if the validation fails to prevent invalid datum names.
Added tests to ensure addDatumGdt rejects multi-character and empty datum names, verifying that only single-character names are accepted and appropriate error messages are returned.
Introduces the 'GDT Datum' command to the modelingCommandConfig schema and command set. This command allows users to add datum geometric dimensioning & tolerancing annotations to selected faces, with configurable node, face selection, and name. Marked as experimental and requires review.
Introduces the prepareToEditGdtDatum function to handle editing of GDT Datum operations, extracting face and name arguments and providing default values. Updates stdLibMap to use the new callback for 'gdt::datum'.
Changed the 'gdt-datum' button to trigger the 'Find and select command' for 'GDT Datum' in the modeling group. Updated its status to 'experimental' and revised the description for clarity.
Introduces support for the 'GDT Datum' modeling command, including event type, handler, and state logic. This enables experimental application of datum GDTs in the modeling workflow.
Added validation logic. Refactored gdt::datum call construction to use module path and updated related code to remove unnecessary mock execution error skipping.
Added calls to enginelessExecutor in GDT datum annotation tests to validate runtime consistency after AST modification. This ensures that the modified ASTs execute correctly in the test context.
@max-mrgrsk max-mrgrsk linked an issue Nov 13, 2025 that may be closed by this pull request
@max-mrgrsk max-mrgrsk self-assigned this Nov 13, 2025
@vercel
Copy link

vercel bot commented Nov 13, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
modeling-app Ready Ready Preview Comment Nov 17, 2025 7:10pm

@max-mrgrsk max-mrgrsk added feature Feature Requests area/ast area/tests/e2e high-priority area/tests/unit area/point-and-click area/command-palette Anything to do with the command palette (or command bar) system labels Nov 13, 2025
Introduces getUsedDatumNames and getNextAvailableDatumName functions to scan AST for used datum names and suggest the next available name. Integrates getNextAvailableDatumName into the command bar config for datum creation, ensuring default names do not conflict. Adds related tests for both AST utilities and command bar integration.
Relocated deduplicateFaceExprs, exprToKey, getUsedDatumNames, and getNextAvailableDatumName functions from earlier in the file to the end. No functional changes; improves code organization and readability.
Added a check to reject datum names containing double quotes in addDatumGdt. Updated tests to verify validation error is thrown for such names.
Added data attributes (data-1p-ignore, data-lpignore, data-form-type, data-bwignore) to the input element to prevent password managers and autofill extensions from interfering with command bar input.
Enhances the OperationItem component to display the datum name for 'gdt::datum' StdLibCall operations by extracting and formatting the 'name' argument from the code. This improves clarity when viewing GDT Datum operations in the feature tree.
The addDatumGdt function now supports optional parameters for framePosition, framePlane, fontPointSize, and fontScale. These allow more control over the feature control frame's display and annotation text, and variables for these arguments are inserted only when needed.
Introduces a new GDT Datum button to the toolbar fixture and adds comprehensive end-to-end tests for creating, editing, and deleting GDT Datum features via the command bar. The tests cover all argument and optional parameter flows, including UI interactions and code verification.
@max-mrgrsk max-mrgrsk marked this pull request as ready for review November 17, 2025 15:46
@max-mrgrsk max-mrgrsk requested a review from a team as a code owner November 17, 2025 15:46
Copy link
Contributor

@pierremtb pierremtb left a comment

Choose a reason for hiding this comment

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

Works great in Vercel Preview, and thanks for the comprehensive demo and details ❤️

Just a few comments before I approve, not all of them are 100% needed to merge especially as an experimental command.

Comment on lines +88 to +91
data-1p-ignore
data-lpignore="true"
data-form-type="other"
data-bwignore
Copy link
Contributor

Choose a reason for hiding this comment

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

Oh wow you had your pw manager try to fill this up?

Comment on lines +28 to +40
it('should extract datum name from GDT datum operation', () => {
const mockCode = 'gdt::datum(face = extrude001, name = "A")'
// Calculate sourceRange positions dynamically
const nameStart = mockCode.indexOf('"A"')
const nameEnd = nameStart + 3 // Length of "A" including quotes
const nameSourceRange: [number, number, number] = [nameStart, nameEnd, 0]
const mockOperation = createGdtDatumOperation(nameSourceRange)

const valueDetail = getFeatureTreeValueDetail(mockOperation, mockCode)

expect(valueDetail?.display).toBe('A')
expect(valueDetail?.calculated).toEqual({ type: 'String', value: 'A' })
})
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we add another test case for getFeatureTreeValueDetail about VariableDeclaration types?

|> close()
extrude001 = extrude(profile001, length = 10)`
const ast = assertParse(code, instanceInThisFile)
const { getUsedDatumNames } = await import('@src/lang/modifyAst/gdt')
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's move that import to the top?

nodeToEdit?: PathToNode
}): Error | { modifiedAst: Node<Program>; pathToNode: PathToNode } {
// Clone the AST to avoid mutating the original
let modifiedAst = structuredClone(ast)
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's also create a copied nodeToEdit here, so that mock exec doesn't mutate it.

  const mNodeToEdit = structuredClone(nodeToEdit)

and then use it throughout. Check other codemods for ref!

Comment on lines +285 to +287
const faceSelections = faces.graphSelections.filter((selection) =>
isFaceArtifact(selection.artifact)
)
Copy link
Contributor

Choose a reason for hiding this comment

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

Don't mind the extra step here, just wondering why this isn't a guarantee from the command bar?

Comment on lines +360 to +366
if (typeof framePlane === 'string') {
// Named plane like 'XY', 'XZ', 'YZ'
framePlaneExpr = createLocalName(framePlane)
} else {
// Variable reference
framePlaneExpr = valueOrVariable(framePlane)
}
Copy link
Contributor

Choose a reason for hiding this comment

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

I know you mentioned it in the note, would likely be good to get a helper fn here

Comment on lines +383 to +386
// Add optional labeled arguments if provided
if (framePositionExpr !== undefined) {
labeledArgs.push(createLabeledArg('framePosition', framePositionExpr))
}
Copy link
Contributor

Choose a reason for hiding this comment

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

I think I have a slight pref for the pattern at

const sectionalExpr = sectional
? [createLabeledArg('sectional', createLiteral(sectional))]
: []
and other codemods, of setting an empty array for that expr and then reconstructing it all in one array declaration but won't die on that hill

Comment on lines +1931 to +1933
defaultValue: (commandBarContext) => {
return getNextAvailableDatumName(kclManager.ast)
},
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
defaultValue: (commandBarContext) => {
return getNextAvailableDatumName(kclManager.ast)
},
defaultValue: (_) => getNextAvailableDatumName(kclManager.ast),


// Extract name argument as a plain string (strip quotes if present)
const nameRaw = extractStringArgument(operation, 'name')
const name = nameRaw?.replace(/^["']|["']$/g, '') || ''
Copy link
Contributor

Choose a reason for hiding this comment

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

I think that regex should be part of a tested util fn?

Comment on lines +3692 to +3694
}: {
input: ModelingCommandSchema['GDT Datum'] | undefined
}) => {
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we've been inconsistent with this due to branches in parallel, pretty sure @nadr0 introduced the dep injection here with #8511, check the other actors, maybe some need updating on main

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/ast area/command-palette Anything to do with the command palette (or command bar) system area/point-and-click area/tests/e2e area/tests/unit feature Feature Requests high-priority

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Point & Click support for GD&T Datum (MBD)

4 participants