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,108 @@ 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+ < PopoverTrigger >
449+ < Box position = "absolute" top = "5px" left = "5px" opacity = "0.5" fontSize = "0.8rem" zIndex = { 1000 } cursor = "pointer" > < FaRegClock /> </ Box >
450+ </ PopoverTrigger >
451+ < PopoverContent >
452+ < PanelDatePicker id = { panel . id . toString ( ) } timeRange = { panel . scopeTime } onChange = { tr => {
453+ panel . scopeTime = tr
454+ dispatch ( {
455+ type : UpdatePanelEvent ,
456+ data : cloneDeep ( panel )
457+ } )
458+ } } showIcon />
459+ </ PopoverContent >
460+ </ Popover >
461+ </ >
462+ )
463+ }
464+ < Center width = "100%" >
465+ { ! isEmpty ( title ) ?
466+ < Box
467+ display = { 'flex' }
468+ justifyContent = { 'center' }
469+ // cursor="pointer"
470+ paddingTop = { panel . styles . title . paddingTop }
471+ paddingBottom = { panel . styles . title . paddingBottom }
472+ paddingLeft = { panel . styles . title . paddingLeft }
473+ paddingRight = { panel . styles . title . paddingRight }
474+ width = "100%"
475+ fontSize = { panel . styles . title . fontSize }
476+ fontWeight = { panel . styles . title . fontWeight }
477+ color = { paletteColorNameToHex ( panel . styles . title . color , colorMode ) } >
478+ < TitleDecoration styles = { panel . styles } >
479+ < Text noOfLines = { 1 } >
480+ { title }
481+ </ Text >
482+ </ TitleDecoration >
483+ </ Box > : < Box width = "100px" > </ Box > }
484+ </ Center >
485+ < Box visibility = { 'hidden' } className = "show-on-hover" >
486+ < Menu placement = "bottom" isLazy >
487+ < MenuButton
488+ background = { useColorModeValue ( customColors . bodyBg . light , customColors . bodyBg . dark ) }
489+ transition = 'all 0.2s'
490+ _focus = { { border : null } }
491+ onClick = { e => e . stopPropagation ( ) }
492+ disabled = { embed }
493+ cursor = { 'pointer' }
494+ as = { IconButton }
495+ aria-label = 'Options'
496+ icon = {
497+ < Box
498+ fontSize = { panel . styles . title . fontSize }
499+ fontWeight = { panel . styles . title . fontWeight }
500+ color = { paletteColorNameToHex ( panel . styles . title . color , colorMode ) }
501+ >
502+ < FaEllipsisV />
503+ </ Box > }
504+ size = { 'sm' }
505+ variant = { 'none' }
506+ >
507+ < Center width = "100%" >
508+ {
509+ ! isEmpty ( title )
510+ ?
511+ < Box
512+ cursor = "pointer"
513+ className = "hover-bordered"
514+ paddingTop = { panel . styles . title . paddingTop }
515+ paddingBottom = { panel . styles . title . paddingBottom }
516+ paddingLeft = { panel . styles . title . paddingLeft }
517+ paddingRight = { panel . styles . title . paddingRight } width = "100%"
518+ fontSize = { panel . styles . title . fontSize }
519+ fontWeight = { panel . styles . title . fontWeight }
520+ color = { paletteColorNameToHex ( panel . styles . title . color , colorMode ) }
521+ >
522+ < TitleDecoration styles = { panel . styles } >
523+ < Text noOfLines = { 1 } > { title } </ Text >
524+ </ TitleDecoration >
525+ </ Box >
526+ :
527+ < Box width = "100px" > </ Box >
528+ }
529+ </ Center >
530+ </ MenuButton >
531+
532+ < MenuList p = "1" zIndex = { 1500 } rootProps = { { fontSize : "sm" } } >
439533 < MenuItem icon = { < FaEdit /> } onClick = { ( ) => addParamToUrl ( { edit : panel . id } ) } > { t . edit } </ MenuItem >
440534 < MenuItem icon = { < FaRegCopy /> } onClick = { ( ) => onCopyPanel ( panel , "copy" ) } > { t . copy } </ MenuItem >
441535 < MenuItem icon = { < FaRegClone /> } onClick = { ( ) => onCopyPanel ( panel , "clone" ) } > { t . clone } </ MenuItem >
442536 < MenuDivider my = "1" />
443537 < MenuItem icon = { < FaBug /> } onClick = { onOpen } > { t1 . debugPanel } </ MenuItem >
444538 < MenuItem icon = { < FaRegEye /> } onClick = { ( ) => addParamToUrl ( { viewPanel : viewPanel ? null : panel . id } ) } > { viewPanel ? t1 . exitlView : t1 . viewPanel } </ MenuItem >
445-
446539 { ! viewPanel && < >
447540 < MenuDivider my = "1" />
448541 < MenuItem icon = { < FaRegEyeSlash /> } onClick = { ( ) => onHidePanel ( panel ) } > { t1 . hidePanel } </ MenuItem >
@@ -451,8 +544,8 @@ const PanelHeader = ({ dashboardId, queryError, panel, onCopyPanel, onRemovePane
451544
452545 </ > }
453546 </ MenuList >
454- </ Portal >
455- </ Menu >
547+ </ Menu >
548+ </ Box >
456549 </ Center >
457550 { /* <Box display="none"><FaBook className="grid-drag-handle" /></Box> */ }
458551 </ HStack >
0 commit comments