Add a loading state to CommandBarKclInput while calculating (#6025)
* Add a loading state to CommandBarKclInput while calculating This is so that we can more reliably await for the calculation to be completed before advancing the command bar in Playwright E2E tests. * Make sure the spinner shows on first frame, before `isExecuting` is set too
This commit is contained in:
		@ -27,6 +27,7 @@ import { getNodeFromPath } from 'lang/queryAst'
 | 
			
		||||
import { isPathToNode, SourceRange, VariableDeclarator } from 'lang/wasm'
 | 
			
		||||
import { Node } from '@rust/kcl-lib/bindings/Node'
 | 
			
		||||
import { err } from 'lib/trap'
 | 
			
		||||
import { Spinner } from 'components/Spinner'
 | 
			
		||||
 | 
			
		||||
// TODO: remove the need for this selector once we decouple all actors from React
 | 
			
		||||
const machineContextSelector = (snapshot?: SnapshotFrom<AnyStateMachine>) =>
 | 
			
		||||
@ -115,6 +116,7 @@ function CommandBarKclInput({
 | 
			
		||||
    setNewVariableName,
 | 
			
		||||
    isNewVariableNameUnique,
 | 
			
		||||
    prevVariables,
 | 
			
		||||
    isExecuting,
 | 
			
		||||
  } = useCalculateKclExpression({
 | 
			
		||||
    value,
 | 
			
		||||
    initialVariableName,
 | 
			
		||||
@ -200,9 +202,11 @@ function CommandBarKclInput({
 | 
			
		||||
 | 
			
		||||
  useEffect(() => {
 | 
			
		||||
    setCanSubmit(
 | 
			
		||||
      calcResult !== 'NAN' && (!createNewVariable || isNewVariableNameUnique)
 | 
			
		||||
      calcResult !== 'NAN' &&
 | 
			
		||||
        (!createNewVariable || isNewVariableNameUnique) &&
 | 
			
		||||
        !isExecuting
 | 
			
		||||
    )
 | 
			
		||||
  }, [calcResult, createNewVariable, isNewVariableNameUnique])
 | 
			
		||||
  }, [calcResult, createNewVariable, isNewVariableNameUnique, isExecuting])
 | 
			
		||||
 | 
			
		||||
  function handleSubmit(e?: React.FormEvent<HTMLFormElement>) {
 | 
			
		||||
    e?.preventDefault()
 | 
			
		||||
@ -268,9 +272,13 @@ function CommandBarKclInput({
 | 
			
		||||
              : 'text-succeed-80 dark:text-succeed-40'
 | 
			
		||||
          }
 | 
			
		||||
        >
 | 
			
		||||
          {calcResult === 'NAN'
 | 
			
		||||
            ? "Can't calculate"
 | 
			
		||||
            : roundOff(Number(calcResult), 4)}
 | 
			
		||||
          {isExecuting === true || !calcResult ? (
 | 
			
		||||
            <Spinner className="text-inherit w-4 h-4" />
 | 
			
		||||
          ) : calcResult === 'NAN' ? (
 | 
			
		||||
            "Can't calculate"
 | 
			
		||||
          ) : (
 | 
			
		||||
            roundOff(Number(calcResult), 4)
 | 
			
		||||
          )}
 | 
			
		||||
        </span>
 | 
			
		||||
      </label>
 | 
			
		||||
      {createNewVariable ? (
 | 
			
		||||
 | 
			
		||||
@ -35,7 +35,12 @@ export function useCalculateKclExpression({
 | 
			
		||||
  isNewVariableNameUnique: boolean
 | 
			
		||||
  newVariableInsertIndex: number
 | 
			
		||||
  setNewVariableName: (a: string) => void
 | 
			
		||||
  isExecuting: boolean
 | 
			
		||||
} {
 | 
			
		||||
  // Executing the mini AST to calculate the expression value
 | 
			
		||||
  // is asynchronous. Use this state variable to track if execution
 | 
			
		||||
  // has completed
 | 
			
		||||
  const [isExecuting, setIsExecuting] = useState(false)
 | 
			
		||||
  const { variables, code } = useKclContext()
 | 
			
		||||
  const { context } = useModelingContext()
 | 
			
		||||
  // If there is no selection, use the end of the code
 | 
			
		||||
@ -110,6 +115,7 @@ export function useCalculateKclExpression({
 | 
			
		||||
  useEffect(() => {
 | 
			
		||||
    const execAstAndSetResult = async () => {
 | 
			
		||||
      const result = await getCalculatedKclExpressionValue(value)
 | 
			
		||||
      setIsExecuting(false)
 | 
			
		||||
      if (result instanceof Error || 'errors' in result || !result.astNode) {
 | 
			
		||||
        setCalcResult('NAN')
 | 
			
		||||
        setValueNode(null)
 | 
			
		||||
@ -121,8 +127,10 @@ export function useCalculateKclExpression({
 | 
			
		||||
      result?.astNode && setValueNode(result.astNode)
 | 
			
		||||
    }
 | 
			
		||||
    if (!value) return
 | 
			
		||||
    setIsExecuting(true)
 | 
			
		||||
    execAstAndSetResult().catch(() => {
 | 
			
		||||
      setCalcResult('NAN')
 | 
			
		||||
      setIsExecuting(false)
 | 
			
		||||
      setValueNode(null)
 | 
			
		||||
    })
 | 
			
		||||
  }, [value, availableVarInfo, code, kclManager.variables])
 | 
			
		||||
@ -136,5 +144,6 @@ export function useCalculateKclExpression({
 | 
			
		||||
    isNewVariableNameUnique,
 | 
			
		||||
    setNewVariableName,
 | 
			
		||||
    inputRef,
 | 
			
		||||
    isExecuting,
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user