diff --git a/e2e/playwright/point-click-assemblies.spec.ts b/e2e/playwright/point-click-assemblies.spec.ts index b579518b5..88da75ada 100644 --- a/e2e/playwright/point-click-assemblies.spec.ts +++ b/e2e/playwright/point-click-assemblies.spec.ts @@ -143,28 +143,45 @@ test.describe('Point-and-click assemblies tests', () => { await scene.settled(cmdBar) }) - await test.step('Insert a second time and expect error', async () => { - // TODO: revisit once we have clone with #6209 - await insertPartIntoAssembly( - 'bracket.kcl', - 'bracket', - toolbar, - cmdBar, - page - ) + await test.step('Insert a second time with the same name and expect error', async () => { + await toolbar.insertButton.click() + await cmdBar.selectOption({ name: 'bracket.kcl' }).click() + await cmdBar.expectState({ + stage: 'arguments', + currentArgKey: 'localName', + currentArgValue: '', + headerArguments: { Path: 'bracket.kcl', LocalName: '' }, + highlightedHeaderArg: 'localName', + commandName: 'Insert', + }) + await page.keyboard.insertText('bracket') + await cmdBar.progressCmdBar() + await expect( + page.getByText('This variable name is already in use') + ).toBeVisible() + }) + + await test.step('Insert a second time with a different name and expect error', async () => { + await page.keyboard.insertText('2') + await cmdBar.progressCmdBar() + await cmdBar.expectState({ + stage: 'review', + headerArguments: { Path: 'bracket.kcl', LocalName: 'bracket2' }, + commandName: 'Insert', + }) + await cmdBar.progressCmdBar() await editor.expectEditor.toContain( ` import "cylinder.kcl" as cylinder import "bracket.kcl" as bracket - import "bracket.kcl" as bracket + import "bracket.kcl" as bracket2 cylinder bracket - bracket + bracket2 `, { shouldNormalise: true } ) - await scene.settled(cmdBar) - await expect(page.locator('.cm-lint-marker-error')).toBeVisible() + // TODO: update once we have clone() with #6209 }) } ) diff --git a/src/lib/commandTypes.ts b/src/lib/commandTypes.ts index e895dde18..b726a0cc9 100644 --- a/src/lib/commandTypes.ts +++ b/src/lib/commandTypes.ts @@ -220,6 +220,13 @@ export type CommandArgumentConfig< machineContext?: C ) => OutputType) defaultValueFromContext?: (context: C) => OutputType + validation?: ({ + data, + context, + }: { + data: any + context: CommandBarContext + }) => Promise } | { inputType: 'text' @@ -343,6 +350,13 @@ export type CommandArgument< commandBarContext: ContextFrom, machineContext?: ContextFrom ) => OutputType) + validation?: ({ + data, + context, + }: { + data: any + context: CommandBarContext + }) => Promise } | { inputType: 'path' diff --git a/src/lib/createMachineCommand.ts b/src/lib/createMachineCommand.ts index 4a8504940..969135840 100644 --- a/src/lib/createMachineCommand.ts +++ b/src/lib/createMachineCommand.ts @@ -211,6 +211,15 @@ export function buildCommandArgument< defaultValue: arg.defaultValue, ...baseCommandArgument, } satisfies CommandArgument & { inputType: 'kcl' } + } else if (arg.inputType === 'string') { + return { + inputType: arg.inputType, + defaultValue: arg.defaultValueFromContext + ? arg.defaultValueFromContext(context) + : arg.defaultValue, + validation: arg.validation, + ...baseCommandArgument, + } satisfies CommandArgument & { inputType: 'string' } } else { return { inputType: arg.inputType, diff --git a/src/lib/kclCommands.ts b/src/lib/kclCommands.ts index 004c36913..151310b46 100644 --- a/src/lib/kclCommands.ts +++ b/src/lib/kclCommands.ts @@ -133,6 +133,14 @@ export function kclCommands(commandProps: KclCommandConfig): Command[] { const path = context.argumentsToSubmit['path'] as string return getPathFilenameInVariableCase(path) }, + validation: async ({ data, context }) => { + const variableExists = kclManager.variables[data.localName] + if (variableExists) { + return 'This variable name is already in use.' + } + + return true + }, }, }, onSubmit: (data) => { diff --git a/src/machines/commandBarMachine.ts b/src/machines/commandBarMachine.ts index fb45c2f81..6149c7d55 100644 --- a/src/machines/commandBarMachine.ts +++ b/src/machines/commandBarMachine.ts @@ -307,6 +307,7 @@ export const commandBarMachine = setup({ context.currentArgument && context.selectedCommand && (argConfig?.inputType === 'selection' || + argConfig?.inputType === 'string' || argConfig?.inputType === 'selectionMixed') && argConfig?.validation ) {