From 3c2173de9e5f30a99ddcaca8939a8a52a7559f7e Mon Sep 17 00:00:00 2001 From: Pranshu Chittora Date: Tue, 19 Apr 2022 10:57:56 +0530 Subject: [PATCH] feat: new dashboard widget's option selection (#982) * feat: new dashboard widget's option selection * fix: overflowing legend * feat: delete menu item is of type danger * feat: added keyboard events onFocus and onBlur --- .../GridGraphLayout/Graph/Bar/index.tsx | 39 ------- .../GridGraphLayout/Graph/Bar/styles.ts | 15 --- .../container/GridGraphLayout/Graph/index.tsx | 38 ++++-- .../GridGraphLayout/WidgetHeader/index.tsx | 109 ++++++++++++++++++ .../GridGraphLayout/WidgetHeader/styles.ts | 30 +++++ 5 files changed, 167 insertions(+), 64 deletions(-) delete mode 100644 frontend/src/container/GridGraphLayout/Graph/Bar/index.tsx delete mode 100644 frontend/src/container/GridGraphLayout/Graph/Bar/styles.ts create mode 100644 frontend/src/container/GridGraphLayout/WidgetHeader/index.tsx create mode 100644 frontend/src/container/GridGraphLayout/WidgetHeader/styles.ts diff --git a/frontend/src/container/GridGraphLayout/Graph/Bar/index.tsx b/frontend/src/container/GridGraphLayout/Graph/Bar/index.tsx deleted file mode 100644 index 7214d4839e..0000000000 --- a/frontend/src/container/GridGraphLayout/Graph/Bar/index.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import { - DeleteOutlined, - EditFilled, - FullscreenOutlined, -} from '@ant-design/icons'; -import history from 'lib/history'; -import React from 'react'; -import { Widgets } from 'types/api/dashboard/getAll'; - -import { Container } from './styles'; - -function Bar({ - widget, - onViewFullScreenHandler, - onDeleteHandler, -}: BarProps): JSX.Element { - const onEditHandler = (): void => { - const widgetId = widget.id; - history.push( - `${window.location.pathname}/new?widgetId=${widgetId}&graphType=${widget.panelTypes}`, - ); - }; - - return ( - - - - - - ); -} - -interface BarProps { - widget: Widgets; - onViewFullScreenHandler: () => void; - onDeleteHandler: () => void; -} - -export default Bar; diff --git a/frontend/src/container/GridGraphLayout/Graph/Bar/styles.ts b/frontend/src/container/GridGraphLayout/Graph/Bar/styles.ts deleted file mode 100644 index ca8073a672..0000000000 --- a/frontend/src/container/GridGraphLayout/Graph/Bar/styles.ts +++ /dev/null @@ -1,15 +0,0 @@ -import styled from 'styled-components'; - -export const Container = styled.div` - height: 15%; - align-items: center; - justify-content: flex-end; - display: flex; - gap: 1rem; - padding-right: 1rem; - padding-left: 1rem; - padding-top: 0.5rem; - position: absolute; - top: 0; - right: 0; -`; diff --git a/frontend/src/container/GridGraphLayout/Graph/index.tsx b/frontend/src/container/GridGraphLayout/Graph/index.tsx index 0447cfca94..eb1ed0e2d6 100644 --- a/frontend/src/container/GridGraphLayout/Graph/index.tsx +++ b/frontend/src/container/GridGraphLayout/Graph/index.tsx @@ -20,7 +20,7 @@ import AppActions from 'types/actions'; import { GlobalTime } from 'types/actions/globalTime'; import { Widgets } from 'types/api/dashboard/getAll'; -import Bar from './Bar'; +import WidgetHeader from '../WidgetHeader'; import FullView from './FullView'; import { ErrorContainer, FullViewContainer, Modal } from './styles'; @@ -37,6 +37,7 @@ function GridCardGraph({ error: false, payload: undefined, }); + const [hovered, setHovered] = useState(false); const [modal, setModal] = useState(false); const { minTime, maxTime } = useSelector( (state) => state.globalTime, @@ -171,10 +172,12 @@ function GridCardGraph({ return ( <> {getModals()} - onToggleModal(setModal)} + onToggleModal(setDeletModal)} + onView={(): void => onToggleModal(setModal)} + onDelete={(): void => onToggleModal(setDeletModal)} /> {state.errorMessage} @@ -187,11 +190,26 @@ function GridCardGraph({ } return ( - <> - onToggleModal(setModal)} + { + setHovered(true); + }} + onFocus={(): void => { + setHovered(true); + }} + onMouseOut={(): void => { + setHovered(false); + }} + onBlur={(): void => { + setHovered(false); + }} + > + onToggleModal(setDeletModal)} + onView={(): void => onToggleModal(setModal)} + onDelete={(): void => onToggleModal(setDeletModal)} /> {getModals()} @@ -202,12 +220,12 @@ function GridCardGraph({ data: state.payload, isStacked: widget.isStacked, opacity: widget.opacity, - title: widget.title, + title: ' ', // empty title to accommodate absolutely positioned widget header name, yAxisUnit, }} /> - + ); } diff --git a/frontend/src/container/GridGraphLayout/WidgetHeader/index.tsx b/frontend/src/container/GridGraphLayout/WidgetHeader/index.tsx new file mode 100644 index 0000000000..ce9478d264 --- /dev/null +++ b/frontend/src/container/GridGraphLayout/WidgetHeader/index.tsx @@ -0,0 +1,109 @@ +import { + DeleteOutlined, + DownOutlined, + EditFilled, + FullscreenOutlined, +} from '@ant-design/icons'; +import { Dropdown, Menu, Typography } from 'antd'; +import history from 'lib/history'; +import React, { useState } from 'react'; +import { Widgets } from 'types/api/dashboard/getAll'; + +import { + ArrowContainer, + HeaderContainer, + HeaderContentContainer, + MenuItemContainer, +} from './styles'; + +type TWidgetOptions = 'view' | 'edit' | 'delete' | string; +interface IWidgetHeaderProps { + title: string; + widget: Widgets; + onView: VoidFunction; + onDelete: VoidFunction; + parentHover: boolean; +} +function WidgetHeader({ + title, + widget, + onView, + onDelete, + parentHover, +}: IWidgetHeaderProps): JSX.Element { + const [localHover, setLocalHover] = useState(false); + + const onEditHandler = (): void => { + const widgetId = widget.id; + history.push( + `${window.location.pathname}/new?widgetId=${widgetId}&graphType=${widget.panelTypes}`, + ); + }; + + const keyMethodMapping: { + [K in TWidgetOptions]: { key: TWidgetOptions; method: VoidFunction }; + } = { + view: { + key: 'view', + method: onView, + }, + edit: { + key: 'edit', + method: onEditHandler, + }, + delete: { + key: 'delete', + method: onDelete, + }, + }; + const onMenuItemSelectHandler = ({ key }: { key: TWidgetOptions }): void => { + keyMethodMapping[key]?.method(); + }; + + const menu = ( + + + + View + + + + + Edit + + + + + + Delete + + + + ); + + return ( + + setLocalHover(true)} + onMouseOut={(): void => setLocalHover(false)} + hover={localHover} + > + e.preventDefault()}> + + {title} + + + + + + + + ); +} + +export default WidgetHeader; diff --git a/frontend/src/container/GridGraphLayout/WidgetHeader/styles.ts b/frontend/src/container/GridGraphLayout/WidgetHeader/styles.ts new file mode 100644 index 0000000000..9600a6bcb4 --- /dev/null +++ b/frontend/src/container/GridGraphLayout/WidgetHeader/styles.ts @@ -0,0 +1,30 @@ +import { grey } from '@ant-design/colors'; +import styled from 'styled-components'; + +export const MenuItemContainer = styled.div` + display: flex; + justify-content: space-between; + align-items: center; +`; + +export const HeaderContainer = styled.div<{ hover: boolean }>` + width: 100%; + text-align: center; + background: ${({ hover }): string => (hover ? `${grey[0]}66` : 'inherit')}; + padding: 0.25rem 0; + font-size: 0.8rem; + cursor: all-scroll; + position: absolute; +`; + +export const HeaderContentContainer = styled.span` + cursor: pointer; + position: relative; + text-align: center; +`; + +export const ArrowContainer = styled.span<{ hover: boolean }>` + visibility: ${({ hover }): string => (hover ? 'visible' : 'hidden')}; + position: absolute; + right: -1rem; +`;