1- import React , { forwardRef } from 'react' ;
1+ import React , { forwardRef , useCallback , useState } from 'react' ;
22
33import styles from './index.module.css' ;
4- import { Button , ButtonProps , Icon , Spin } from '@gravity-ui/uikit' ;
5- import { ArrowRotateRight } from '@gravity-ui/icons' ;
4+ import { Button , ButtonProps , Icon , Popover , Spin } from '@gravity-ui/uikit' ;
5+ import { ArrowRotateRight , ChevronDown } from '@gravity-ui/icons' ;
66import { thunkRunTest } from '@/static/modules/actions' ;
77import { useDispatch , useSelector } from 'react-redux' ;
88import { RunTestsFeature } from '@/constants' ;
99import { useAnalytics } from '../../hooks/useAnalytics' ;
1010import type { BrowserEntity } from '@/static/new-ui/types/store' ;
1111import { isFeatureAvailable } from '../../utils/features' ;
12+ import classNames from 'classnames' ;
13+ import ExtensionPoint , { getExtensionPointComponents } from '../../../components/extension-point' ;
14+ import * as plugins from '../../../modules/plugins' ;
15+ import { ExtensionPointName } from '../../constants/plugins' ;
1216
1317interface RunTestProps {
1418 browser : BrowserEntity | null ;
@@ -35,10 +39,45 @@ export const RunTestButton = forwardRef<HTMLButtonElement | HTMLAnchorElement, R
3539 return null ;
3640 }
3741
38- // eslint-disable-next-line @typescript-eslint/no-explicit-any
39- return < Button ref = { ref as any } view = { 'action' } className = { styles . retryButton } onClick = { onRetryTestHandler } disabled = { isRunning } style = { { width : buttonText === null ? '28px' : undefined } } { ...buttonProps } >
40- { isRunning ? < Spin size = { 'xs' } /> : < Icon data = { ArrowRotateRight } /> } { buttonText === undefined ? 'Retry' : buttonText }
41- </ Button > ;
42+ const loadedPluginConfigs = plugins . getLoadedConfigs ( ) ;
43+ const pluginComponents = getExtensionPointComponents ( loadedPluginConfigs , ExtensionPointName . RunTestOptions ) ;
44+ const hasRunTestOptions = pluginComponents . length > 0 ;
45+ const [ isRunOptionsOpen , setIsRunOptionsOpen ] = useState ( false ) ;
46+ const onRunOptionsOpenChange = useCallback ( ( open : boolean ) => {
47+ setIsRunOptionsOpen ( open ) ;
48+ } , [ ] ) ;
49+
50+ return < div className = { styles . buttonsContainer } >
51+ < Button
52+ ref = { ref as any } // eslint-disable-line @typescript-eslint/no-explicit-any
53+ view = { 'action' }
54+ className = { styles . retryButton }
55+ onClick = { onRetryTestHandler }
56+ disabled = { isRunning }
57+ style = { { width : buttonText === null ? '28px' : undefined } }
58+ pin = { hasRunTestOptions ? 'round-brick' : undefined }
59+ { ...buttonProps }
60+ >
61+ { isRunning ? < Spin size = { 'xs' } /> : < Icon data = { ArrowRotateRight } /> } { buttonText === undefined ? 'Retry' : buttonText }
62+ </ Button >
63+ { hasRunTestOptions && < Popover
64+ onOpenChange = { onRunOptionsOpenChange }
65+ content = { < div className = { styles . runOptionsContainer } > < ExtensionPoint name = { ExtensionPointName . RunTestOptions } > </ ExtensionPoint > </ div > }
66+ trigger = 'click'
67+ placement = 'bottom-end'
68+ >
69+ < Button
70+ view = 'action'
71+ disabled = { isRunning }
72+ className = { classNames ( styles . retryButton , styles . runOptionsButton ) }
73+ style = { { width : buttonText === null ? '28px' : undefined } }
74+ pin = 'brick-round'
75+ { ...buttonProps }
76+ >
77+ < Icon data = { ChevronDown } className = { classNames ( styles . runOptionsButtonIcon , { [ styles . runOptionsButtonIconRotated ] : isRunOptionsOpen } ) } />
78+ </ Button >
79+ </ Popover > }
80+ </ div > ;
4281 }
4382) ;
4483
0 commit comments