Add sketch tools back to the command bar (#3008)
* Make machine command type names more explicit * Prepare "change tool" event for command bar * Make it so that state machine events can each map to multiple command configs * Make commands with all skippable args possible * Add back the tools to the command bar * A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu) * Update to use new `groupId` property name * A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu) * Oops didn't save this other instance of `ownerMachine` * Add a playwright test --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Before Width: | Height: | Size: 249 KiB After Width: | Height: | Size: 249 KiB |
Before Width: | Height: | Size: 249 KiB After Width: | Height: | Size: 249 KiB |
Before Width: | Height: | Size: 249 KiB After Width: | Height: | Size: 249 KiB |
Before Width: | Height: | Size: 171 KiB After Width: | Height: | Size: 171 KiB |
Before Width: | Height: | Size: 171 KiB After Width: | Height: | Size: 171 KiB |
Before Width: | Height: | Size: 171 KiB After Width: | Height: | Size: 171 KiB |
Before Width: | Height: | Size: 171 KiB After Width: | Height: | Size: 171 KiB |
Before Width: | Height: | Size: 249 KiB After Width: | Height: | Size: 249 KiB |
Before Width: | Height: | Size: 171 KiB After Width: | Height: | Size: 171 KiB |
Before Width: | Height: | Size: 171 KiB After Width: | Height: | Size: 171 KiB |
@ -3691,6 +3691,46 @@ const extrude001 = extrude(distance001, sketch001)`.replace(
|
||||
) // remove newlines
|
||||
)
|
||||
})
|
||||
|
||||
test('Can switch between sketch tools via command bar', async ({ page }) => {
|
||||
const u = await getUtils(page)
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
await u.waitForAuthSkipAppStart()
|
||||
|
||||
const sketchButton = page.getByRole('button', { name: 'Start Sketch' })
|
||||
const cmdBarButton = page.getByRole('button', { name: 'Commands' })
|
||||
const rectangleToolCommand = page.getByRole('option', {
|
||||
name: 'Rectangle',
|
||||
})
|
||||
const rectangleToolButton = page.getByRole('button', { name: 'Rectangle' })
|
||||
const lineToolCommand = page.getByRole('option', { name: 'Line' })
|
||||
const lineToolButton = page.getByRole('button', { name: 'Line' })
|
||||
const arcToolCommand = page.getByRole('option', { name: 'Tangential Arc' })
|
||||
const arcToolButton = page.getByRole('button', { name: 'Tangential Arc' })
|
||||
|
||||
// Start a sketch
|
||||
await sketchButton.click()
|
||||
await page.mouse.click(700, 200)
|
||||
|
||||
// Switch between sketch tools via the command bar
|
||||
await expect(lineToolButton).toHaveAttribute('aria-pressed', 'true')
|
||||
await cmdBarButton.click()
|
||||
await rectangleToolCommand.click()
|
||||
await expect(rectangleToolButton).toHaveAttribute('aria-pressed', 'true')
|
||||
await cmdBarButton.click()
|
||||
await lineToolCommand.click()
|
||||
await expect(lineToolButton).toHaveAttribute('aria-pressed', 'true')
|
||||
|
||||
// Click in the scene a couple times to draw a line
|
||||
// so tangential arc is valid
|
||||
await page.mouse.click(700, 200)
|
||||
await page.mouse.click(700, 300)
|
||||
|
||||
// switch to tangential arc via command bar
|
||||
await cmdBarButton.click()
|
||||
await arcToolCommand.click()
|
||||
await expect(arcToolButton).toHaveAttribute('aria-pressed', 'true')
|
||||
})
|
||||
})
|
||||
|
||||
test.describe('Regression tests', () => {
|
||||
|
Before Width: | Height: | Size: 71 KiB After Width: | Height: | Size: 71 KiB |
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 44 KiB |
@ -60,7 +60,7 @@ export function Toolbar({
|
||||
? send('CancelSketch')
|
||||
: send({
|
||||
type: 'change tool',
|
||||
data: 'line',
|
||||
data: { tool: 'line' },
|
||||
}),
|
||||
{ enabled: !disableLineButton, scopes: ['sketch'] }
|
||||
)
|
||||
@ -75,7 +75,7 @@ export function Toolbar({
|
||||
? send('CancelSketch')
|
||||
: send({
|
||||
type: 'change tool',
|
||||
data: 'tangentialArc',
|
||||
data: { tool: 'tangentialArc' },
|
||||
}),
|
||||
{ enabled: !disableTangentialArc, scopes: ['sketch'] }
|
||||
)
|
||||
@ -89,7 +89,7 @@ export function Toolbar({
|
||||
? send('CancelSketch')
|
||||
: send({
|
||||
type: 'change tool',
|
||||
data: 'rectangle',
|
||||
data: { tool: 'rectangle' },
|
||||
}),
|
||||
{ enabled: !disableRectangle, scopes: ['sketch'] }
|
||||
)
|
||||
@ -263,7 +263,7 @@ export function Toolbar({
|
||||
? send('CancelSketch')
|
||||
: send({
|
||||
type: 'change tool',
|
||||
data: 'line',
|
||||
data: { tool: 'line' },
|
||||
})
|
||||
}
|
||||
aria-pressed={state?.matches('Sketch.Line tool')}
|
||||
@ -293,7 +293,7 @@ export function Toolbar({
|
||||
? send('CancelSketch')
|
||||
: send({
|
||||
type: 'change tool',
|
||||
data: 'tangentialArc',
|
||||
data: { tool: 'tangentialArc' },
|
||||
})
|
||||
}
|
||||
aria-pressed={state.matches('Sketch.Tangential arc to')}
|
||||
@ -323,7 +323,7 @@ export function Toolbar({
|
||||
? send('CancelSketch')
|
||||
: send({
|
||||
type: 'change tool',
|
||||
data: 'rectangle',
|
||||
data: { tool: 'rectangle' },
|
||||
})
|
||||
}
|
||||
aria-pressed={state.matches('Sketch.Rectangle tool')}
|
||||
|
@ -28,6 +28,11 @@ export const CommandBarProvider = ({
|
||||
Object.keys(context.selectedCommand?.args).length === 0
|
||||
)
|
||||
},
|
||||
'All arguments are skippable': (context, _event) => {
|
||||
return Object.values(context.selectedCommand!.args!).every(
|
||||
(argConfig) => argConfig.skip
|
||||
)
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
|
@ -70,7 +70,7 @@ function CommandComboBox({
|
||||
>
|
||||
{filteredOptions?.map((option) => (
|
||||
<Combobox.Option
|
||||
key={option.name}
|
||||
key={option.groupId + option.name + (option.displayName || '')}
|
||||
value={option}
|
||||
className="flex items-center gap-2 px-4 py-1 first:mt-2 last:mb-2 ui-active:bg-primary/10 dark:ui-active:bg-chalkboard-90"
|
||||
>
|
||||
|
@ -42,7 +42,7 @@ import {
|
||||
import { applyConstraintIntersect } from './Toolbar/Intersect'
|
||||
import { applyConstraintAbsDistance } from './Toolbar/SetAbsDistance'
|
||||
import useStateMachineCommands from 'hooks/useStateMachineCommands'
|
||||
import { modelingMachineConfig } from 'lib/commandBarConfigs/modelingCommandConfig'
|
||||
import { modelingMachineCommandConfig } from 'lib/commandBarConfigs/modelingCommandConfig'
|
||||
import {
|
||||
STRAIGHT_SEGMENT,
|
||||
TANGENTIAL_ARC_TO_SEGMENT,
|
||||
@ -920,7 +920,7 @@ export const ModelingMachineProvider = ({
|
||||
state: modelingState,
|
||||
send: modelingSend,
|
||||
actor: modelingActor,
|
||||
commandBarConfig: modelingMachineConfig,
|
||||
commandBarConfig: modelingMachineCommandConfig,
|
||||
allCommandsRequireNetwork: true,
|
||||
// TODO for when sketch tools are in the toolbar: This was added when we used one "Cancel" event,
|
||||
// but we need to support "SketchCancel" and basically
|
||||
|
@ -6,7 +6,11 @@ import { modelingMachine } from 'machines/modelingMachine'
|
||||
import { authMachine } from 'machines/authMachine'
|
||||
import { settingsMachine } from 'machines/settingsMachine'
|
||||
import { homeMachine } from 'machines/homeMachine'
|
||||
import { Command, CommandSetConfig, CommandSetSchema } from 'lib/commandTypes'
|
||||
import {
|
||||
Command,
|
||||
StateMachineCommandSetConfig,
|
||||
StateMachineCommandSetSchema,
|
||||
} from 'lib/commandTypes'
|
||||
import { useKclContext } from 'lang/KclProvider'
|
||||
import { useNetworkContext } from 'hooks/useNetworkContext'
|
||||
import { NetworkHealthState } from 'hooks/useNetworkStatus'
|
||||
@ -21,20 +25,20 @@ export type AllMachines =
|
||||
|
||||
interface UseStateMachineCommandsArgs<
|
||||
T extends AllMachines,
|
||||
S extends CommandSetSchema<T>
|
||||
S extends StateMachineCommandSetSchema<T>
|
||||
> {
|
||||
machineId: T['id']
|
||||
state: StateFrom<T>
|
||||
send: Function
|
||||
actor: InterpreterFrom<T>
|
||||
commandBarConfig?: CommandSetConfig<T, S>
|
||||
commandBarConfig?: StateMachineCommandSetConfig<T, S>
|
||||
allCommandsRequireNetwork?: boolean
|
||||
onCancel?: () => void
|
||||
}
|
||||
|
||||
export default function useStateMachineCommands<
|
||||
T extends AnyStateMachine,
|
||||
S extends CommandSetSchema<T>
|
||||
S extends StateMachineCommandSetSchema<T>
|
||||
>({
|
||||
machineId,
|
||||
state,
|
||||
@ -58,7 +62,7 @@ export default function useStateMachineCommands<
|
||||
const newCommands = state.nextEvents
|
||||
.filter((_) => !allCommandsRequireNetwork || !disableAllButtons)
|
||||
.filter((e) => !['done.', 'error.'].some((n) => e.includes(n)))
|
||||
.map((type) =>
|
||||
.flatMap((type) =>
|
||||
createMachineCommand<T, S>({
|
||||
// The group is the owner machine's ID.
|
||||
groupId: machineId,
|
||||
|
@ -1,9 +1,9 @@
|
||||
import { CommandSetConfig } from 'lib/commandTypes'
|
||||
import { StateMachineCommandSetConfig } from 'lib/commandTypes'
|
||||
import { authMachine } from 'machines/authMachine'
|
||||
|
||||
type AuthCommandSchema = {}
|
||||
|
||||
export const authCommandBarConfig: CommandSetConfig<
|
||||
export const authCommandBarConfig: StateMachineCommandSetConfig<
|
||||
typeof authMachine,
|
||||
AuthCommandSchema
|
||||
> = {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { CommandSetConfig } from 'lib/commandTypes'
|
||||
import { StateMachineCommandSetConfig } from 'lib/commandTypes'
|
||||
import { homeMachine } from 'machines/homeMachine'
|
||||
|
||||
export type HomeCommandSchema = {
|
||||
@ -17,7 +17,7 @@ export type HomeCommandSchema = {
|
||||
}
|
||||
}
|
||||
|
||||
export const homeCommandBarConfig: CommandSetConfig<
|
||||
export const homeCommandBarConfig: StateMachineCommandSetConfig<
|
||||
typeof homeMachine,
|
||||
HomeCommandSchema
|
||||
> = {
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { Models } from '@kittycad/lib'
|
||||
import { CommandSetConfig, KclCommandValue } from 'lib/commandTypes'
|
||||
import { StateMachineCommandSetConfig, KclCommandValue } from 'lib/commandTypes'
|
||||
import { KCL_DEFAULT_LENGTH } from 'lib/constants'
|
||||
import { Selections } from 'lib/selections'
|
||||
import { modelingMachine } from 'machines/modelingMachine'
|
||||
import { modelingMachine, SketchTool } from 'machines/modelingMachine'
|
||||
|
||||
type OutputFormat = Models['OutputFormat_type']
|
||||
type OutputTypeKey = OutputFormat['type']
|
||||
@ -27,9 +27,12 @@ export type ModelingCommandSchema = {
|
||||
// result: (typeof EXTRUSION_RESULTS)[number]
|
||||
distance: KclCommandValue
|
||||
}
|
||||
'change tool': {
|
||||
tool: SketchTool
|
||||
}
|
||||
}
|
||||
|
||||
export const modelingMachineConfig: CommandSetConfig<
|
||||
export const modelingMachineCommandConfig: StateMachineCommandSetConfig<
|
||||
typeof modelingMachine,
|
||||
ModelingCommandSchema
|
||||
> = {
|
||||
@ -37,22 +40,47 @@ export const modelingMachineConfig: CommandSetConfig<
|
||||
description: 'Enter sketch mode.',
|
||||
icon: 'sketch',
|
||||
},
|
||||
// TODO the event is no 'change tool' with data: 'line', 'rectangle' etc
|
||||
// 'Equip Line tool': {
|
||||
// description: 'Start drawing straight lines.',
|
||||
// icon: 'line',
|
||||
// displayName: 'Line',
|
||||
// },
|
||||
// 'Equip tangential arc to': {
|
||||
// description: 'Start drawing an arc tangent to the current segment.',
|
||||
// icon: 'arc',
|
||||
// displayName: 'Tangential Arc',
|
||||
// },
|
||||
// 'Equip rectangle tool': {
|
||||
// description: 'Start drawing a rectangle.',
|
||||
// icon: 'rectangle',
|
||||
// displayName: 'Rectangle',
|
||||
// },
|
||||
'change tool': [
|
||||
{
|
||||
description: 'Start drawing straight lines.',
|
||||
icon: 'line',
|
||||
displayName: 'Line',
|
||||
args: {
|
||||
tool: {
|
||||
defaultValue: 'line',
|
||||
required: true,
|
||||
skip: true,
|
||||
inputType: 'string',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
description: 'Start drawing an arc tangent to the current segment.',
|
||||
icon: 'arc',
|
||||
displayName: 'Tangential Arc',
|
||||
args: {
|
||||
tool: {
|
||||
defaultValue: 'tangentialArc',
|
||||
required: true,
|
||||
skip: true,
|
||||
inputType: 'string',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
description: 'Start drawing a rectangle.',
|
||||
icon: 'rectangle',
|
||||
displayName: 'Rectangle',
|
||||
args: {
|
||||
tool: {
|
||||
defaultValue: 'rectangle',
|
||||
required: true,
|
||||
skip: true,
|
||||
inputType: 'string',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
Export: {
|
||||
description: 'Export the current model.',
|
||||
icon: 'exportFile',
|
||||
|
@ -33,13 +33,13 @@ export interface KclExpressionWithVariable extends KclExpression {
|
||||
export type KclCommandValue = KclExpression | KclExpressionWithVariable
|
||||
export type CommandInputType = (typeof INPUT_TYPES)[number]
|
||||
|
||||
export type CommandSetSchema<T extends AnyStateMachine> = Partial<{
|
||||
export type StateMachineCommandSetSchema<T extends AnyStateMachine> = Partial<{
|
||||
[EventType in EventFrom<T>['type']]: Record<string, any>
|
||||
}>
|
||||
|
||||
export type CommandSet<
|
||||
export type StateMachineCommandSet<
|
||||
T extends AllMachines,
|
||||
Schema extends CommandSetSchema<T>
|
||||
Schema extends StateMachineCommandSetSchema<T>
|
||||
> = Partial<{
|
||||
[EventType in EventFrom<T>['type']]: Command<
|
||||
T,
|
||||
@ -48,21 +48,25 @@ export type CommandSet<
|
||||
>
|
||||
}>
|
||||
|
||||
export type CommandSetConfig<
|
||||
/**
|
||||
* A configuration object for a set of commands tied to a state machine.
|
||||
* Each event type can have one or more commands associated with it.
|
||||
* @param T The state machine type.
|
||||
* @param Schema The schema for the command set, defined by the developer.
|
||||
*/
|
||||
export type StateMachineCommandSetConfig<
|
||||
T extends AllMachines,
|
||||
Schema extends CommandSetSchema<T>
|
||||
Schema extends StateMachineCommandSetSchema<T>
|
||||
> = Partial<{
|
||||
[EventType in EventFrom<T>['type']]: CommandConfig<
|
||||
T,
|
||||
EventFrom<T>['type'],
|
||||
Schema[EventType]
|
||||
>
|
||||
[EventType in EventFrom<T>['type']]:
|
||||
| CommandConfig<T, EventFrom<T>['type'], Schema[EventType]>
|
||||
| CommandConfig<T, EventFrom<T>['type'], Schema[EventType]>[]
|
||||
}>
|
||||
|
||||
export type Command<
|
||||
T extends AnyStateMachine = AnyStateMachine,
|
||||
CommandName extends EventFrom<T>['type'] = EventFrom<T>['type'],
|
||||
CommandSchema extends CommandSetSchema<T>[CommandName] = CommandSetSchema<T>[CommandName]
|
||||
CommandSchema extends StateMachineCommandSetSchema<T>[CommandName] = StateMachineCommandSetSchema<T>[CommandName]
|
||||
> = {
|
||||
name: CommandName
|
||||
groupId: T['id']
|
||||
@ -81,7 +85,7 @@ export type Command<
|
||||
export type CommandConfig<
|
||||
T extends AnyStateMachine = AnyStateMachine,
|
||||
CommandName extends EventFrom<T>['type'] = EventFrom<T>['type'],
|
||||
CommandSchema extends CommandSetSchema<T>[CommandName] = CommandSetSchema<T>[CommandName]
|
||||
CommandSchema extends StateMachineCommandSetSchema<T>[CommandName] = StateMachineCommandSetSchema<T>[CommandName]
|
||||
> = Omit<
|
||||
Command<T, CommandName, CommandSchema>,
|
||||
'name' | 'groupId' | 'onSubmit' | 'onCancel' | 'args' | 'needsReview'
|
||||
|
@ -11,20 +11,20 @@ import {
|
||||
CommandArgument,
|
||||
CommandArgumentConfig,
|
||||
CommandConfig,
|
||||
CommandSetConfig,
|
||||
CommandSetSchema,
|
||||
StateMachineCommandSetConfig,
|
||||
StateMachineCommandSetSchema,
|
||||
} from './commandTypes'
|
||||
|
||||
interface CreateMachineCommandProps<
|
||||
T extends AnyStateMachine,
|
||||
S extends CommandSetSchema<T>
|
||||
S extends StateMachineCommandSetSchema<T>
|
||||
> {
|
||||
type: EventFrom<T>['type']
|
||||
groupId: T['id']
|
||||
state: StateFrom<T>
|
||||
send: Function
|
||||
actor: InterpreterFrom<T>
|
||||
commandBarConfig?: CommandSetConfig<T, S>
|
||||
commandBarConfig?: StateMachineCommandSetConfig<T, S>
|
||||
onCancel?: () => void
|
||||
}
|
||||
|
||||
@ -32,7 +32,7 @@ interface CreateMachineCommandProps<
|
||||
// from a more terse Command Bar Meta definition.
|
||||
export function createMachineCommand<
|
||||
T extends AnyStateMachine,
|
||||
S extends CommandSetSchema<T>
|
||||
S extends StateMachineCommandSetSchema<T>
|
||||
>({
|
||||
groupId,
|
||||
type,
|
||||
@ -41,13 +41,30 @@ export function createMachineCommand<
|
||||
actor,
|
||||
commandBarConfig,
|
||||
onCancel,
|
||||
}: CreateMachineCommandProps<T, S>): Command<
|
||||
T,
|
||||
typeof type,
|
||||
S[typeof type]
|
||||
> | null {
|
||||
}: CreateMachineCommandProps<T, S>):
|
||||
| Command<T, typeof type, S[typeof type]>
|
||||
| Command<T, typeof type, S[typeof type]>[]
|
||||
| null {
|
||||
const commandConfig = commandBarConfig && commandBarConfig[type]
|
||||
if (!commandConfig) return null
|
||||
// There may be no command config for this event type,
|
||||
// or there may be multiple commands to create.
|
||||
if (!commandConfig) {
|
||||
return null
|
||||
} else if (commandConfig instanceof Array) {
|
||||
return commandConfig
|
||||
.map((config) =>
|
||||
createMachineCommand({
|
||||
groupId,
|
||||
type,
|
||||
state,
|
||||
send,
|
||||
actor,
|
||||
commandBarConfig: { [type]: config },
|
||||
onCancel,
|
||||
})
|
||||
)
|
||||
.filter((c) => c !== null) as Command<T, typeof type, S[typeof type]>[]
|
||||
}
|
||||
|
||||
// Hide commands based on platform by returning `null`
|
||||
// so the consumer can filter them out
|
||||
@ -84,6 +101,10 @@ export function createMachineCommand<
|
||||
command.onCancel = onCancel
|
||||
}
|
||||
|
||||
if ('displayName' in commandConfig) {
|
||||
command.displayName = commandConfig.displayName
|
||||
}
|
||||
|
||||
return command
|
||||
}
|
||||
|
||||
@ -92,7 +113,7 @@ export function createMachineCommand<
|
||||
// bundled together into the args for a Command.
|
||||
function buildCommandArguments<
|
||||
T extends AnyStateMachine,
|
||||
S extends CommandSetSchema<T>,
|
||||
S extends StateMachineCommandSetSchema<T>,
|
||||
CommandName extends EventFrom<T>['type'] = EventFrom<T>['type']
|
||||
>(
|
||||
state: StateFrom<T>,
|
||||
@ -112,7 +133,7 @@ function buildCommandArguments<
|
||||
|
||||
export function buildCommandArgument<
|
||||
T extends AnyStateMachine,
|
||||
O extends CommandSetSchema<T> = CommandSetSchema<T>
|
||||
O extends StateMachineCommandSetSchema<T> = StateMachineCommandSetSchema<T>
|
||||
>(
|
||||
arg: CommandArgumentConfig<O, T>,
|
||||
context: ContextFrom<T>,
|
||||
|
@ -66,7 +66,7 @@ export type CommandBarMachineEvent =
|
||||
|
||||
export const commandBarMachine = createMachine(
|
||||
{
|
||||
/** @xstate-layout N4IgpgJg5mDOIC5QGED2BbdBDAdhABAEJYBOAxMgDaqxgDaADALqKgAONAlgC6eo6sQAD0QBaAJwA6AGwAmAKwBmBoukAWafIAcDcSoA0IAJ6JZDaZIDs8hgzV6AjA61a1DWQF8PhtJlwFiciowUkYWJBAOWB4+AQiRBFF5CwdpcVkHS1lpVyU5QxNEh1lFGTUsrUUtOQd5SwZLLx8MbDwiUkkqGkgyAHk2MBwwwSiY-kEEswZJbPltM0U3eXLZAsRFeQcrerUHRbTFvfkmkF9WgI6u2ggyADFONv98WkowAGNufDeW-2GI0d443iiHESkktUUilkskqdiUWjWCAcDC0kjUqnElkc6lkoK0JzOT0CnWo1zIAEEIARvn48LA-uwuIC4qAEqIHJjJPJcYtxFoYdJFFjVsZEG5pqCquJxJoGvJxOUCT82sSrj0AEpgdCoABuYC+yog9OYIyZsQmYmhWzMmTqLnU0kyikRGVRbj5lg2SmUam5StpFxIkgAymBXh8HlADQGyKHw58aecGZEzUDWYgchY7CisWoSlpQQ5EVDLJJxKkdIpyypUop-ed2kHCW0Xu9uD1kwDzcCEJCtlUNgWhZZ1OlnaKEBpZJItHVzDZ5xlpPWiZdDc8w22Ow5wozosyLUiVNMSg5ytVKmfrIipzO564z2otPVpI1vKd18SAOJYbgACzAEhI3wUgoAAV3QQZuFgCg-1wGAvjAkgSCgkCSHAyCcG4TtUxZYRED2TQZGSOw80qaQ7ARCc9mmZYSksextGkNJBRXFUOh-f9AOA0CIKgmCABE4E3D5oyTE1-lww8clKBjZF2Bh5SFZwXUUyRVDzJwNE2LQzzYwNJE4gCgJwKNeMw6DJHJAB3LAYlM-AHjYMDuFjMCACN0B4NCMKgnD927dMkWSUs8yY8RISfWQshvcsrDlapshULJPHfZsDKM7iHPM-jJAANSwShOAgX9IzICB+DASQHh1VAAGsqp1Qrit-MByXQvisP8sY8ISZwbCsDllBLSwz1qRFBQsRZ5WRIVkui-TG0M39jJ4jqLNgfLmpK3hTLIQCSFQIM2EoX8ADMjvQSQmqKna2vWvyJL3HrD1SEoyzSdJUkUm9dnUtQn10aK6hkxbiU1HVODAay3M87zE1+J6UwCtN8IQUauR0OZ0ksFwUUqRFPWmUdouPXR3TBjoIahmHKQIHKuqRrtUYSaVShhLF+TkeTzBFQosVKDRM2RVInEdSmg2p6GyE1bU9R8zrsKZqSexFqQHWlHNXHzCbFhnX1+UydFkVxiXJClmGAFEIG8hmld3ZGXp7TR5C5RSCxdjlQV1tR9bqaVdhsSFxDN5AALeOrgPa3ysJgiqcCqmr6sa7bWujxXjQd5nesQZYthsblIQYJx6hUic9AsdEFT2HQzByVLmgDJaw-eSOHPTjbysq6qcFqhrrtT9sO-4ugd1NFGc4QXEPo5eVLGsFxlnKREXGnZI9HcT1mOikO0s-S5w7bqNh9j-bkKOyQTvOy6B9utOHtj7qD1V8pSyrHJZ3STY4QmjQ0R2Ww0oSjuF3u+HAqAIBwEEOlRs48nZBVENkKQNprC42qBoJ0LothaXMJ9aElRXDLj3k3VUpJIBwOfgg4oMx8y41SPUOY8p5DFk2GiKoxsoRVmhGoM2cY2zAQRngChgU0a7HZtFH0ilRp1D5usVh6JXCKD2CUdI8lQ7rlbB8chkkJ6HkxFsBeulbQZAUCwrYCiqzIhyE+fqZtMomTMg-aCwiWYEV2NOBUCghQ6EFGzYsvpwQUT5MxawFECx2JWllRxMdLI2TsrtKMTkXIuMnmeCiZYwrePMFWCKv1XZKVGroWwmxNARK4g4hWG0tp3wSSk16lQpC41ULjV8uxUjSBvFCNEDTdCOkWCY44xCGzgzAJDaGdTnaZHBADYcqg5DpCovzeRno5izA0BeUOh8o5OPgDo+BaNvqV0xNFaE7gdYTnnvkmUChdKEMyF4LwQA */
|
||||
/** @xstate-layout N4IgpgJg5mDOIC5QGED2BbdBDAdhABAEJYBOAxMgDaqxgDaADALqKgAONAlgC6eo6sQAD0QBaAJwA6AGwAmAKwBmBoukAWafIAcDcSoA0IAJ6JZDaZIDs8hgzV6AjA61a1DWQF8PhtJlwFiciowUkYWJBAOWB4+AQiRBFF5CwdpcVkHS1lpVyU5QxNEh1lFGTUsrUUtOQd5SwZLLx8MbDwiUkkqGkgyAHk2MBwwwSiY-kEEswZJbPltM0U3eXLZAsRFeQcrerUHRbTFvfkmkF9WgI6u2ggyADFONv98WkowAGNufDeW-2GI0d443iiHESkktUUilkskqdiUWjWCAcDC0kjUqnElkc6lkoK0JzOT0CnWo1zIAEEIARvn48LA-uwuIC4qAEqIHJjJPJcYtxFoYdJFFjVsZEG5pqCquJxJoGvJxOUCT82sSrj0AEpgdCoABuYC+yog9OYIyZsQmYmhWzMmTqLnU0kyikRGVRbj5lg2SmUam5StpFxIkgAymBXh8HlADQGyKHw58aecGZEzUDWYgchY7CisWoSlpQQ5EVDLJJxKkdIpyypUop-ed2kHCW0Xu9uD1kwDzcCEJCtlUNgWhZZ1OlnaKEBpZJItHVzDZ5xlpPWiZdDc8w22O7JwozosyLUj3KiZZY85YtMUNgx5Ii81JuS5xBtPVCCyuVR0AOJYbgACzAEhI3wUgoAAV3QQZuFgCg-1wGAvjAkgSCgkCSHAyCcG4TtUxZYRED2TQZGSOw80qaQ7ARCc9mmZYSjPPFpDSQUP0DSQf3-QDgNAiCoJggAROBNw+aMkxNf5cMPHJSjPWRdhvZ9LGcF0b0kVQ8ycDRNkvNRWMbdjfwAoCcCjHjMOgyRyQAdywGITPwB42DA7hYzAgAjdAeDQjCoJw-du3TJE6mnWwoT0NIUTUAs71sMtdGsRYCyUtI9OJDijO49DeKw2BJAANSwShOAgX9IzICB+DASQHh1VAAGsqp1Qrit-MBySy8y-LGPCElSeoy2lZJcwcNRfXHQpBWmWQsRsPYdDPZJUu-QyuPssy+Py5qSt4EyyEAkhUCDNhKF-AAzQ70EkJqiu2tqOt88S926w9UhhLlykWXFHXcTJixsd60hHGxNj2Jag01HVODAKzXI8rzE1+R6U38tN8IQJSuR0OZ0gvHQXHGxBPWmUdppUWwFV0MHJAhqGYcpAh1qwrqDx7ZFajUmVpulEbqlqREsfBTQ0jcPM5P5KmaehshNW1PVvOy7Cka7VHeoYDkyjSPQtAvPMqkRQU1BnX1+UydFkQvCWwEhqWAFEIC8xnFd3ZHntZuTDZG4ob1nGxPTUfXrBnS8nDmEpT2ObxTnXVUALeOrgPanycvKyrqpwWqGqurbWsThXjWd5WesQZYtmBkplCceplIncK0SrXYqnccxxcj5s2OQWP4-s3PzJgiqcCqmr6sa7P2x7vi6AcAvJJ7XEy0dUFMWsFxlnKfn+S5CL3E9Jiuapjv3i7qNx+T-bDskY6zourObpz+6cuZgK0Y5Ua0TqEvXDkJR-YnR0s1xjkIMnDln3uuVsHwOxT1NCjIuR5nCSBUExJi1huRqyooUTYpYnzeyUFkKsy4Tg4FQBAOAgg26Nmga7QKohshSBtNYXGDonQumtPYaQfsSjLBHDefepJICUJZtQ4oMx8wXj6jebGt4JwbC2OiVwig9hh2hLpVu0cOhxjbMBBGeABFPwSA3ERRMlhKWCn9WRVQzZQirMo0BAYNzxn4RJGBh5MRbGXsHawGQFBmLrpUasOQorOAjs0OxaUVrGVMvfaCuiVYEV2KWTYg1yxyA0i6ZYaIPSL3lOkS8wSo6hOWpxCJ8te6WRsnZKMjlnIxNgSNIiiTF6vVSdI9JM1taXlxLzTwqiClBnSqtSJScLIFVvjtKANSXquENqoJwtgyZzRFIUQ4MhqgNACdNTQCpLbWyshMnsjpSwjXRJYHecgcmImsLIz0odNAaGqPiHpDYY6HwTlE+ATiqHPwohYewWQshmGhHrCcJz5Bck5toZwGhMheC8EAA */
|
||||
predictableActionArguments: true,
|
||||
tsTypes: {} as import('./commandBarMachine.typegen').Typegen0,
|
||||
context: {
|
||||
@ -147,6 +147,10 @@ export const commandBarMachine = createMachine(
|
||||
cond: 'Command has no arguments',
|
||||
actions: ['Execute command'],
|
||||
},
|
||||
{
|
||||
target: 'Checking Arguments',
|
||||
cond: 'All arguments are skippable',
|
||||
},
|
||||
{
|
||||
target: 'Gathering arguments',
|
||||
actions: ['Set current argument to first non-skippable'],
|
||||
|