Compare commits

...

3 Commits

Author SHA1 Message Date
56c4ab27aa Merge branch 'main' into toast-does-not-accept-Errors 2024-06-04 02:03:34 -07:00
c551d88db4 add remove constraints to overlays (#2584)
* add remove constrainst to overlay three dot menu

* add tests
2024-06-04 06:29:20 +00:00
0df03656aa toast error does not accept error param 2024-05-22 19:38:54 -07:00
4 changed files with 174 additions and 22 deletions

View File

@ -4239,6 +4239,130 @@ ${extraLine ? "const myVar = segLen('seg01', part001)" : ''}`
} }
} }
}) })
test.describe('Testing remove constraints segments', () => {
const cases = [
{
before: `line([22 + 0, 2 + 0], %, 'seg01')`,
after: `line([22, 2], %, 'seg01')`,
},
{
before: `angledLine([5 + 0, 23.03 + 0], %, 'seg01')`,
after: `line([22.94, 2.01], %, 'seg01')`,
},
{
before: `xLine(23 + 0, %, 'seg01')`,
after: `line([23, 0], %, 'seg01')`,
},
{
before: `yLine(-8 + 0, %, 'seg01')`,
after: `line([0, -8], %, 'seg01')`,
},
{
before: `xLineTo(30 + 0, %, 'seg01')`,
after: `line([25, 0], %, 'seg01')`,
},
{
before: `yLineTo(-4 + 0, %, 'seg01')`,
after: `line([0, -10], %, 'seg01')`,
},
{
before: `angledLineOfXLength([3 + 0, 30 + 0], %, 'seg01')`,
after: `line([30, 1.57], %, 'seg01')`,
},
{
before: `angledLineOfYLength([3 + 0, 1.5 + 0], %, 'seg01')`,
after: `line([28.62, 1.5], %, 'seg01')`,
},
{
before: `angledLineToX([3 + 0, 30 + 0], %, 'seg01')`,
after: `line([25, 1.31], %, 'seg01')`,
},
{
before: `angledLineToY([3 + 0, 7 + 0], %, 'seg01')`,
after: `line([19.08, 1], %, 'seg01')`,
},
{
before: `angledLineOfXLength({ angle: 3 + 0, length: 30 + 0 }, %, 'seg01')`,
after: `line([30, 1.57], %, 'seg01')`,
},
{
before: `angledLineOfYLength({ angle: 3 + 0, length: 1.5 + 0 }, %, 'seg01')`,
after: `line([28.62, 1.5], %, 'seg01')`,
},
{
before: `angledLineToX({ angle: 3 + 0, to: 30 + 0 }, %, 'seg01')`,
after: `line([25, 1.31], %, 'seg01')`,
},
{
before: `angledLineToY({ angle: 3 + 0, to: 7 + 0 }, %, 'seg01')`,
after: `line([19.08, 1], %, 'seg01')`,
},
]
for (const { before, after } of cases) {
const isObj = before.includes('{ angle: 3')
test(`${before.split('(')[0]}${isObj ? '-[obj-input]' : ''}`, async ({
page,
}) => {
await page.addInitScript(
async ({ lineToBeDeleted }) => {
localStorage.setItem(
'persistCode',
`const part001 = startSketchOn('XZ')
|> startProfileAt([5, 6], %)
|> ${lineToBeDeleted}
|> line([-10, -15], %)
|> angledLine([-176, segLen('seg01', %)], %)`
)
},
{
lineToBeDeleted: before,
}
)
const u = await getUtils(page)
await page.setViewportSize({ width: 1200, height: 500 })
await page.goto('/')
await u.waitForAuthSkipAppStart()
await page.waitForTimeout(300)
await page.getByText(before).click()
await page.waitForTimeout(100)
await page.getByRole('button', { name: 'Edit Sketch' }).click()
await page.waitForTimeout(500)
await expect(page.getByTestId('segment-overlay')).toHaveCount(3)
const segmentToDelete = await u.getBoundingBox(
`[data-overlay-index="0"]`
)
const isYLine = before.toLowerCase().includes('yline')
const hoverPos = {
x: segmentToDelete.x + (isYLine ? 0 : -20),
y: segmentToDelete.y + (isYLine ? -20 : 0),
}
await expect(page.getByText('Added variable')).not.toBeVisible()
const ang = isYLine ? 45 : -45
const [x, y] = [
Math.cos((ang * Math.PI) / 180) * 45,
Math.sin((ang * Math.PI) / 180) * 45,
]
await page.mouse.move(hoverPos.x + x, hoverPos.y + y)
await page.mouse.move(hoverPos.x, hoverPos.y, { steps: 5 })
await expect(page.locator('.cm-content')).toContainText(before)
await page.getByTestId('overlay-menu').click()
await page.getByText('Remove constraints').click()
await expect(page.locator('.cm-content')).toContainText(after)
// check the cursor was left in the correct place after transform
await expect(page.locator('.cm-activeLine')).toHaveText('|> ' + after)
await expect(page.getByTestId('segment-overlay')).toHaveCount(3)
})
}
})
}) })
test('First escape in tool pops you out of tool, second exits sketch mode', async ({ test('First escape in tool pops you out of tool, second exits sketch mode', async ({
page, page,

View File

@ -420,12 +420,16 @@ const SegmentMenu = ({
verticalPosition === 'top' ? 'bottom-full' : 'top-full' verticalPosition === 'top' ? 'bottom-full' : 'top-full'
} z-10 w-36 flex flex-col gap-1 divide-y divide-chalkboard-20 dark:divide-chalkboard-70 align-stretch px-0 py-1 bg-chalkboard-10 dark:bg-chalkboard-100 rounded-sm shadow-lg border border-solid border-chalkboard-20/50 dark:border-chalkboard-80/50`} } z-10 w-36 flex flex-col gap-1 divide-y divide-chalkboard-20 dark:divide-chalkboard-70 align-stretch px-0 py-1 bg-chalkboard-10 dark:bg-chalkboard-100 rounded-sm shadow-lg border border-solid border-chalkboard-20/50 dark:border-chalkboard-80/50`}
> >
{/* <button className="hover:bg-white/80 bg-white/50 rounded p-1 text-nowrap">
Remove segment constraints
</button> */}
<button <button
className="!border-transparent rounded-sm text-left p-1 text-nowrap" className="!border-transparent rounded-sm text-left p-1 text-nowrap"
// disabled={dependentSourceRanges.length > 0} onClick={() => {
send({ type: 'Constrain remove constraints', data: pathToNode })
}}
>
Remove constraints
</button>
<button
className="!border-transparent rounded-sm text-left p-1 text-nowrap"
title={ title={
dependentSourceRanges.length > 0 dependentSourceRanges.length > 0
? `At least ${dependentSourceRanges.length} segment rely on this segment's tag.` ? `At least ${dependentSourceRanges.length} segment rely on this segment's tag.`

View File

@ -1,6 +1,6 @@
import { toolTips } from '../../useStore' import { toolTips } from '../../useStore'
import { Selections } from 'lib/selections' import { Selection, Selections } from 'lib/selections'
import { Program, Value } from '../../lang/wasm' import { PathToNode, Program, Value } from '../../lang/wasm'
import { import {
getNodePathFromSourceRange, getNodePathFromSourceRange,
getNodeFromPath, getNodeFromPath,
@ -14,15 +14,30 @@ import { kclManager } from 'lib/singletons'
export function removeConstrainingValuesInfo({ export function removeConstrainingValuesInfo({
selectionRanges, selectionRanges,
pathToNodes,
}: { }: {
selectionRanges: Selections selectionRanges: Selections
pathToNodes?: Array<PathToNode>
}) { }) {
const paths = selectionRanges.codeBasedSelections.map(({ range }) => const paths =
getNodePathFromSourceRange(kclManager.ast, range) pathToNodes ||
) selectionRanges.codeBasedSelections.map(({ range }) =>
getNodePathFromSourceRange(kclManager.ast, range)
)
const nodes = paths.map( const nodes = paths.map(
(pathToNode) => getNodeFromPath<Value>(kclManager.ast, pathToNode).node (pathToNode) => getNodeFromPath<Value>(kclManager.ast, pathToNode).node
) )
const updatedSelectionRanges = pathToNodes
? {
otherSelections: [],
codeBasedSelections: nodes.map(
(node): Selection => ({
range: [node.start, node.end],
type: 'default',
})
),
}
: selectionRanges
const isAllTooltips = nodes.every( const isAllTooltips = nodes.every(
(node) => (node) =>
node?.type === 'CallExpression' && node?.type === 'CallExpression' &&
@ -31,31 +46,36 @@ export function removeConstrainingValuesInfo({
try { try {
const transforms = getRemoveConstraintsTransforms( const transforms = getRemoveConstraintsTransforms(
selectionRanges, updatedSelectionRanges,
kclManager.ast, kclManager.ast,
'removeConstrainingValues' 'removeConstrainingValues'
) )
const enabled = isAllTooltips && transforms.every(Boolean) const enabled = isAllTooltips && transforms.every(Boolean)
return { enabled, transforms } return { enabled, transforms, updatedSelectionRanges }
} catch (e) { } catch (e) {
console.error(e) console.error(e)
return { enabled: false, transforms: [] } return { enabled: false, transforms: [], updatedSelectionRanges }
} }
} }
export function applyRemoveConstrainingValues({ export function applyRemoveConstrainingValues({
selectionRanges, selectionRanges,
pathToNodes,
}: { }: {
selectionRanges: Selections selectionRanges: Selections
pathToNodes?: Array<PathToNode>
}): { }): {
modifiedAst: Program modifiedAst: Program
pathToNodeMap: PathToNodeMap pathToNodeMap: PathToNodeMap
} { } {
const { transforms } = removeConstrainingValuesInfo({ selectionRanges }) const { transforms, updatedSelectionRanges } = removeConstrainingValuesInfo({
selectionRanges,
pathToNodes,
})
return transformAstSketchLines({ return transformAstSketchLines({
ast: kclManager.ast, ast: kclManager.ast,
selectionRanges, selectionRanges: updatedSelectionRanges,
transformInfos: transforms, transformInfos: transforms,
programMemory: kclManager.programMemory, programMemory: kclManager.programMemory,
referenceSegName: '', referenceSegName: '',

File diff suppressed because one or more lines are too long