Submit selection to command on unmount of selection arg input (#7047)
* Submit selection to command on unmount of selection arg input This fixes #7024 by saving the user's selection to the command even if they click another argument in the command palette's header. It does no harm to save the selection to the argument, even if it's being torn down because the user dismissed it has no negative effect. * Refactor to not auto-submit before selection is cleared on mount Thanks E2E test suite * Update failing E2E tests with new behavior, which allows skip with preselection --------- Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
This commit is contained in:
@ -38,20 +38,22 @@ test.describe('Command bar tests', () => {
|
|||||||
// Click the line of code for xLine.
|
// Click the line of code for xLine.
|
||||||
await page.getByText(`startProfile(at = [-10, -10])`).click()
|
await page.getByText(`startProfile(at = [-10, -10])`).click()
|
||||||
|
|
||||||
|
// Wait for the selection to register (TODO: we need a definitive way to wait for this)
|
||||||
|
await page.waitForTimeout(200)
|
||||||
|
|
||||||
await toolbar.extrudeButton.click()
|
await toolbar.extrudeButton.click()
|
||||||
await cmdBar.expectState({
|
await cmdBar.expectState({
|
||||||
stage: 'arguments',
|
stage: 'arguments',
|
||||||
commandName: 'Extrude',
|
commandName: 'Extrude',
|
||||||
currentArgKey: 'sketches',
|
currentArgKey: 'length',
|
||||||
currentArgValue: '',
|
currentArgValue: '5',
|
||||||
headerArguments: {
|
headerArguments: {
|
||||||
Profiles: '',
|
Profiles: '1 profile',
|
||||||
Length: '',
|
Length: '',
|
||||||
},
|
},
|
||||||
highlightedHeaderArg: 'Profiles',
|
highlightedHeaderArg: 'length',
|
||||||
})
|
})
|
||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
await cmdBar.progressCmdBar()
|
|
||||||
await cmdBar.expectState({
|
await cmdBar.expectState({
|
||||||
stage: 'review',
|
stage: 'review',
|
||||||
commandName: 'Extrude',
|
commandName: 'Extrude',
|
||||||
|
@ -1131,8 +1131,9 @@ sketch001 = startSketchOn(XZ)
|
|||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
|
|
||||||
await page.getByText('startProfile(at = [4.61, -14.01])').click()
|
await page.getByText('startProfile(at = [4.61, -14.01])').click()
|
||||||
|
// Wait for the selection to register (TODO: we need a definitive way to wait for this)
|
||||||
|
await page.waitForTimeout(200)
|
||||||
await toolbar.extrudeButton.click()
|
await toolbar.extrudeButton.click()
|
||||||
await cmdBar.progressCmdBar()
|
|
||||||
await cmdBar.expectState({
|
await cmdBar.expectState({
|
||||||
stage: 'arguments',
|
stage: 'arguments',
|
||||||
currentArgKey: 'length',
|
currentArgKey: 'length',
|
||||||
@ -1354,7 +1355,9 @@ sketch001 = startSketchOn(XZ)
|
|||||||
const u = await getUtils(page)
|
const u = await getUtils(page)
|
||||||
const projectLink = page.getByRole('link', { name: 'cube' })
|
const projectLink = page.getByRole('link', { name: 'cube' })
|
||||||
const gizmo = page.locator('[aria-label*=gizmo]')
|
const gizmo = page.locator('[aria-label*=gizmo]')
|
||||||
const resetCameraButton = page.getByRole('button', { name: 'Reset view' })
|
const resetCameraButton = page.getByRole('button', {
|
||||||
|
name: 'Reset view',
|
||||||
|
})
|
||||||
const locationToHaveColor = async (
|
const locationToHaveColor = async (
|
||||||
position: { x: number; y: number },
|
position: { x: number; y: number },
|
||||||
color: [number, number, number]
|
color: [number, number, number]
|
||||||
|
@ -74,15 +74,6 @@ test.describe('Point-and-click tests', () => {
|
|||||||
|
|
||||||
await test.step('do extrude flow and check extrude code is added to editor', async () => {
|
await test.step('do extrude flow and check extrude code is added to editor', async () => {
|
||||||
await toolbar.extrudeButton.click()
|
await toolbar.extrudeButton.click()
|
||||||
await cmdBar.expectState({
|
|
||||||
stage: 'arguments',
|
|
||||||
currentArgKey: 'sketches',
|
|
||||||
currentArgValue: '',
|
|
||||||
headerArguments: { Profiles: '', Length: '' },
|
|
||||||
highlightedHeaderArg: 'Profiles',
|
|
||||||
commandName: 'Extrude',
|
|
||||||
})
|
|
||||||
await cmdBar.progressCmdBar()
|
|
||||||
await cmdBar.expectState({
|
await cmdBar.expectState({
|
||||||
stage: 'arguments',
|
stage: 'arguments',
|
||||||
currentArgKey: 'length',
|
currentArgKey: 'length',
|
||||||
@ -1654,15 +1645,6 @@ sketch002 = startSketchOn(plane001)
|
|||||||
|
|
||||||
await test.step(`Go through the command bar flow with preselected sketches`, async () => {
|
await test.step(`Go through the command bar flow with preselected sketches`, async () => {
|
||||||
await toolbar.loftButton.click()
|
await toolbar.loftButton.click()
|
||||||
await cmdBar.expectState({
|
|
||||||
stage: 'arguments',
|
|
||||||
currentArgKey: 'sketches',
|
|
||||||
currentArgValue: '',
|
|
||||||
headerArguments: { Profiles: '' },
|
|
||||||
highlightedHeaderArg: 'Profiles',
|
|
||||||
commandName: 'Loft',
|
|
||||||
})
|
|
||||||
await cmdBar.progressCmdBar()
|
|
||||||
await cmdBar.expectState({
|
await cmdBar.expectState({
|
||||||
stage: 'review',
|
stage: 'review',
|
||||||
headerArguments: { Profiles: '2 profiles' },
|
headerArguments: { Profiles: '2 profiles' },
|
||||||
@ -2106,18 +2088,6 @@ extrude001 = extrude(sketch001, length = -12)
|
|||||||
await test.step(`Apply fillet to the preselected edge`, async () => {
|
await test.step(`Apply fillet to the preselected edge`, async () => {
|
||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
await toolbar.filletButton.click()
|
await toolbar.filletButton.click()
|
||||||
await cmdBar.expectState({
|
|
||||||
commandName: 'Fillet',
|
|
||||||
highlightedHeaderArg: 'selection',
|
|
||||||
currentArgKey: 'selection',
|
|
||||||
currentArgValue: '',
|
|
||||||
headerArguments: {
|
|
||||||
Selection: '',
|
|
||||||
Radius: '',
|
|
||||||
},
|
|
||||||
stage: 'arguments',
|
|
||||||
})
|
|
||||||
await cmdBar.progressCmdBar()
|
|
||||||
await cmdBar.expectState({
|
await cmdBar.expectState({
|
||||||
commandName: 'Fillet',
|
commandName: 'Fillet',
|
||||||
highlightedHeaderArg: 'radius',
|
highlightedHeaderArg: 'radius',
|
||||||
@ -2647,18 +2617,6 @@ extrude001 = extrude(profile001, length = 5)
|
|||||||
await test.step(`Apply fillet`, async () => {
|
await test.step(`Apply fillet`, async () => {
|
||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
await toolbar.filletButton.click()
|
await toolbar.filletButton.click()
|
||||||
await cmdBar.expectState({
|
|
||||||
commandName: 'Fillet',
|
|
||||||
highlightedHeaderArg: 'selection',
|
|
||||||
currentArgKey: 'selection',
|
|
||||||
currentArgValue: '',
|
|
||||||
headerArguments: {
|
|
||||||
Selection: '',
|
|
||||||
Radius: '',
|
|
||||||
},
|
|
||||||
stage: 'arguments',
|
|
||||||
})
|
|
||||||
await cmdBar.progressCmdBar()
|
|
||||||
await cmdBar.expectState({
|
await cmdBar.expectState({
|
||||||
commandName: 'Fillet',
|
commandName: 'Fillet',
|
||||||
highlightedHeaderArg: 'radius',
|
highlightedHeaderArg: 'radius',
|
||||||
@ -2764,19 +2722,6 @@ extrude001 = extrude(sketch001, length = -12)
|
|||||||
await test.step(`Apply chamfer to the preselected edge`, async () => {
|
await test.step(`Apply chamfer to the preselected edge`, async () => {
|
||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
await toolbar.chamferButton.click()
|
await toolbar.chamferButton.click()
|
||||||
await cmdBar.expectState({
|
|
||||||
commandName: 'Chamfer',
|
|
||||||
highlightedHeaderArg: 'selection',
|
|
||||||
currentArgKey: 'selection',
|
|
||||||
currentArgValue: '',
|
|
||||||
headerArguments: {
|
|
||||||
Selection: '',
|
|
||||||
Length: '',
|
|
||||||
},
|
|
||||||
stage: 'arguments',
|
|
||||||
})
|
|
||||||
await cmdBar.progressCmdBar()
|
|
||||||
await page.waitForTimeout(1000)
|
|
||||||
await cmdBar.expectState({
|
await cmdBar.expectState({
|
||||||
commandName: 'Chamfer',
|
commandName: 'Chamfer',
|
||||||
highlightedHeaderArg: 'length',
|
highlightedHeaderArg: 'length',
|
||||||
@ -3260,8 +3205,6 @@ extrude001 = extrude(sketch001, length = 30)
|
|||||||
await test.step(`Go through the command bar flow with a preselected face (cap)`, async () => {
|
await test.step(`Go through the command bar flow with a preselected face (cap)`, async () => {
|
||||||
await toolbar.shellButton.click()
|
await toolbar.shellButton.click()
|
||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
await page.waitForTimeout(500)
|
|
||||||
await cmdBar.progressCmdBar()
|
|
||||||
await cmdBar.expectState({
|
await cmdBar.expectState({
|
||||||
stage: 'review',
|
stage: 'review',
|
||||||
headerArguments: {
|
headerArguments: {
|
||||||
@ -3695,12 +3638,13 @@ tag=$rectangleSegmentC002,
|
|||||||
// revolve
|
// revolve
|
||||||
await editor.scrollToText(codeToSelection)
|
await editor.scrollToText(codeToSelection)
|
||||||
await page.getByText(codeToSelection).click()
|
await page.getByText(codeToSelection).click()
|
||||||
|
// Wait for the selection to register (TODO: we need a definitive way to wait for this)
|
||||||
|
await page.waitForTimeout(200)
|
||||||
await toolbar.revolveButton.click()
|
await toolbar.revolveButton.click()
|
||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
await cmdBar.progressCmdBar()
|
|
||||||
|
|
||||||
const newCodeToFind = `revolve001 = revolve(sketch002, angle = 360, axis = X)`
|
const newCodeToFind = `revolve001 = revolve(sketch002, angle = 360, axis = X)`
|
||||||
expect(editor.expectEditor.toContain(newCodeToFind)).toBeTruthy()
|
expect(editor.expectEditor.toContain(newCodeToFind)).toBeTruthy()
|
||||||
@ -4629,18 +4573,6 @@ path001 = startProfile(sketch001, at = [0, 0])
|
|||||||
|
|
||||||
await test.step('Go through command bar flow', async () => {
|
await test.step('Go through command bar flow', async () => {
|
||||||
await toolbar.extrudeButton.click()
|
await toolbar.extrudeButton.click()
|
||||||
await cmdBar.expectState({
|
|
||||||
stage: 'arguments',
|
|
||||||
currentArgKey: 'sketches',
|
|
||||||
currentArgValue: '',
|
|
||||||
headerArguments: {
|
|
||||||
Profiles: '',
|
|
||||||
Length: '',
|
|
||||||
},
|
|
||||||
highlightedHeaderArg: 'Profiles',
|
|
||||||
commandName: 'Extrude',
|
|
||||||
})
|
|
||||||
await cmdBar.progressCmdBar()
|
|
||||||
await cmdBar.expectState({
|
await cmdBar.expectState({
|
||||||
stage: 'arguments',
|
stage: 'arguments',
|
||||||
currentArgKey: 'length',
|
currentArgKey: 'length',
|
||||||
@ -4723,19 +4655,6 @@ path001 = startProfile(sketch001, at = [0, 0])
|
|||||||
|
|
||||||
await test.step('Go through command bar flow', async () => {
|
await test.step('Go through command bar flow', async () => {
|
||||||
await toolbar.sweepButton.click()
|
await toolbar.sweepButton.click()
|
||||||
await cmdBar.expectState({
|
|
||||||
stage: 'arguments',
|
|
||||||
currentArgKey: 'sketches',
|
|
||||||
currentArgValue: '',
|
|
||||||
headerArguments: {
|
|
||||||
Profiles: '',
|
|
||||||
Path: '',
|
|
||||||
Sectional: '',
|
|
||||||
},
|
|
||||||
highlightedHeaderArg: 'Profiles',
|
|
||||||
commandName: 'Sweep',
|
|
||||||
})
|
|
||||||
await cmdBar.progressCmdBar()
|
|
||||||
await cmdBar.expectState({
|
await cmdBar.expectState({
|
||||||
stage: 'arguments',
|
stage: 'arguments',
|
||||||
currentArgKey: 'path',
|
currentArgKey: 'path',
|
||||||
@ -4820,19 +4739,6 @@ path001 = startProfile(sketch001, at = [0, 0])
|
|||||||
await test.step('Go through command bar flow', async () => {
|
await test.step('Go through command bar flow', async () => {
|
||||||
await toolbar.closePane('code')
|
await toolbar.closePane('code')
|
||||||
await toolbar.revolveButton.click()
|
await toolbar.revolveButton.click()
|
||||||
await cmdBar.expectState({
|
|
||||||
stage: 'arguments',
|
|
||||||
currentArgKey: 'sketches',
|
|
||||||
currentArgValue: '',
|
|
||||||
headerArguments: {
|
|
||||||
Profiles: '',
|
|
||||||
AxisOrEdge: '',
|
|
||||||
Angle: '',
|
|
||||||
},
|
|
||||||
highlightedHeaderArg: 'Profiles',
|
|
||||||
commandName: 'Revolve',
|
|
||||||
})
|
|
||||||
await cmdBar.progressCmdBar()
|
|
||||||
await cmdBar.expectState({
|
await cmdBar.expectState({
|
||||||
stage: 'arguments',
|
stage: 'arguments',
|
||||||
currentArgKey: 'axisOrEdge',
|
currentArgKey: 'axisOrEdge',
|
||||||
|
@ -1016,7 +1016,6 @@ profile001 = startProfile(sketch001, at = [${roundOff(scale * 69.6)}, ${roundOff
|
|||||||
|
|
||||||
// sketch selection should already have been made.
|
// sketch selection should already have been made.
|
||||||
// otherwise the cmdbar would be waiting for a selection.
|
// otherwise the cmdbar would be waiting for a selection.
|
||||||
await cmdBar.progressCmdBar()
|
|
||||||
await cmdBar.expectState({
|
await cmdBar.expectState({
|
||||||
stage: 'arguments',
|
stage: 'arguments',
|
||||||
currentArgKey: 'length',
|
currentArgKey: 'length',
|
||||||
|
@ -573,7 +573,6 @@ profile001 = startProfile(sketch002, at = [-12.34, 12.34])
|
|||||||
await expect(page.getByTestId('command-bar')).toBeVisible()
|
await expect(page.getByTestId('command-bar')).toBeVisible()
|
||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
|
|
||||||
await cmdBar.progressCmdBar()
|
|
||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
await expect(page.getByText('Confirm Extrude')).toBeVisible()
|
await expect(page.getByText('Confirm Extrude')).toBeVisible()
|
||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
|
@ -54,6 +54,7 @@ function CommandBarSelectionInput({
|
|||||||
const inputRef = useRef<HTMLInputElement>(null)
|
const inputRef = useRef<HTMLInputElement>(null)
|
||||||
const commandBarState = useCommandBarState()
|
const commandBarState = useCommandBarState()
|
||||||
const [hasSubmitted, setHasSubmitted] = useState(false)
|
const [hasSubmitted, setHasSubmitted] = useState(false)
|
||||||
|
const [hasClearedSelection, setHasClearedSelection] = useState(false)
|
||||||
const selection = useSelector(arg.machineActor, selectionSelector)
|
const selection = useSelector(arg.machineActor, selectionSelector)
|
||||||
const selectionsByType = useMemo(() => {
|
const selectionsByType = useMemo(() => {
|
||||||
return getSelectionCountByType(selection)
|
return getSelectionCountByType(selection)
|
||||||
@ -102,7 +103,7 @@ function CommandBarSelectionInput({
|
|||||||
if (canSubmitSelection && arg.skip && argValue === undefined) {
|
if (canSubmitSelection && arg.skip && argValue === undefined) {
|
||||||
handleSubmit()
|
handleSubmit()
|
||||||
}
|
}
|
||||||
}, [canSubmitSelection])
|
}, [arg.name, canSubmitSelection])
|
||||||
|
|
||||||
function handleChange() {
|
function handleChange() {
|
||||||
inputRef.current?.focus()
|
inputRef.current?.focus()
|
||||||
@ -139,7 +140,30 @@ function CommandBarSelectionInput({
|
|||||||
selectionType: 'singleCodeCursor',
|
selectionType: 'singleCodeCursor',
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}, [arg.clearSelectionFirst])
|
setHasClearedSelection(true)
|
||||||
|
}, [arg])
|
||||||
|
|
||||||
|
// Watch for outside teardowns of this component
|
||||||
|
// (such as clicking another argument in the command palette header)
|
||||||
|
// and quickly save the current selection if we can
|
||||||
|
useEffect(() => {
|
||||||
|
return () => {
|
||||||
|
const resolvedSelection: Selections | undefined = isArgRequired
|
||||||
|
? selection
|
||||||
|
: selection || {
|
||||||
|
graphSelections: [],
|
||||||
|
otherSelections: [],
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
!(arg.clearSelectionFirst && !hasClearedSelection) &&
|
||||||
|
canSubmitSelection &&
|
||||||
|
resolvedSelection
|
||||||
|
) {
|
||||||
|
onSubmit(resolvedSelection)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [hasClearedSelection])
|
||||||
|
|
||||||
// Set selection filter if needed, and reset it when the component unmounts
|
// Set selection filter if needed, and reset it when the component unmounts
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -63,7 +63,7 @@ export default function CommandBarSelectionMixedInput({
|
|||||||
setHasAutoSkipped(true)
|
setHasAutoSkipped(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [])
|
}, [arg.name])
|
||||||
|
|
||||||
// Set selection filter if needed, and reset it when the component unmounts
|
// Set selection filter if needed, and reset it when the component unmounts
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -71,6 +71,24 @@ export default function CommandBarSelectionMixedInput({
|
|||||||
return () => kclManager.defaultSelectionFilter(selection)
|
return () => kclManager.defaultSelectionFilter(selection)
|
||||||
}, [arg.selectionFilter])
|
}, [arg.selectionFilter])
|
||||||
|
|
||||||
|
// Watch for outside teardowns of this component
|
||||||
|
// (such as clicking another argument in the command palette header)
|
||||||
|
// and quickly save the current selection if we can
|
||||||
|
useEffect(() => {
|
||||||
|
return () => {
|
||||||
|
const resolvedSelection: Selections | undefined = isArgRequired
|
||||||
|
? selection
|
||||||
|
: selection || {
|
||||||
|
graphSelections: [],
|
||||||
|
otherSelections: [],
|
||||||
|
}
|
||||||
|
|
||||||
|
if (canSubmitSelection && resolvedSelection) {
|
||||||
|
onSubmit(resolvedSelection)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [])
|
||||||
|
|
||||||
function handleChange() {
|
function handleChange() {
|
||||||
inputRef.current?.focus()
|
inputRef.current?.focus()
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user