Proper command bar UI support for optional args (#7506)
* WIP: Add bidirectional args to point-and-click Extrude Will eventually close #7495 * Wire up edit flow for symmetric * Show skip true args in header in review phase * Add bidirectionalLength * Make currentArg always part of header * WIP * Add twistAng * Proper optional args line in review * Labels in progress button and option arg section heading * Clean up extrude specific changes * More UI polish * Remove options bool icon * Fix labels for tests * Upgrade e2e tests to cmdBar fixtures with fixes * More fixes * Fixed up more tests related to sweep behavior change * Fix nodeToEdit not having hidden: true on Shell * Add typecheck * WIP: footer buttons * back to reg width * Clean up * Clean up * Fix tests and remove label * Refactor * Fix offset plane test * Add CommandBarDivider * Fix step back * Add comment * Fix it, thanks bot * Clean up and inline optional heading * Little case tweak * Update src/components/CommandBar/CommandBarReview.tsx Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com> * Rename to CommandBarHeaderFooter --------- Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
This commit is contained in:
@ -307,7 +307,7 @@ test.describe('Command bar tests', () => {
|
||||
)
|
||||
|
||||
const continueButton = page.getByRole('button', { name: 'Continue' })
|
||||
const submitButton = page.getByRole('button', { name: 'Submit command' })
|
||||
const submitButton = page.getByTestId('command-bar-submit')
|
||||
await continueButton.click()
|
||||
|
||||
// Review step and argument hotkeys
|
||||
|
@ -54,9 +54,7 @@ test(
|
||||
await page.keyboard.press('Enter')
|
||||
|
||||
// Click the checkbox
|
||||
const submitButton = page.getByText('Confirm Export')
|
||||
await expect(submitButton).toBeVisible()
|
||||
await page.keyboard.press('Enter')
|
||||
await cmdBar.submit()
|
||||
|
||||
// Expect it to succeed
|
||||
const errorToastMessage = page.getByText(`Error while exporting`)
|
||||
@ -119,9 +117,7 @@ test(
|
||||
await page.keyboard.press('Enter')
|
||||
|
||||
// Click the checkbox
|
||||
const submitButton = page.getByText('Confirm Export')
|
||||
await expect(submitButton).toBeVisible()
|
||||
await page.keyboard.press('Enter')
|
||||
await cmdBar.submit()
|
||||
|
||||
// Look out for the toast message
|
||||
const exportingToastMessage = page.getByText(`Exporting...`)
|
||||
|
@ -118,15 +118,11 @@ export class CmdBarFixture {
|
||||
return
|
||||
}
|
||||
|
||||
const arrowButton = this.page.getByRole('button', {
|
||||
name: 'arrow right Continue',
|
||||
})
|
||||
const arrowButton = this.page.getByTestId('command-bar-continue')
|
||||
if (await arrowButton.isVisible()) {
|
||||
await arrowButton.click()
|
||||
await this.continue()
|
||||
} else {
|
||||
await this.page
|
||||
.getByRole('button', { name: 'checkmark Submit command' })
|
||||
.click()
|
||||
await this.submit()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1083,14 +1083,13 @@ openSketch = startSketchOn(XY)
|
||||
cmdBar,
|
||||
}) => {
|
||||
// One dumb hardcoded screen pixel value
|
||||
const testPoint = { x: 700, y: 150 }
|
||||
const testPoint = { x: 700, y: 200 }
|
||||
// TODO: replace the testPoint selection with a feature tree click once that's supported #7544
|
||||
const [clickOnXzPlane] = scene.makeMouseHelpers(testPoint.x, testPoint.y)
|
||||
const expectedOutput = `plane001 = offsetPlane(XZ, offset = 5)`
|
||||
|
||||
await homePage.goToModelingScene()
|
||||
// FIXME: Since there is no KCL code loaded. We need to wait for the scene to load before we continue.
|
||||
// The engine may not be connected
|
||||
await page.waitForTimeout(15000)
|
||||
await scene.settled(cmdBar)
|
||||
|
||||
await test.step(`Look for the blue of the XZ plane`, async () => {
|
||||
//await scene.expectPixelColor([50, 51, 96], testPoint, 15) // FIXME
|
||||
@ -1829,7 +1828,6 @@ profile002 = startProfile(sketch002, at = [0, 0])
|
||||
currentArgKey: 'sketches',
|
||||
currentArgValue: '',
|
||||
headerArguments: {
|
||||
Sectional: '',
|
||||
Profiles: '',
|
||||
Path: '',
|
||||
},
|
||||
@ -1843,7 +1841,6 @@ profile002 = startProfile(sketch002, at = [0, 0])
|
||||
currentArgKey: 'path',
|
||||
currentArgValue: '',
|
||||
headerArguments: {
|
||||
Sectional: '',
|
||||
Profiles: '1 profile',
|
||||
Path: '',
|
||||
},
|
||||
@ -1856,7 +1853,6 @@ profile002 = startProfile(sketch002, at = [0, 0])
|
||||
currentArgKey: 'path',
|
||||
currentArgValue: '',
|
||||
headerArguments: {
|
||||
Sectional: '',
|
||||
Profiles: '1 profile',
|
||||
Path: '',
|
||||
},
|
||||
@ -1869,7 +1865,6 @@ profile002 = startProfile(sketch002, at = [0, 0])
|
||||
headerArguments: {
|
||||
Profiles: '1 profile',
|
||||
Path: '1 segment',
|
||||
Sectional: '',
|
||||
},
|
||||
stage: 'review',
|
||||
})
|
||||
@ -1894,6 +1889,9 @@ profile002 = startProfile(sketch002, at = [0, 0])
|
||||
0
|
||||
)
|
||||
await operationButton.dblclick({ button: 'left' })
|
||||
await page
|
||||
.getByRole('button', { name: 'sectional', exact: false })
|
||||
.click()
|
||||
await cmdBar.expectState({
|
||||
commandName: 'Sweep',
|
||||
currentArgKey: 'sectional',
|
||||
@ -1971,7 +1969,6 @@ profile001 = ${circleCode}`
|
||||
currentArgKey: 'sketches',
|
||||
currentArgValue: '',
|
||||
headerArguments: {
|
||||
Sectional: '',
|
||||
Profiles: '',
|
||||
Path: '',
|
||||
},
|
||||
@ -1986,7 +1983,6 @@ profile001 = ${circleCode}`
|
||||
currentArgKey: 'path',
|
||||
currentArgValue: '',
|
||||
headerArguments: {
|
||||
Sectional: '',
|
||||
Profiles: '1 profile',
|
||||
Path: '',
|
||||
},
|
||||
@ -2000,7 +1996,6 @@ profile001 = ${circleCode}`
|
||||
currentArgKey: 'path',
|
||||
currentArgValue: '',
|
||||
headerArguments: {
|
||||
Sectional: '',
|
||||
Profiles: '1 profile',
|
||||
Path: '',
|
||||
},
|
||||
@ -2013,7 +2008,6 @@ profile001 = ${circleCode}`
|
||||
headerArguments: {
|
||||
Profiles: '1 profile',
|
||||
Path: '1 helix',
|
||||
Sectional: '',
|
||||
},
|
||||
stage: 'review',
|
||||
})
|
||||
@ -4734,7 +4728,6 @@ path001 = startProfile(sketch001, at = [0, 0])
|
||||
headerArguments: {
|
||||
Profiles: '',
|
||||
Path: '',
|
||||
Sectional: '',
|
||||
},
|
||||
highlightedHeaderArg: 'Profiles',
|
||||
commandName: 'Sweep',
|
||||
@ -4747,7 +4740,6 @@ path001 = startProfile(sketch001, at = [0, 0])
|
||||
headerArguments: {
|
||||
Profiles: '2 profiles',
|
||||
Path: '',
|
||||
Sectional: '',
|
||||
},
|
||||
highlightedHeaderArg: 'path',
|
||||
commandName: 'Sweep',
|
||||
@ -4760,7 +4752,6 @@ path001 = startProfile(sketch001, at = [0, 0])
|
||||
headerArguments: {
|
||||
Profiles: '2 profiles',
|
||||
Path: '1 segment',
|
||||
Sectional: '',
|
||||
},
|
||||
commandName: 'Sweep',
|
||||
})
|
||||
|
@ -475,6 +475,7 @@ test.describe('Can export from electron app', () => {
|
||||
},
|
||||
tronApp.projectDirName,
|
||||
page,
|
||||
cmdBar,
|
||||
method
|
||||
)
|
||||
)
|
||||
@ -779,9 +780,6 @@ test.describe(`Project management commands`, () => {
|
||||
const commandContinueButton = page.getByRole('button', {
|
||||
name: 'Continue',
|
||||
})
|
||||
const commandSubmitButton = page.getByRole('button', {
|
||||
name: 'Submit command',
|
||||
})
|
||||
const toastMessage = page.getByText(`Successfully renamed`)
|
||||
|
||||
await test.step(`Setup`, async () => {
|
||||
@ -800,8 +798,7 @@ test.describe(`Project management commands`, () => {
|
||||
await expect(commandContinueButton).toBeVisible()
|
||||
await commandContinueButton.click()
|
||||
|
||||
await expect(commandSubmitButton).toBeVisible()
|
||||
await commandSubmitButton.click()
|
||||
await cmdBar.submit()
|
||||
|
||||
await expect(toastMessage).toBeVisible()
|
||||
})
|
||||
@ -837,9 +834,6 @@ test.describe(`Project management commands`, () => {
|
||||
})
|
||||
const projectNameOption = page.getByRole('option', { name: projectName })
|
||||
const commandWarning = page.getByText('Are you sure you want to delete?')
|
||||
const commandSubmitButton = page.getByRole('button', {
|
||||
name: 'Submit command',
|
||||
})
|
||||
const toastMessage = page.getByText(`Successfully deleted`)
|
||||
const noProjectsMessage = page.getByText('No projects found')
|
||||
|
||||
@ -859,8 +853,7 @@ test.describe(`Project management commands`, () => {
|
||||
await projectNameOption.click()
|
||||
|
||||
await expect(commandWarning).toBeVisible()
|
||||
await expect(commandSubmitButton).toBeVisible()
|
||||
await commandSubmitButton.click()
|
||||
await cmdBar.submit()
|
||||
|
||||
await expect(toastMessage).toBeVisible()
|
||||
})
|
||||
@ -894,9 +887,6 @@ test.describe(`Project management commands`, () => {
|
||||
const commandContinueButton = page.getByRole('button', {
|
||||
name: 'Continue',
|
||||
})
|
||||
const commandSubmitButton = page.getByRole('button', {
|
||||
name: 'Submit command',
|
||||
})
|
||||
const toastMessage = page.getByText(`Successfully renamed`)
|
||||
|
||||
await test.step(`Setup`, async () => {
|
||||
@ -914,8 +904,7 @@ test.describe(`Project management commands`, () => {
|
||||
await expect(commandContinueButton).toBeVisible()
|
||||
await commandContinueButton.click()
|
||||
|
||||
await expect(commandSubmitButton).toBeVisible()
|
||||
await commandSubmitButton.click()
|
||||
await cmdBar.submit()
|
||||
|
||||
await expect(toastMessage).toBeVisible()
|
||||
})
|
||||
@ -949,9 +938,6 @@ test.describe(`Project management commands`, () => {
|
||||
})
|
||||
const projectNameOption = page.getByRole('option', { name: projectName })
|
||||
const commandWarning = page.getByText('Are you sure you want to delete?')
|
||||
const commandSubmitButton = page.getByRole('button', {
|
||||
name: 'Submit command',
|
||||
})
|
||||
const toastMessage = page.getByText(`Successfully deleted`)
|
||||
const noProjectsMessage = page.getByText('No projects found')
|
||||
|
||||
@ -967,8 +953,7 @@ test.describe(`Project management commands`, () => {
|
||||
await projectNameOption.click()
|
||||
|
||||
await expect(commandWarning).toBeVisible()
|
||||
await expect(commandSubmitButton).toBeVisible()
|
||||
await commandSubmitButton.click()
|
||||
await cmdBar.submit()
|
||||
|
||||
await expect(toastMessage).toBeVisible()
|
||||
})
|
||||
|
@ -1,6 +1,7 @@
|
||||
import path from 'path'
|
||||
import { bracket } from '@e2e/playwright/fixtures/bracket'
|
||||
import type { Page } from '@playwright/test'
|
||||
import type { CmdBarFixture } from '@e2e/playwright/fixtures/cmdBarFixture'
|
||||
import { reportRejection } from '@src/lib/trap'
|
||||
import * as fsp from 'fs/promises'
|
||||
|
||||
@ -421,10 +422,7 @@ extrude002 = extrude(profile002, length = 150)
|
||||
await page.keyboard.press('Enter')
|
||||
|
||||
// Click the checkbox
|
||||
const submitButton = page.getByText('Confirm Export')
|
||||
await expect(submitButton).toBeVisible()
|
||||
|
||||
await page.keyboard.press('Enter')
|
||||
await cmdBar.submit()
|
||||
|
||||
// Find the toast.
|
||||
// Look out for the toast message
|
||||
@ -461,8 +459,7 @@ extrude002 = extrude(profile002, length = 150)
|
||||
await page.keyboard.press('Enter')
|
||||
|
||||
// Click the checkbox
|
||||
await expect(submitButton).toBeVisible()
|
||||
await page.keyboard.press('Enter')
|
||||
await cmdBar.submit()
|
||||
|
||||
// Find the toast.
|
||||
// Look out for the toast message
|
||||
@ -482,6 +479,7 @@ extrude002 = extrude(profile002, length = 150)
|
||||
test('ensure you CAN export while an export is already going', async ({
|
||||
page,
|
||||
homePage,
|
||||
cmdBar,
|
||||
}) => {
|
||||
const u = await getUtils(page)
|
||||
await test.step('Set up the code and durations', async () => {
|
||||
@ -516,11 +514,11 @@ extrude002 = extrude(profile002, length = 150)
|
||||
const successToastMessage = page.getByText(`Exported successfully`)
|
||||
|
||||
await test.step('second export', async () => {
|
||||
await clickExportButton(page)
|
||||
await clickExportButton(page, cmdBar)
|
||||
|
||||
await expect(exportingToastMessage).toBeVisible()
|
||||
|
||||
await clickExportButton(page)
|
||||
await clickExportButton(page, cmdBar)
|
||||
|
||||
await test.step('The first export still succeeds', async () => {
|
||||
await Promise.all([
|
||||
@ -537,7 +535,7 @@ extrude002 = extrude(profile002, length = 150)
|
||||
|
||||
await test.step('Successful, unblocked export', async () => {
|
||||
// Try exporting again.
|
||||
await clickExportButton(page)
|
||||
await clickExportButton(page, cmdBar)
|
||||
|
||||
// Find the toast.
|
||||
// Look out for the toast message
|
||||
@ -880,7 +878,7 @@ s2 = startSketchOn(XY)
|
||||
})
|
||||
})
|
||||
|
||||
async function clickExportButton(page: Page) {
|
||||
async function clickExportButton(page: Page, cmdBar: CmdBarFixture) {
|
||||
await test.step('Running export flow', async () => {
|
||||
// export the model
|
||||
const exportButton = page.getByTestId('export-pane-button')
|
||||
@ -896,9 +894,6 @@ async function clickExportButton(page: Page) {
|
||||
await page.keyboard.press('Enter')
|
||||
|
||||
// Click the checkbox
|
||||
const submitButton = page.getByText('Confirm Export')
|
||||
await expect(submitButton).toBeVisible()
|
||||
|
||||
await page.keyboard.press('Enter')
|
||||
await cmdBar.submit()
|
||||
})
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ export const token = process.env.token || ''
|
||||
import type { ProjectConfiguration } from '@rust/kcl-lib/bindings/ProjectConfiguration'
|
||||
|
||||
import type { ElectronZoo } from '@e2e/playwright/fixtures/fixtureSetup'
|
||||
import type { CmdBarFixture } from '@e2e/playwright/fixtures/cmdBarFixture'
|
||||
import { isErrorWhitelisted } from '@e2e/playwright/lib/console-error-whitelist'
|
||||
import { TEST_SETTINGS, TEST_SETTINGS_KEY } from '@e2e/playwright/storageStates'
|
||||
import { test } from '@e2e/playwright/zoo-test'
|
||||
@ -737,6 +738,7 @@ export const doExport = async (
|
||||
output: Models['OutputFormat3d_type'],
|
||||
rootDir: string,
|
||||
page: Page,
|
||||
cmdBar: CmdBarFixture,
|
||||
exportFrom: 'dropdown' | 'sidebarButton' | 'commandBar' = 'dropdown'
|
||||
): Promise<Paths> => {
|
||||
if (exportFrom === 'dropdown') {
|
||||
@ -780,9 +782,7 @@ export const doExport = async (
|
||||
.click()
|
||||
await page.locator('#arg-form').waitFor({ state: 'detached' })
|
||||
}
|
||||
await expect(page.getByText('Confirm Export')).toBeVisible()
|
||||
|
||||
await page.getByRole('button', { name: 'Submit command' }).click()
|
||||
await cmdBar.submit()
|
||||
|
||||
await expect(page.getByText('Exported successfully')).toBeVisible()
|
||||
|
||||
|
@ -10,7 +10,7 @@ import {
|
||||
import { expect, test } from '@e2e/playwright/zoo-test'
|
||||
|
||||
test.describe('Testing constraints', () => {
|
||||
test('Can constrain line length', async ({ page, homePage }) => {
|
||||
test('Can constrain line length', async ({ page, homePage, cmdBar }) => {
|
||||
await page.addInitScript(async () => {
|
||||
localStorage.setItem(
|
||||
'persistCode',
|
||||
@ -50,11 +50,7 @@ test.describe('Testing constraints', () => {
|
||||
await page.waitForTimeout(100)
|
||||
await page.getByTestId('constraint-length').click()
|
||||
await page.getByTestId('cmd-bar-arg-value').getByRole('textbox').fill('20')
|
||||
await page
|
||||
.getByRole('button', {
|
||||
name: 'arrow right Continue',
|
||||
})
|
||||
.click()
|
||||
await cmdBar.continue()
|
||||
|
||||
await expect(page.locator('.cm-content')).toHaveText(
|
||||
`length001 = 20sketch001 = startSketchOn(XY) |> startProfile(at = [-10, -10]) |> line(end = [20, 0]) |> angledLine(angle = 90, length = length001) |> xLine(length = -20)`
|
||||
@ -681,9 +677,6 @@ test.describe('Testing constraints', () => {
|
||||
.getByRole('textbox')
|
||||
const cmdBarKclVariableNameInput =
|
||||
page.getByPlaceholder('Variable name')
|
||||
const cmdBarSubmitButton = page.getByRole('button', {
|
||||
name: 'arrow right Continue',
|
||||
})
|
||||
|
||||
await page.addInitScript(async () => {
|
||||
localStorage.setItem(
|
||||
@ -736,7 +729,7 @@ part002 = startSketchOn(XZ)
|
||||
await page.waitForTimeout(500)
|
||||
const [ang, len] = value.split(', ')
|
||||
const changedCode = `|> angledLine(angle = ${ang}, length = ${len})`
|
||||
await cmdBarSubmitButton.click()
|
||||
await cmdBar.continue()
|
||||
await expect(page.locator('.cm-content')).toContainText(changedCode)
|
||||
|
||||
// checking active assures the cursor is where it should be
|
||||
@ -1101,11 +1094,7 @@ part002 = startSketchOn(XZ)
|
||||
await page.waitForTimeout(500)
|
||||
|
||||
await page.getByTestId('cmd-bar-arg-value').getByRole('textbox').fill('10')
|
||||
await page
|
||||
.getByRole('button', {
|
||||
name: 'arrow right Continue',
|
||||
})
|
||||
.click()
|
||||
await cmdBar.continue()
|
||||
|
||||
await pollEditorLinesSelectedLength(page, 1)
|
||||
activeLinesContent = await page.locator('.cm-activeLine').all()
|
||||
|
@ -21,7 +21,7 @@ test.describe('Testing loading external models', () => {
|
||||
// We have no more web tests
|
||||
test.fail(
|
||||
'Web: should overwrite current code, cannot create new file',
|
||||
async ({ editor, context, page, homePage }) => {
|
||||
async ({ editor, context, page, homePage, cmdBar }) => {
|
||||
const u = await getUtils(page)
|
||||
await test.step(`Test setup`, async () => {
|
||||
await context.addInitScript((code) => {
|
||||
@ -52,9 +52,6 @@ test.describe('Testing loading external models', () => {
|
||||
name,
|
||||
})
|
||||
const warningText = page.getByText('Overwrite current file with sample?')
|
||||
const confirmButton = page.getByRole('button', {
|
||||
name: 'Submit command',
|
||||
})
|
||||
|
||||
await test.step(`Precondition: check the initial code`, async () => {
|
||||
await u.openKclCodePanel()
|
||||
@ -70,7 +67,7 @@ test.describe('Testing loading external models', () => {
|
||||
await expect(commandMethodOption('Create new file')).not.toBeVisible()
|
||||
await commandMethodOption('Overwrite').click()
|
||||
await expect(warningText).toBeVisible()
|
||||
await confirmButton.click()
|
||||
await cmdBar.submit()
|
||||
|
||||
await editor.expectEditor.toContain('// ' + newSample.title)
|
||||
})
|
||||
|
@ -3,6 +3,7 @@ import type { LineInputsType } from '@src/lang/std/sketchcombos'
|
||||
import { uuidv4 } from '@src/lib/utils'
|
||||
|
||||
import type { EditorFixture } from '@e2e/playwright/fixtures/editorFixture'
|
||||
import type { CmdBarFixture } from '@e2e/playwright/fixtures/cmdBarFixture'
|
||||
import { deg, getUtils, wiggleMove } from '@e2e/playwright/test-utils'
|
||||
import { expect, test } from '@e2e/playwright/zoo-test'
|
||||
|
||||
@ -18,7 +19,7 @@ test.describe('Testing segment overlays', () => {
|
||||
* @param {number} options.steps - The number of steps to perform
|
||||
*/
|
||||
const _clickConstrained =
|
||||
(page: Page, editor: EditorFixture) =>
|
||||
(page: Page, editor: EditorFixture, cmdBar: CmdBarFixture) =>
|
||||
async ({
|
||||
hoverPos,
|
||||
constraintType,
|
||||
@ -93,11 +94,7 @@ test.describe('Testing segment overlays', () => {
|
||||
page.getByTestId('cmd-bar-arg-value').getByRole('textbox')
|
||||
).toBeFocused()
|
||||
await page.waitForTimeout(500)
|
||||
await page
|
||||
.getByRole('button', {
|
||||
name: 'arrow right Continue',
|
||||
})
|
||||
.click()
|
||||
await cmdBar.continue()
|
||||
await editor.expectEditor.toContain(expectFinal, {
|
||||
shouldNormalise: true,
|
||||
})
|
||||
@ -113,7 +110,7 @@ test.describe('Testing segment overlays', () => {
|
||||
* @param {number} options.steps - The number of steps to perform
|
||||
*/
|
||||
const _clickUnconstrained =
|
||||
(page: Page, editor: EditorFixture) =>
|
||||
(page: Page, editor: EditorFixture, cmdBar: CmdBarFixture) =>
|
||||
async ({
|
||||
hoverPos,
|
||||
constraintType,
|
||||
@ -163,11 +160,7 @@ test.describe('Testing segment overlays', () => {
|
||||
page.getByTestId('cmd-bar-arg-value').getByRole('textbox')
|
||||
).toBeFocused()
|
||||
await page.waitForTimeout(500)
|
||||
await page
|
||||
.getByRole('button', {
|
||||
name: 'arrow right Continue',
|
||||
})
|
||||
.click()
|
||||
await cmdBar.continue()
|
||||
await editor.expectEditor.toContain(expectAfterUnconstrained, {
|
||||
shouldNormalise: true,
|
||||
})
|
||||
@ -239,8 +232,8 @@ test.describe('Testing segment overlays', () => {
|
||||
|
||||
await expect(page.getByTestId('segment-overlay')).toHaveCount(14)
|
||||
|
||||
const clickUnconstrained = _clickUnconstrained(page, editor)
|
||||
const clickConstrained = _clickConstrained(page, editor)
|
||||
const clickUnconstrained = _clickUnconstrained(page, editor, cmdBar)
|
||||
const clickConstrained = _clickConstrained(page, editor, cmdBar)
|
||||
|
||||
await u.openAndClearDebugPanel()
|
||||
await u.sendCustomCmd({
|
||||
@ -664,7 +657,7 @@ profile002 = circle(sketch001, center = [345, 0], radius = 238.38)
|
||||
await expect(
|
||||
page.getByTestId('cmd-bar-arg-value').getByRole('textbox')
|
||||
).toBeFocused()
|
||||
await page.getByRole('button', { name: 'arrow right Continue' }).click()
|
||||
await cmdBar.continue()
|
||||
|
||||
// Verify the X constraint was added
|
||||
await editor.expectEditor.toContain('center = [xAbs001, 0]', {
|
||||
@ -682,7 +675,7 @@ profile002 = circle(sketch001, center = [345, 0], radius = 238.38)
|
||||
await expect(
|
||||
page.getByTestId('cmd-bar-arg-value').getByRole('textbox')
|
||||
).toBeFocused()
|
||||
await page.getByRole('button', { name: 'arrow right Continue' }).click()
|
||||
await cmdBar.continue()
|
||||
|
||||
// Verify the Y constraint was added
|
||||
await editor.expectEditor.toContain('center = [xAbs001, yAbs001]', {
|
||||
@ -700,7 +693,7 @@ profile002 = circle(sketch001, center = [345, 0], radius = 238.38)
|
||||
await expect(
|
||||
page.getByTestId('cmd-bar-arg-value').getByRole('textbox')
|
||||
).toBeFocused()
|
||||
await page.getByRole('button', { name: 'arrow right Continue' }).click()
|
||||
await cmdBar.continue()
|
||||
|
||||
// Verify all constraints were added
|
||||
await editor.expectEditor.toContain(
|
||||
@ -887,7 +880,7 @@ profile003 = startProfile(sketch001, at = [64.39, 35.16])
|
||||
await expect(
|
||||
page.getByTestId('cmd-bar-arg-value').getByRole('textbox')
|
||||
).toBeFocused()
|
||||
await page.getByRole('button', { name: 'arrow right Continue' }).click()
|
||||
await cmdBar.continue()
|
||||
|
||||
// Verify the constraint was added
|
||||
await editor.expectEditor.toContain(
|
||||
@ -910,7 +903,7 @@ profile003 = startProfile(sketch001, at = [64.39, 35.16])
|
||||
await expect(
|
||||
page.getByTestId('cmd-bar-arg-value').getByRole('textbox')
|
||||
).toBeFocused()
|
||||
await page.getByRole('button', { name: 'arrow right Continue' }).click()
|
||||
await cmdBar.continue()
|
||||
|
||||
// Verify both constraints were added
|
||||
await editor.expectEditor.toContain(
|
||||
@ -935,7 +928,7 @@ profile003 = startProfile(sketch001, at = [64.39, 35.16])
|
||||
await expect(
|
||||
page.getByTestId('cmd-bar-arg-value').getByRole('textbox')
|
||||
).toBeFocused()
|
||||
await page.getByRole('button', { name: 'arrow right Continue' }).click()
|
||||
await cmdBar.continue()
|
||||
|
||||
// Verify the constraint was added
|
||||
await editor.expectEditor.toContain('endAbsolute = [xAbs002, 84.07]', {
|
||||
@ -955,7 +948,7 @@ profile003 = startProfile(sketch001, at = [64.39, 35.16])
|
||||
await expect(
|
||||
page.getByTestId('cmd-bar-arg-value').getByRole('textbox')
|
||||
).toBeFocused()
|
||||
await page.getByRole('button', { name: 'arrow right Continue' }).click()
|
||||
await cmdBar.continue()
|
||||
|
||||
// Verify all constraints were added
|
||||
await editor.expectEditor.toContain(
|
||||
|
@ -32,7 +32,7 @@ test('Units menu', async ({ page, homePage }) => {
|
||||
test(
|
||||
'Successful export shows a success toast',
|
||||
{ tag: '@skipLocalEngine' },
|
||||
async ({ page, homePage, tronApp }) => {
|
||||
async ({ page, homePage, cmdBar, tronApp }) => {
|
||||
// FYI this test doesn't work with only engine running locally
|
||||
// And you will need to have the KittyCAD CLI installed
|
||||
const u = await getUtils(page)
|
||||
@ -94,7 +94,8 @@ part001 = startSketchOn(-XZ)
|
||||
presentation: 'pretty',
|
||||
},
|
||||
tronApp?.projectDirName,
|
||||
page
|
||||
page,
|
||||
cmdBar
|
||||
)
|
||||
}
|
||||
)
|
||||
@ -254,6 +255,7 @@ test('First escape in tool pops you out of tool, second exits sketch mode', asyn
|
||||
test('Basic default modeling and sketch hotkeys work', async ({
|
||||
page,
|
||||
homePage,
|
||||
cmdBar,
|
||||
}) => {
|
||||
const u = await getUtils(page)
|
||||
await test.step(`Set up test`, async () => {
|
||||
@ -397,11 +399,8 @@ test('Basic default modeling and sketch hotkeys work', async ({
|
||||
await expect(page.getByRole('button', { name: 'Continue' })).toBeVisible({
|
||||
timeout: 20_000,
|
||||
})
|
||||
await page.getByRole('button', { name: 'Continue' }).click()
|
||||
await expect(
|
||||
page.getByRole('button', { name: 'Submit command' })
|
||||
).toBeVisible()
|
||||
await page.getByRole('button', { name: 'Submit command' }).click()
|
||||
await cmdBar.continue()
|
||||
await cmdBar.submit()
|
||||
await expect(page.locator('.cm-content')).toContainText('extrude(')
|
||||
})
|
||||
|
||||
@ -575,8 +574,7 @@ profile001 = startProfile(sketch002, at = [-12.34, 12.34])
|
||||
|
||||
await cmdBar.progressCmdBar()
|
||||
await cmdBar.progressCmdBar()
|
||||
await expect(page.getByText('Confirm Extrude')).toBeVisible()
|
||||
await cmdBar.progressCmdBar()
|
||||
await cmdBar.submit()
|
||||
|
||||
const result2 = result.genNext`
|
||||
const sketch002 = extrude(sketch002, length = ${[5, 5]} + 7)`
|
||||
|
@ -21,7 +21,7 @@ export const CommandBar = () => {
|
||||
const commandBarState = useCommandBarState()
|
||||
const { immediateState } = useNetworkContext()
|
||||
const {
|
||||
context: { selectedCommand, currentArgument, commands },
|
||||
context: { selectedCommand, currentArgument, commands, argumentsToSubmit },
|
||||
} = commandBarState
|
||||
const isArgumentThatShouldBeHardToDismiss =
|
||||
currentArgument?.inputType === 'selection' ||
|
||||
@ -68,16 +68,23 @@ export const CommandBar = () => {
|
||||
})
|
||||
|
||||
function stepBack() {
|
||||
if (!currentArgument) {
|
||||
if (commandBarState.matches('Review')) {
|
||||
const entries = Object.entries(selectedCommand?.args || {}).filter(
|
||||
([_, argConfig]) =>
|
||||
!argConfig.hidden &&
|
||||
(typeof argConfig.required === 'function'
|
||||
? argConfig.required(commandBarState.context)
|
||||
: argConfig.required)
|
||||
([argName, arg]) => {
|
||||
const argValue =
|
||||
(typeof argumentsToSubmit[argName] === 'function'
|
||||
? argumentsToSubmit[argName](commandBarState.context)
|
||||
: argumentsToSubmit[argName]) || ''
|
||||
const isRequired =
|
||||
typeof arg.required === 'function'
|
||||
? arg.required(commandBarState.context)
|
||||
: arg.required
|
||||
|
||||
return !arg.hidden && (argValue || isRequired)
|
||||
}
|
||||
)
|
||||
|
||||
if (!currentArgument) {
|
||||
if (commandBarState.matches('Review')) {
|
||||
const currentArgName = entries[entries.length - 1][0]
|
||||
const currentArg = {
|
||||
name: currentArgName,
|
||||
@ -94,9 +101,6 @@ export const CommandBar = () => {
|
||||
commandBarActor.send({ type: 'Deselect command' })
|
||||
}
|
||||
} else {
|
||||
const entries = Object.entries(selectedCommand?.args || {}).filter(
|
||||
(a) => !a[1].hidden
|
||||
)
|
||||
const index = entries.findIndex(
|
||||
([key, _]) => key === currentArgument.name
|
||||
)
|
||||
@ -183,20 +187,6 @@ export const CommandBar = () => {
|
||||
<kbd className="hotkey ml-4 dark:!bg-chalkboard-80">esc</kbd>
|
||||
</Tooltip>
|
||||
</button>
|
||||
{!commandBarState.matches('Selecting command') && (
|
||||
<button onClick={stepBack} className="m-0 p-0 border-none">
|
||||
<CustomIcon name="arrowLeft" className="w-5 h-5 rounded-sm" />
|
||||
<Tooltip position="bottom">
|
||||
Step back{' '}
|
||||
<kbd className="hotkey ml-4 dark:!bg-chalkboard-80">
|
||||
Shift
|
||||
</kbd>
|
||||
<kbd className="hotkey ml-4 dark:!bg-chalkboard-80">
|
||||
Bksp
|
||||
</kbd>
|
||||
</Tooltip>
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</WrapperComponent.Panel>
|
||||
</Transition.Child>
|
||||
|
@ -1,11 +1,12 @@
|
||||
import CommandArgOptionInput from '@src/components/CommandBar/CommandArgOptionInput'
|
||||
import CommandBarBasicInput from '@src/components/CommandBar/CommandBarBasicInput'
|
||||
import CommandBarHeader from '@src/components/CommandBar/CommandBarHeader'
|
||||
import CommandBarHeaderFooter from '@src/components/CommandBar/CommandBarHeaderFooter'
|
||||
import CommandBarKclInput from '@src/components/CommandBar/CommandBarKclInput'
|
||||
import CommandBarPathInput from '@src/components/CommandBar/CommandBarPathInput'
|
||||
import CommandBarSelectionInput from '@src/components/CommandBar/CommandBarSelectionInput'
|
||||
import CommandBarSelectionMixedInput from '@src/components/CommandBar/CommandBarSelectionMixedInput'
|
||||
import CommandBarTextareaInput from '@src/components/CommandBar/CommandBarTextareaInput'
|
||||
import CommandBarDivider from '@src/components/CommandBar/CommandBarDivider'
|
||||
import type { CommandArgument } from '@src/lib/commandTypes'
|
||||
import { commandBarActor, useCommandBarState } from '@src/lib/singletons'
|
||||
|
||||
@ -28,13 +29,14 @@ function CommandBarArgument({ stepBack }: { stepBack: () => void }) {
|
||||
|
||||
return (
|
||||
currentArgument && (
|
||||
<CommandBarHeader>
|
||||
<CommandBarHeaderFooter stepBack={stepBack}>
|
||||
<ArgumentInput
|
||||
arg={currentArgument}
|
||||
stepBack={stepBack}
|
||||
onSubmit={onSubmit}
|
||||
/>
|
||||
</CommandBarHeader>
|
||||
<CommandBarDivider />
|
||||
</CommandBarHeaderFooter>
|
||||
)
|
||||
)
|
||||
}
|
||||
|
5
src/components/CommandBar/CommandBarDivider.tsx
Normal file
5
src/components/CommandBar/CommandBarDivider.tsx
Normal file
@ -0,0 +1,5 @@
|
||||
export default function CommandBarDivider() {
|
||||
return (
|
||||
<div className="block w-full my-2 h-[1px] bg-chalkboard-20 dark:bg-chalkboard-80" />
|
||||
)
|
||||
}
|
@ -5,6 +5,7 @@ import { useHotkeys } from 'react-hotkeys-hook'
|
||||
import { ActionButton } from '@src/components/ActionButton'
|
||||
import { CustomIcon } from '@src/components/CustomIcon'
|
||||
import Tooltip from '@src/components/Tooltip'
|
||||
import CommandBarDivider from '@src/components/CommandBar/CommandBarDivider'
|
||||
import type {
|
||||
KclCommandValue,
|
||||
KclExpressionWithVariable,
|
||||
@ -14,7 +15,10 @@ import { getSelectionTypeDisplayText } from '@src/lib/selections'
|
||||
import { roundOff } from '@src/lib/utils'
|
||||
import { commandBarActor, useCommandBarState } from '@src/lib/singletons'
|
||||
|
||||
function CommandBarHeader({ children }: React.PropsWithChildren<object>) {
|
||||
function CommandBarHeaderFooter({
|
||||
children,
|
||||
stepBack,
|
||||
}: React.PropsWithChildren<object> & { stepBack: () => void }) {
|
||||
const commandBarState = useCommandBarState()
|
||||
const {
|
||||
context: { selectedCommand, currentArgument, argumentsToSubmit },
|
||||
@ -102,19 +106,23 @@ function CommandBarHeader({ children }: React.PropsWithChildren<object>) {
|
||||
<span className="pr-2" />
|
||||
)}
|
||||
</p>
|
||||
{Object.entries(nonHiddenArgs || {})
|
||||
.filter(
|
||||
([_, argConfig]) =>
|
||||
argConfig.skip === false ||
|
||||
(typeof argConfig.required === 'function'
|
||||
? argConfig.required(commandBarState.context)
|
||||
: argConfig.required)
|
||||
)
|
||||
.map(([argName, arg], i) => {
|
||||
{Object.entries(nonHiddenArgs || {}).flatMap(
|
||||
([argName, arg], i) => {
|
||||
const argValue =
|
||||
(typeof argumentsToSubmit[argName] === 'function'
|
||||
? argumentsToSubmit[argName](commandBarState.context)
|
||||
: argumentsToSubmit[argName]) || ''
|
||||
const isCurrentArg = argName === currentArgument?.name
|
||||
const isSkipFalse = arg.skip === false
|
||||
const isRequired =
|
||||
typeof arg.required === 'function'
|
||||
? arg.required(commandBarState.context)
|
||||
: arg.required
|
||||
|
||||
// We actually want to show non-hidden optional args that have a value set already
|
||||
if (!(argValue || isCurrentArg || isSkipFalse || isRequired)) {
|
||||
return []
|
||||
}
|
||||
|
||||
return (
|
||||
<button
|
||||
@ -161,7 +169,9 @@ function CommandBarHeader({ children }: React.PropsWithChildren<object>) {
|
||||
),
|
||||
4
|
||||
)
|
||||
) : arg.inputType === 'text' && !arg.valueSummary ? (
|
||||
) : arg.inputType === 'text' &&
|
||||
!arg.valueSummary &&
|
||||
typeof argValue === 'string' ? (
|
||||
`${argValue.slice(0, 12)}${argValue.length > 12 ? '...' : ''}`
|
||||
) : typeof argValue === 'object' ? (
|
||||
arg.valueSummary ? (
|
||||
@ -207,8 +217,14 @@ function CommandBarHeader({ children }: React.PropsWithChildren<object>) {
|
||||
)}
|
||||
</button>
|
||||
)
|
||||
})}
|
||||
}
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<CommandBarDivider />
|
||||
{children}
|
||||
<div className="px-4 pb-2 flex justify-between items-center gap-2">
|
||||
<StepBackButton stepBack={stepBack} />
|
||||
{isReviewing ? (
|
||||
<ReviewingButton
|
||||
bgClassName={
|
||||
@ -237,8 +253,6 @@ function CommandBarHeader({ children }: React.PropsWithChildren<object>) {
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
<div className="block w-full my-2 h-[1px] bg-chalkboard-20 dark:bg-chalkboard-80" />
|
||||
{children}
|
||||
</>
|
||||
)
|
||||
)
|
||||
@ -258,16 +272,16 @@ function ReviewingButton({ bgClassName, iconClassName }: ButtonProps) {
|
||||
ref={buttonRef}
|
||||
type="submit"
|
||||
form="review-form"
|
||||
className="w-fit !p-0 rounded-sm hover:shadow focus:outline-current"
|
||||
className={`w-fit !p-0 rounded-sm hover:brightness-110 hover:shadow focus:outline-current ${bgClassName}`}
|
||||
tabIndex={0}
|
||||
data-testid="command-bar-submit"
|
||||
iconStart={{
|
||||
iconEnd={{
|
||||
icon: 'checkmark',
|
||||
bgClassName: `p-1 rounded-sm hover:brightness-110 ${bgClassName}`,
|
||||
bgClassName: `p-1 rounded-sm ${bgClassName}`,
|
||||
iconClassName: `${iconClassName}`,
|
||||
}}
|
||||
>
|
||||
<span className="sr-only">Submit command</span>
|
||||
<span className={`pl-2 ${iconClassName}`}>Submit</span>
|
||||
</ActionButton>
|
||||
)
|
||||
}
|
||||
@ -278,18 +292,48 @@ function GatheringArgsButton({ bgClassName, iconClassName }: ButtonProps) {
|
||||
Element="button"
|
||||
type="submit"
|
||||
form="arg-form"
|
||||
className="w-fit !p-0 rounded-sm hover:shadow focus:outline-current"
|
||||
className={`w-fit !p-0 rounded-sm hover:brightness-110 hover:shadow focus:outline-current ${bgClassName}`}
|
||||
tabIndex={0}
|
||||
data-testid="command-bar-continue"
|
||||
iconStart={{
|
||||
iconEnd={{
|
||||
icon: 'arrowRight',
|
||||
bgClassName: `p-1 rounded-sm hover:brightness-110 ${bgClassName}`,
|
||||
bgClassName: `p-1 rounded-sm ${bgClassName}`,
|
||||
iconClassName: `${iconClassName}`,
|
||||
}}
|
||||
>
|
||||
<span className="sr-only">Continue</span>
|
||||
<span className={`pl-2 ${iconClassName}`}>Continue</span>
|
||||
</ActionButton>
|
||||
)
|
||||
}
|
||||
|
||||
export default CommandBarHeader
|
||||
function StepBackButton({
|
||||
bgClassName,
|
||||
iconClassName,
|
||||
stepBack,
|
||||
}: ButtonProps & { stepBack: () => void }) {
|
||||
return (
|
||||
<ActionButton
|
||||
Element="button"
|
||||
type="button"
|
||||
form="arg-form"
|
||||
className={`w-fit !p-0 rounded-sm hover:brightness-110 hover:shadow focus:outline-current bg-chalkboard-20/50 dark:bg-chalkboard-80/50 border-chalkboard-20 dark:border-chalkboard-80 ${bgClassName}`}
|
||||
tabIndex={0}
|
||||
data-testid="command-bar-step-back"
|
||||
iconStart={{
|
||||
icon: 'arrowLeft',
|
||||
bgClassName: `p-1 rounded-sm bg-chalkboard-20/50 dark:bg-chalkboard-80/50 ${bgClassName}`,
|
||||
iconClassName: `${iconClassName}`,
|
||||
}}
|
||||
onClick={stepBack}
|
||||
>
|
||||
<span className={`pr-2 ${iconClassName}`}>Step back</span>
|
||||
<Tooltip position="bottom">
|
||||
Step back
|
||||
<kbd className="hotkey ml-4 dark:!bg-chalkboard-80">Shift</kbd>
|
||||
<kbd className="hotkey ml-2 dark:!bg-chalkboard-80">Bksp</kbd>
|
||||
</Tooltip>
|
||||
</ActionButton>
|
||||
)
|
||||
}
|
||||
|
||||
export default CommandBarHeaderFooter
|
@ -1,7 +1,10 @@
|
||||
import { useHotkeys } from 'react-hotkeys-hook'
|
||||
|
||||
import CommandBarHeader from '@src/components/CommandBar/CommandBarHeader'
|
||||
import CommandBarHeaderFooter from '@src/components/CommandBar/CommandBarHeaderFooter'
|
||||
import CommandBarDivider from '@src/components/CommandBar/CommandBarDivider'
|
||||
import { commandBarActor, useCommandBarState } from '@src/lib/singletons'
|
||||
import { useMemo } from 'react'
|
||||
import { CustomIcon } from '@src/components/CustomIcon'
|
||||
|
||||
function CommandBarReview({ stepBack }: { stepBack: () => void }) {
|
||||
const commandBarState = useCommandBarState()
|
||||
@ -57,19 +60,71 @@ function CommandBarReview({ stepBack }: { stepBack: () => void }) {
|
||||
})
|
||||
}
|
||||
|
||||
const availableOptionalArgs = useMemo(() => {
|
||||
if (!selectedCommand?.args) return undefined
|
||||
const s = { ...selectedCommand.args }
|
||||
for (const [name, arg] of Object.entries(s)) {
|
||||
const value =
|
||||
(typeof argumentsToSubmit[name] === 'function'
|
||||
? argumentsToSubmit[name](commandBarState.context)
|
||||
: argumentsToSubmit[name]) || ''
|
||||
const isHidden =
|
||||
typeof arg.hidden === 'function'
|
||||
? arg.hidden(commandBarState.context)
|
||||
: arg.hidden
|
||||
const isRequired =
|
||||
typeof arg.required === 'function'
|
||||
? arg.required(commandBarState.context)
|
||||
: arg.required
|
||||
if (isHidden || isRequired || value) {
|
||||
delete s[name]
|
||||
}
|
||||
}
|
||||
return s
|
||||
}, [selectedCommand, argumentsToSubmit, commandBarState.context])
|
||||
return (
|
||||
<CommandBarHeader>
|
||||
<p className="px-4 pb-2">
|
||||
{selectedCommand?.reviewMessage ? (
|
||||
selectedCommand.reviewMessage instanceof Function ? (
|
||||
selectedCommand.reviewMessage(commandBarState.context)
|
||||
) : (
|
||||
selectedCommand.reviewMessage
|
||||
)
|
||||
) : (
|
||||
<>Confirm {selectedCommand?.displayName || selectedCommand?.name}</>
|
||||
)}
|
||||
<CommandBarHeaderFooter stepBack={stepBack}>
|
||||
{selectedCommand?.reviewMessage && (
|
||||
<>
|
||||
<p className="px-4 py-2">
|
||||
{selectedCommand.reviewMessage instanceof Function
|
||||
? selectedCommand.reviewMessage(commandBarState.context)
|
||||
: selectedCommand.reviewMessage}
|
||||
</p>
|
||||
<CommandBarDivider />
|
||||
</>
|
||||
)}
|
||||
{Object.entries(availableOptionalArgs || {}).length > 0 && (
|
||||
<>
|
||||
<div className="px-4 flex flex-wrap gap-2 items-baseline">
|
||||
<span className="text-sm mr-4">Optional</span>
|
||||
{Object.entries(availableOptionalArgs || {}).map(
|
||||
([argName, arg]) => {
|
||||
return (
|
||||
<button
|
||||
data-testid="cmd-bar-add-optional-arg"
|
||||
type="button"
|
||||
onClick={() => {
|
||||
commandBarActor.send({
|
||||
type: 'Edit argument',
|
||||
data: { arg: { ...arg, name: argName } },
|
||||
})
|
||||
}}
|
||||
key={argName}
|
||||
className="w-fit px-2 py-1 m-0 rounded-sm flex gap-2 items-center border"
|
||||
>
|
||||
<span className="capitalize">
|
||||
{arg.displayName || argName}
|
||||
</span>
|
||||
<CustomIcon name="plus" className="w-4 h-4" />
|
||||
</button>
|
||||
)
|
||||
}
|
||||
)}
|
||||
</div>
|
||||
<CommandBarDivider />
|
||||
</>
|
||||
)}
|
||||
<form
|
||||
id="review-form"
|
||||
className="absolute opacity-0 inset-0 pointer-events-none"
|
||||
@ -97,7 +152,7 @@ function CommandBarReview({ stepBack }: { stepBack: () => void }) {
|
||||
)
|
||||
})}
|
||||
</form>
|
||||
</CommandBarHeader>
|
||||
</CommandBarHeaderFooter>
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -275,6 +275,10 @@ export const modelingMachineCommandConfig: StateMachineCommandSetConfig<
|
||||
['gltf', 'stl', 'ply'].includes(
|
||||
commandContext.argumentsToSubmit.type as string
|
||||
),
|
||||
hidden: (commandContext) =>
|
||||
!['gltf', 'stl', 'ply'].includes(
|
||||
commandContext.argumentsToSubmit.type as string
|
||||
),
|
||||
options: (commandContext) => {
|
||||
const type = commandContext.argumentsToSubmit.type as
|
||||
| OutputTypeKey
|
||||
@ -428,9 +432,7 @@ export const modelingMachineCommandConfig: StateMachineCommandSetConfig<
|
||||
sectional: {
|
||||
inputType: 'options',
|
||||
skip: true,
|
||||
defaultValue: false,
|
||||
hidden: false,
|
||||
required: true,
|
||||
required: false,
|
||||
options: [
|
||||
{ name: 'False', value: false },
|
||||
{ name: 'True', value: true },
|
||||
@ -464,6 +466,7 @@ export const modelingMachineCommandConfig: StateMachineCommandSetConfig<
|
||||
skip: true,
|
||||
inputType: 'text',
|
||||
required: false,
|
||||
hidden: true,
|
||||
},
|
||||
sketches: {
|
||||
inputType: 'selection',
|
||||
@ -484,27 +487,27 @@ export const modelingMachineCommandConfig: StateMachineCommandSetConfig<
|
||||
hidden: (context) => Boolean(context.argumentsToSubmit.nodeToEdit),
|
||||
},
|
||||
axis: {
|
||||
required: (commandContext) =>
|
||||
['Axis'].includes(
|
||||
commandContext.argumentsToSubmit.axisOrEdge as string
|
||||
),
|
||||
required: (context) =>
|
||||
['Axis'].includes(context.argumentsToSubmit.axisOrEdge as string),
|
||||
inputType: 'options',
|
||||
displayName: 'Sketch Axis',
|
||||
options: [
|
||||
{ name: 'X Axis', isCurrent: true, value: 'X' },
|
||||
{ name: 'Y Axis', isCurrent: false, value: 'Y' },
|
||||
],
|
||||
hidden: (context) => Boolean(context.argumentsToSubmit.nodeToEdit),
|
||||
hidden: (context) =>
|
||||
Boolean(context.argumentsToSubmit.nodeToEdit) ||
|
||||
!['Axis'].includes(context.argumentsToSubmit.axisOrEdge as string),
|
||||
},
|
||||
edge: {
|
||||
required: (commandContext) =>
|
||||
['Edge'].includes(
|
||||
commandContext.argumentsToSubmit.axisOrEdge as string
|
||||
),
|
||||
required: (context) =>
|
||||
['Edge'].includes(context.argumentsToSubmit.axisOrEdge as string),
|
||||
inputType: 'selection',
|
||||
selectionTypes: ['segment', 'sweepEdge', 'edgeCutEdge'],
|
||||
multiple: false,
|
||||
hidden: (context) => Boolean(context.argumentsToSubmit.nodeToEdit),
|
||||
hidden: (context) =>
|
||||
Boolean(context.argumentsToSubmit.nodeToEdit) ||
|
||||
!['Edge'].includes(context.argumentsToSubmit.axisOrEdge as string),
|
||||
},
|
||||
angle: {
|
||||
inputType: 'kcl',
|
||||
@ -524,6 +527,7 @@ export const modelingMachineCommandConfig: StateMachineCommandSetConfig<
|
||||
skip: true,
|
||||
inputType: 'text',
|
||||
required: false,
|
||||
hidden: true,
|
||||
},
|
||||
selection: {
|
||||
inputType: 'selection',
|
||||
|
Reference in New Issue
Block a user