1111// See the License for the specific language governing permissions and
1212// limitations under the License.
1313import { Dashboard , Panel , PanelProps , PanelQuery } from "types/dashboard"
14- import { Box , Center , HStack , Menu , MenuButton , MenuDivider , MenuItem , MenuList , Popover , PopoverArrow , PopoverBody , PopoverContent , PopoverTrigger , Portal , Text , Tooltip , useColorMode , useColorModeValue , useDisclosure , useToast } from "@chakra-ui/react" ;
15- import { FaBook , FaBug , FaEdit , FaRegClock , FaRegClone , FaRegCopy , FaRegEye , FaRegEyeSlash , FaTrashAlt } from "react-icons/fa" ;
14+ import { Box , Center , HStack , Menu , MenuButton , MenuDivider , MenuItem , MenuList , Popover , PopoverArrow , PopoverBody , PopoverContent , PopoverTrigger , Portal , Text , Tooltip , useColorMode , useColorModeValue , useDisclosure , useToast , IconButton } from "@chakra-ui/react" ;
15+ import { FaBook , FaBug , FaEdit , FaEllipsisV , FaRegClock , FaRegClone , FaRegCopy , FaRegEye , FaRegEyeSlash , FaTrashAlt } from "react-icons/fa" ;
1616import { IoMdInformation } from "react-icons/io" ;
1717import { memo , useCallback , useEffect , useMemo , useRef , useState } from "react" ;
1818import { DatasourceMaxDataPoints , DatasourceMinInterval , PANEL_HEADER_HEIGHT } from "src/data/constants" ;
@@ -56,6 +56,8 @@ import { PanelTypeGraph } from "../../plugins/built-in/panel/graph/types";
5656import { DatasourceTypeTestData } from "../../plugins/built-in/datasource/testdata/types" ;
5757import PanelDatePicker from "../../components/PanelDatePicker" ;
5858import useEmbed from "hooks/useEmbed" ;
59+ import { css } from "@emotion/react" ;
60+ import customColors from "theme/colors" ;
5961
6062interface PanelGridProps {
6163 dashboard : Dashboard
@@ -347,7 +349,13 @@ export const PanelComponent = ({ dashboard, panel, variables, onRemovePanel, onH
347349 return res
348350 } , [ panel . transform , panel . enableTransform , panelData ] )
349351
350- return < Box height = { height } width = { width } className = { ( panel . styles . border == "Normal" && "bordered" ) + ( dashboard . data . styles . bgEnabled ? " panel-bg-alpha" : " panel-bg" ) } position = "relative" >
352+ return < Box height = { height } width = { width } className = { ( panel . styles . border == "Normal" && "bordered" ) + ( dashboard . data . styles . bgEnabled ? " panel-bg-alpha" : " panel-bg" ) } position = "relative"
353+ css = { css `
354+ & : hover .show-on-hover {
355+ visibility : visible
356+ }
357+ ` }
358+ >
351359
352360 { data && < Box overflow = "hidden" >
353361 < PanelHeader dashboardId = { dashboard . id } panel = { panel } data = { panelData } queryError = { queryError } onCopyPanel = { onCopyPanel } onRemovePanel = { onRemovePanel } onHidePanel = { onHidePanel } />
@@ -364,24 +372,25 @@ export const PanelComponent = ({ dashboard, panel, variables, onRemovePanel, onH
364372
365373 </ Box > }
366374 { loading && < Box position = "absolute" top = "0" right = "0" > < Loading size = "sm" /> </ Box > }
367- { ! loading && panel . enableScopeTime && < Popover trigger = "hover" >
375+
376+ { /* {!loading && panel.enableScopeTime && <Popover trigger="hover">
368377 <PopoverTrigger>
369378 <Box position="absolute" top="5px" right="5px" opacity="0.5" fontSize="0.8rem" zIndex={1000} cursor="pointer"><FaRegClock /></Box>
370379 </PopoverTrigger>
371380 <PopoverContent>
372- < PopoverArrow />
381+ <PopoverArrow />
373382 <PopoverBody>
374383 <PanelDatePicker id={panel.id.toString()} timeRange={panel.scopeTime} onChange={tr => {
375384 panel.scopeTime = tr
376385 dispatch({
377386 type: UpdatePanelEvent,
378387 data: cloneDeep(panel)
379388 })
380- } } showIcon />
389+ }} showIcon />
381390 <Text opacity={0.7} mt="2" ml="3" fontSize="0.9rem">Panel time range</Text>
382391 </PopoverBody>
383392 </PopoverContent>
384- </ Popover > }
393+ </Popover>} */ }
385394 < Box position = "absolute" top = "0" left = "0" right = "0" bottom = "0" zIndex = { - 1 } overflow = "hidden" > < PanelBorder width = { width } height = { height } border = { panel . styles ?. border } > < Box > </ Box > </ PanelBorder > </ Box >
386395 </ Box >
387396}
@@ -425,24 +434,109 @@ const PanelHeader = ({ dashboardId, queryError, panel, onCopyPanel, onRemovePane
425434 </ Tooltip >
426435 </ Box > }
427436 < Center width = "100%" >
428- < Menu placement = "bottom" >
429- < MenuButton
430- transition = 'all 0.2s'
431- _focus = { { border : null } }
432- onClick = { e => e . stopPropagation ( ) }
433- disabled = { embed }
434- >
435- < Center width = "100%" > { ! isEmpty ( title ) ? < Box cursor = "pointer" className = "hover-bordered" paddingTop = { panel . styles . title . paddingTop } paddingBottom = { panel . styles . title . paddingBottom } paddingLeft = { panel . styles . title . paddingLeft } paddingRight = { panel . styles . title . paddingRight } width = "100%" fontSize = { panel . styles . title . fontSize } fontWeight = { panel . styles . title . fontWeight } color = { paletteColorNameToHex ( panel . styles . title . color , colorMode ) } > < TitleDecoration styles = { panel . styles } > < Text noOfLines = { 1 } > { title } </ Text > </ TitleDecoration > </ Box > : < Box width = "100px" > </ Box > } </ Center >
436- </ MenuButton >
437- < Portal >
438- < MenuList p = "1" zIndex = { 1500 } >
437+ {
438+ panel . enableScopeTime && (
439+ < >
440+ < Popover
441+ isLazy
442+ returnFocusOnClose = { false }
443+ placement = 'left'
444+ closeOnBlur = { false }
445+ size = "sm"
446+ trigger = "hover"
447+
448+ >
449+ < PopoverTrigger >
450+ < Box position = "absolute" top = "5px" left = "5px" opacity = "0.5" fontSize = "0.8rem" zIndex = { 1000 } cursor = "pointer" > < FaRegClock /> </ Box >
451+ </ PopoverTrigger >
452+ < PopoverContent width = "10rem" >
453+ < PanelDatePicker id = { panel . id . toString ( ) } timeRange = { panel . scopeTime } onChange = { tr => {
454+ panel . scopeTime = tr
455+ dispatch ( {
456+ type : UpdatePanelEvent ,
457+ data : cloneDeep ( panel )
458+ } )
459+ } } showIcon />
460+ </ PopoverContent >
461+ </ Popover >
462+ </ >
463+ )
464+ }
465+ < Center width = "100%" >
466+ { ! isEmpty ( title ) ?
467+ < Box
468+ display = { 'flex' }
469+ justifyContent = { 'center' }
470+ // cursor="pointer"
471+ paddingTop = { panel . styles . title . paddingTop }
472+ paddingBottom = { panel . styles . title . paddingBottom }
473+ paddingLeft = { panel . styles . title . paddingLeft }
474+ paddingRight = { panel . styles . title . paddingRight }
475+ width = "100%"
476+ fontSize = { panel . styles . title . fontSize }
477+ fontWeight = { panel . styles . title . fontWeight }
478+ color = { paletteColorNameToHex ( panel . styles . title . color , colorMode ) } >
479+ < TitleDecoration styles = { panel . styles } >
480+ < Text noOfLines = { 1 } >
481+ { title }
482+ </ Text >
483+ </ TitleDecoration >
484+ </ Box > : < Box width = "100px" > </ Box > }
485+ </ Center >
486+ < Box visibility = { 'hidden' } className = "show-on-hover" >
487+ < Menu placement = "bottom" isLazy >
488+ < MenuButton
489+ background = { useColorModeValue ( customColors . bodyBg . light , customColors . bodyBg . dark ) }
490+ transition = 'all 0.2s'
491+ _focus = { { border : null } }
492+ onClick = { e => e . stopPropagation ( ) }
493+ disabled = { embed }
494+ cursor = { 'pointer' }
495+ as = { IconButton }
496+ aria-label = 'Options'
497+ icon = {
498+ < Box
499+ fontSize = { panel . styles . title . fontSize }
500+ fontWeight = { panel . styles . title . fontWeight }
501+ color = { paletteColorNameToHex ( panel . styles . title . color , colorMode ) }
502+ >
503+ < FaEllipsisV />
504+ </ Box > }
505+ size = { 'sm' }
506+ variant = { 'none' }
507+ >
508+ < Center width = "100%" >
509+ {
510+ ! isEmpty ( title )
511+ ?
512+ < Box
513+ cursor = "pointer"
514+ className = "hover-bordered"
515+ paddingTop = { panel . styles . title . paddingTop }
516+ paddingBottom = { panel . styles . title . paddingBottom }
517+ paddingLeft = { panel . styles . title . paddingLeft }
518+ paddingRight = { panel . styles . title . paddingRight } width = "100%"
519+ fontSize = { panel . styles . title . fontSize }
520+ fontWeight = { panel . styles . title . fontWeight }
521+ color = { paletteColorNameToHex ( panel . styles . title . color , colorMode ) }
522+ >
523+ < TitleDecoration styles = { panel . styles } >
524+ < Text noOfLines = { 1 } > { title } </ Text >
525+ </ TitleDecoration >
526+ </ Box >
527+ :
528+ < Box width = "100px" > </ Box >
529+ }
530+ </ Center >
531+ </ MenuButton >
532+
533+ < MenuList p = "1" zIndex = { 1500 } rootProps = { { fontSize : "sm" } } >
439534 < MenuItem icon = { < FaEdit /> } onClick = { ( ) => addParamToUrl ( { edit : panel . id } ) } > { t . edit } </ MenuItem >
440535 < MenuItem icon = { < FaRegCopy /> } onClick = { ( ) => onCopyPanel ( panel , "copy" ) } > { t . copy } </ MenuItem >
441536 < MenuItem icon = { < FaRegClone /> } onClick = { ( ) => onCopyPanel ( panel , "clone" ) } > { t . clone } </ MenuItem >
442537 < MenuDivider my = "1" />
443538 < MenuItem icon = { < FaBug /> } onClick = { onOpen } > { t1 . debugPanel } </ MenuItem >
444539 < MenuItem icon = { < FaRegEye /> } onClick = { ( ) => addParamToUrl ( { viewPanel : viewPanel ? null : panel . id } ) } > { viewPanel ? t1 . exitlView : t1 . viewPanel } </ MenuItem >
445-
446540 { ! viewPanel && < >
447541 < MenuDivider my = "1" />
448542 < MenuItem icon = { < FaRegEyeSlash /> } onClick = { ( ) => onHidePanel ( panel ) } > { t1 . hidePanel } </ MenuItem >
@@ -451,8 +545,8 @@ const PanelHeader = ({ dashboardId, queryError, panel, onCopyPanel, onRemovePane
451545
452546 </ > }
453547 </ MenuList >
454- </ Portal >
455- </ Menu >
548+ </ Menu >
549+ </ Box >
456550 </ Center >
457551 { /* <Box display="none"><FaBook className="grid-drag-handle" /></Box> */ }
458552 </ HStack >
0 commit comments