1414 * limitations under the License.
1515 */
1616
17- import React , { memo , useCallback , useEffect , useMemo , useRef , useState } from 'react'
18- import Draggable from 'react-draggable'
17+ import React , { memo , useCallback , useState } from 'react'
1918import Tippy from '@tippyjs/react'
2019
2120import { ReactComponent as ICDrag } from '@Icons/ic-drag.svg'
21+ import { DraggablePositionVariant , DraggableWrapper } from '@Common/DraggableWrapper'
2222import { useAsync } from '@Common/Helper'
23- import { useWindowSize } from '@Common/Hooks'
2423import { ALLOW_ACTION_OUTSIDE_FOCUS_TRAP } from '@Shared/constants'
2524
2625import { Icon } from '../Icon'
27- import { SUGGESTIONS_SIZE } from './constants'
2826import { getScopedVariables } from './service'
2927import Suggestions from './Suggestions'
3028import { FloatingVariablesSuggestionsProps } from './types'
@@ -35,7 +33,6 @@ import { FloatingVariablesSuggestionsProps } from './types'
3533 * @param appId - To fetch the scoped variables
3634 * @param envId - (Optional)
3735 * @param clusterId - (Optional)
38- * @param bounds - (Optional) To set the bounds of the suggestions
3936 * @param hideObjectVariables - (Optional) To hide the object/array variables, default is true
4037 * @returns
4138 */
@@ -44,89 +41,18 @@ const FloatingVariablesSuggestions = ({
4441 appId,
4542 envId,
4643 clusterId,
47- bounds,
4844 hideObjectVariables = true ,
4945 showValueOnHover = true ,
5046 isTemplateView,
5147} : FloatingVariablesSuggestionsProps ) => {
5248 const [ isActive , setIsActive ] = useState < boolean > ( false )
53- const [ collapsedPosition , setCollapsedPosition ] = useState < { x : number ; y : number } > ( { x : 0 , y : 0 } )
54- const [ expandedPosition , setExpandedPosition ] = useState < { x : number ; y : number } > ( { x : 0 , y : 0 } )
5549
5650 const [ loadingScopedVariables , variablesData , error , reloadScopedVariables ] = useAsync (
5751 ( ) => getScopedVariables ( appId , envId , clusterId , { hideObjectVariables, isTemplateView } ) ,
5852 [ appId , envId , clusterId ] ,
5953 )
6054
61- const windowSize = useWindowSize ( )
62- // In case of StrictMode, we get error findDOMNode is deprecated in StrictMode
63- // So we use useRef to get the DOM node
64- const nodeRef = useRef ( null )
65-
66- // nodeRef.current is dependency even though its a ref as initially its null and we need to get the
67- // first value that it gets and after that is not going to trigger again
68- const initialPosition = useMemo ( ( ) => {
69- const initialPositionData = nodeRef . current ?. getBoundingClientRect ( ) || {
70- x : 0 ,
71- y : 0 ,
72- }
73- return { x : initialPositionData . x , y : initialPositionData . y }
74- } , [ nodeRef . current ] )
75-
76- // The size of the active state can expand say in case user expands SuggestionsInfo and the widget is at bottom of screen
77- useEffect ( ( ) => {
78- const resizeObserver = new ResizeObserver ( ( entries ) => {
79- if ( entries ?. length > 0 && isActive ) {
80- const { height } = entries [ 0 ] . contentRect
81- if ( initialPosition . y + expandedPosition . y + height > windowSize . height ) {
82- setExpandedPosition ( {
83- x : expandedPosition . x ,
84- y : windowSize . height - height - initialPosition . y ,
85- } )
86- }
87- }
88- } )
89- resizeObserver . observe ( nodeRef . current )
90- return ( ) => {
91- resizeObserver . disconnect ( )
92- }
93- } , [ isActive , expandedPosition , windowSize , initialPosition ] )
94-
9555 const handleActivation = ( ) => {
96- const currentPosInScreen = {
97- x : initialPosition . x + collapsedPosition . x ,
98- y : initialPosition . y + collapsedPosition . y ,
99- }
100-
101- setExpandedPosition ( {
102- x : collapsedPosition . x ,
103- y : collapsedPosition . y ,
104- } )
105-
106- if ( currentPosInScreen . y > windowSize . height - SUGGESTIONS_SIZE . height ) {
107- setExpandedPosition ( {
108- x : collapsedPosition . x ,
109- y : windowSize . height - SUGGESTIONS_SIZE . height - initialPosition . y ,
110- } )
111- }
112-
113- if ( currentPosInScreen . x > windowSize . width - SUGGESTIONS_SIZE . width ) {
114- setExpandedPosition ( {
115- x : windowSize . width - SUGGESTIONS_SIZE . width - initialPosition . x ,
116- y : collapsedPosition . y ,
117- } )
118- }
119-
120- if (
121- currentPosInScreen . x > windowSize . width - SUGGESTIONS_SIZE . width &&
122- currentPosInScreen . y > windowSize . height - SUGGESTIONS_SIZE . height
123- ) {
124- setExpandedPosition ( {
125- x : windowSize . width - SUGGESTIONS_SIZE . width - initialPosition . x ,
126- y : windowSize . height - SUGGESTIONS_SIZE . height - initialPosition . y ,
127- } )
128- }
129-
13056 setIsActive ( true )
13157 }
13258
@@ -136,103 +62,71 @@ const FloatingVariablesSuggestions = ({
13662 setIsActive ( false )
13763 } , [ ] )
13864
139- // e will be unused, but we need to pass it as a parameter since Draggable expects it
140- const handleCollapsedDrag = ( e , data : { x : number ; y : number } ) => {
141- const currentPosInScreen = {
142- x : initialPosition . x + data . x ,
143- y : initialPosition . y + data . y ,
144- }
145- if (
146- currentPosInScreen . y < 0 ||
147- currentPosInScreen . x < 0 ||
148- currentPosInScreen . x + ( nodeRef . current ?. getBoundingClientRect ( ) . width || 0 ) > windowSize . width ||
149- currentPosInScreen . y + ( nodeRef . current ?. getBoundingClientRect ( ) . height || 0 ) > windowSize . height
150- ) {
151- return
152- }
153-
154- setCollapsedPosition ( data )
155- }
65+ const boundaryGap = { x : 32 , y : 90 }
15666
157- const handleExpandedDrag = ( e , data : { x : number ; y : number } ) => {
158- const currentPosInScreen = {
159- x : initialPosition . x + data . x ,
160- y : initialPosition . y + data . y ,
161- }
162- if (
163- currentPosInScreen . y < 0 ||
164- currentPosInScreen . x < 0 ||
165- currentPosInScreen . x + ( nodeRef . current ?. getBoundingClientRect ( ) . width || 0 ) > windowSize . width ||
166- currentPosInScreen . y + ( nodeRef . current ?. getBoundingClientRect ( ) . height || 0 ) > windowSize . height
167- ) {
168- return
169- }
170- setExpandedPosition ( data )
171- // Only Need to retain the collapsed position if the user has not dragged the suggestions, so need to update
172- setCollapsedPosition ( data )
173- }
174-
175- if ( ! isActive ) {
176- return (
177- < Draggable
178- bounds = { bounds }
179- handle = ".handle-drag"
180- nodeRef = { nodeRef }
181- position = { collapsedPosition }
182- onDrag = { handleCollapsedDrag }
183- >
184- < div
185- className = "bcn-7 dc__outline-none-imp dc__border-n0 br-48 flex h-40 pt-8 pb-8 pl-12 pr-12 dc__gap-8 dc__no-shrink dc__position-abs"
186- style = { { zIndex, boxShadow : '0px 4px 8px 0px rgba(0, 0, 0, 0.20)' } }
187- ref = { nodeRef }
188- data-testid = "collapsed-state"
67+ return (
68+ < >
69+ < div className = { `${ isActive ? 'dc__visibility-hidden dc__disable-click' : '' } ` } >
70+ < DraggableWrapper
71+ key = "collapsed"
72+ zIndex = { zIndex }
73+ positionVariant = { DraggablePositionVariant . SCREEN_BOTTOM_RIGHT }
74+ dragSelector = ".handle-drag"
75+ boundaryGap = { boundaryGap }
76+ parentRef = { null }
18977 >
190- < button type = "button" className = "dc__outline-none-imp dc__no-border p-0 bcn-7 h-24" >
191- < ICDrag className = "handle-drag dc__grabbable icon-dim-24 fcn-2" />
192- </ button >
193-
194- < Tippy content = "Scoped variables" placement = "top" className = "default-tt" arrow = { false } >
195- < button
196- className = { `dc__outline-none-imp dc__no-border p-0 bcn-7 h-20 ${ ALLOW_ACTION_OUTSIDE_FOCUS_TRAP } ` }
197- type = "button"
198- onClick = { handleActivation }
199- data-testid = "activate-suggestions"
200- aria-label = "Activate suggestions"
201- >
202- < Icon name = "ic-view-variable-toggle" color = "N0" size = { 20 } />
78+ < div
79+ className = "bcn-7 dc__outline-none-imp dc__border-n0 br-48 flex h-40 pt-8 pb-8 pl-12 pr-12 dc__gap-8 dc__no-shrink"
80+ style = { { zIndex, boxShadow : '0px 4px 8px 0px rgba(0, 0, 0, 0.20)' } }
81+ data-testid = "collapsed-state"
82+ >
83+ < button type = "button" className = "dc__outline-none-imp dc__no-border p-0 bcn-7 h-24" >
84+ < ICDrag className = "handle-drag dc__grabbable icon-dim-24 fcn-2" />
20385 </ button >
204- </ Tippy >
205- </ div >
206- </ Draggable >
207- )
208- }
20986
210- return (
211- < Draggable
212- bounds = { bounds }
213- handle = ".handle-drag"
214- nodeRef = { nodeRef }
215- position = { expandedPosition }
216- onDrag = { handleExpandedDrag }
217- >
218- < div
219- className = { `flex column dc__no-shrink w-356 dc__content-space dc__border-radius-8-imp dc__border dc__overflow-hidden dc__position-abs mxh-504 bg__overlay--primary ${ ALLOW_ACTION_OUTSIDE_FOCUS_TRAP } ` }
220- style = { {
221- zIndex,
222- boxShadow : '0px 4px 8px 0px rgba(0, 0, 0, 0.25)' ,
223- } }
224- ref = { nodeRef }
225- >
226- < Suggestions
227- handleDeActivation = { handleDeActivation }
228- loading = { loadingScopedVariables }
229- variables = { variablesData ?? [ ] }
230- reloadVariables = { reloadScopedVariables }
231- error = { error }
232- showValueOnHover = { showValueOnHover }
233- />
87+ < Tippy content = "Scoped variables" placement = "top" className = "default-tt" arrow = { false } >
88+ < button
89+ className = { `dc__outline-none-imp dc__no-border p-0 bcn-7 h-20 ${ ALLOW_ACTION_OUTSIDE_FOCUS_TRAP } ` }
90+ type = "button"
91+ onClick = { handleActivation }
92+ data-testid = "activate-suggestions"
93+ aria-label = "Activate suggestions"
94+ >
95+ < Icon name = "ic-view-variable-toggle" color = "N0" size = { 20 } />
96+ </ button >
97+ </ Tippy >
98+ </ div >
99+ </ DraggableWrapper >
100+ </ div >
101+
102+ < div className = { `${ ! isActive ? 'dc__visibility-hidden dc__disable-click' : '' } ` } >
103+ < DraggableWrapper
104+ key = { `expanded-${ loadingScopedVariables } ` }
105+ zIndex = { zIndex }
106+ positionVariant = { DraggablePositionVariant . SCREEN_BOTTOM_RIGHT }
107+ dragSelector = ".handle-drag"
108+ boundaryGap = { boundaryGap }
109+ parentRef = { null }
110+ >
111+ < div
112+ className = { `flex column dc__no-shrink w-356 dc__content-space dc__border-radius-8-imp dc__border dc__overflow-hidden mxh-504 bg__overlay--primary ${ ALLOW_ACTION_OUTSIDE_FOCUS_TRAP } ` }
113+ style = { {
114+ zIndex,
115+ boxShadow : '0px 4px 8px 0px rgba(0, 0, 0, 0.25)' ,
116+ } }
117+ >
118+ < Suggestions
119+ handleDeActivation = { handleDeActivation }
120+ loading = { loadingScopedVariables }
121+ variables = { variablesData ?? [ ] }
122+ reloadVariables = { reloadScopedVariables }
123+ error = { error }
124+ showValueOnHover = { showValueOnHover }
125+ />
126+ </ div >
127+ </ DraggableWrapper >
234128 </ div >
235- </ Draggable >
129+ </ >
236130 )
237131}
238132
0 commit comments