From 2ea07b045aff73f1bb07d46119123ee812003dae Mon Sep 17 00:00:00 2001 From: Shekar Siri Date: Wed, 26 Jun 2024 10:13:06 +0200 Subject: [PATCH] change(ui): dashboard redesign --- .../components/AddCardSelectionModal.tsx | 8 +-- .../components/AddToDashboardButton.tsx | 71 +++++++++++++------ .../NewDashModal/CardsLibrary.tsx | 22 ++++-- .../NewDashModal/NewDashboardModal.tsx | 12 ++-- .../DashboardList/NewDashModal/SelectCard.tsx | 71 +++++++++++++------ .../DashboardSelectionModal.tsx | 27 +++---- .../components/FilterSeries/FilterSeries.tsx | 2 +- .../components/WidgetChart/WidgetChart.tsx | 1 - .../components/WidgetView/WidgetView.tsx | 2 +- .../WidgetView/WidgetViewHeader.tsx | 66 +++++++++++++++-- .../components/WidgetWrapper/AlertButton.tsx | 19 +++-- .../components/WidgetWrapper/CardMenu.tsx | 48 +++++++++++++ .../WidgetWrapper/WidgetWrapperNew.tsx | 30 ++------ frontend/app/mstore/types/widget.ts | 2 - 14 files changed, 262 insertions(+), 119 deletions(-) create mode 100644 frontend/app/components/Dashboard/components/WidgetWrapper/CardMenu.tsx diff --git a/frontend/app/components/Dashboard/components/AddCardSelectionModal.tsx b/frontend/app/components/Dashboard/components/AddCardSelectionModal.tsx index f427082fa..649122170 100644 --- a/frontend/app/components/Dashboard/components/AddCardSelectionModal.tsx +++ b/frontend/app/components/Dashboard/components/AddCardSelectionModal.tsx @@ -1,6 +1,6 @@ import React from 'react'; import {Card, Col, Modal, Row, Typography} from "antd"; -import {Grid2X2, Plus} from "lucide-react"; +import {Grid2x2CheckIcon, Plus} from "lucide-react"; import NewDashboardModal from "Components/Dashboard/components/DashboardList/NewDashModal"; interface Props { @@ -32,8 +32,8 @@ function AddCardSelectionModal(props: Props) { onClick(true)}> -
- +
+ Add from library

Select from 12 available

@@ -41,7 +41,7 @@ function AddCardSelectionModal(props: Props) { onClick(false)}> -
+

Create New Card

diff --git a/frontend/app/components/Dashboard/components/AddToDashboardButton.tsx b/frontend/app/components/Dashboard/components/AddToDashboardButton.tsx index 84f9f7fa3..c7139afb3 100644 --- a/frontend/app/components/Dashboard/components/AddToDashboardButton.tsx +++ b/frontend/app/components/Dashboard/components/AddToDashboardButton.tsx @@ -1,32 +1,63 @@ import React from 'react'; -import DashboardSelectionModal from "Components/Dashboard/components/DashboardSelectionModal/DashboardSelectionModal"; import {Grid2x2Check} from "lucide-react" -import {Button} from "antd"; +import {Button, Modal} from "antd"; +import Select from "Shared/Select/Select"; +import {Form} from "UI"; +import {useStore} from "App/mstore"; interface Props { metricId: string; } function AddToDashboardButton({metricId}: Props) { - const [show, setShow] = React.useState(false); + const {dashboardStore} = useStore(); + const dashboardOptions = dashboardStore.dashboards.map((i: any) => ({ + key: i.id, + label: i.name, + value: i.dashboardId, + })); + const [selectedId, setSelectedId] = React.useState(dashboardOptions[0].value); + + const onSave = (close: any) => { + const dashboard = dashboardStore.getDashboard(selectedId) + if (dashboard) { + dashboardStore.addWidgetToDashboard(dashboard, [metricId]).then(close) + } + } + + const onClick = () => { + Modal.confirm({ + title: 'Add to selected dashboard', + icon: null, + content: ( + + setSelectedId(value.value)} + onChange={({value}: any) => setSelectedId(value.value)} /> - + - + )); } diff --git a/frontend/app/components/Dashboard/components/FilterSeries/FilterSeries.tsx b/frontend/app/components/Dashboard/components/FilterSeries/FilterSeries.tsx index 45ef923bf..36eb148f3 100644 --- a/frontend/app/components/Dashboard/components/FilterSeries/FilterSeries.tsx +++ b/frontend/app/components/Dashboard/components/FilterSeries/FilterSeries.tsx @@ -91,7 +91,7 @@ function FilterSeries(props: Props) { canExclude = false, expandable = false } = props; - const [expanded, setExpanded] = useState(false); + const [expanded, setExpanded] = useState(!expandable); const {series, seriesIndex} = props; const onUpdateFilter = (filterIndex: any, filter: any) => { diff --git a/frontend/app/components/Dashboard/components/WidgetChart/WidgetChart.tsx b/frontend/app/components/Dashboard/components/WidgetChart/WidgetChart.tsx index 15376eb1c..32c63c5e6 100644 --- a/frontend/app/components/Dashboard/components/WidgetChart/WidgetChart.tsx +++ b/frontend/app/components/Dashboard/components/WidgetChart/WidgetChart.tsx @@ -97,7 +97,6 @@ function WidgetChart(props: Props) { if (!isMounted()) return; setLoading(true); dashboardStore.fetchMetricChartData(metric, payload, isWidget, period).then((res: any) => { - console.log('res', res) if (isMounted()) setData(res); }).finally(() => { setLoading(false); diff --git a/frontend/app/components/Dashboard/components/WidgetView/WidgetView.tsx b/frontend/app/components/Dashboard/components/WidgetView/WidgetView.tsx index b1f00c057..02e586420 100644 --- a/frontend/app/components/Dashboard/components/WidgetView/WidgetView.tsx +++ b/frontend/app/components/Dashboard/components/WidgetView/WidgetView.tsx @@ -57,7 +57,7 @@ function WidgetView(props: Props) { React.useEffect(() => { if (metricId && metricId !== 'create') { metricStore.fetch(metricId, dashboardStore.period).catch((e) => { - if (e.status === 404 || e.status === 422) { + if (e.response.status === 404 || e.response.status === 422) { setMetricNotFound(true); } }); diff --git a/frontend/app/components/Dashboard/components/WidgetView/WidgetViewHeader.tsx b/frontend/app/components/Dashboard/components/WidgetView/WidgetViewHeader.tsx index d54528e9b..4fc81338a 100644 --- a/frontend/app/components/Dashboard/components/WidgetView/WidgetViewHeader.tsx +++ b/frontend/app/components/Dashboard/components/WidgetView/WidgetViewHeader.tsx @@ -5,7 +5,10 @@ import {useStore} from "App/mstore"; import {useObserver} from "mobx-react-lite"; import AddToDashboardButton from "Components/Dashboard/components/AddToDashboardButton"; import WidgetDateRange from "Components/Dashboard/components/WidgetDateRange/WidgetDateRange"; -import {Button, Space} from "antd"; +import {Button, Dropdown, MenuProps, Space, message, Modal} from "antd"; +import {BellIcon, EllipsisVertical, TrashIcon} from "lucide-react"; +import {useHistory} from "react-router"; +import {toast} from "react-toastify"; interface Props { onClick?: () => void; @@ -31,16 +34,69 @@ function WidgetViewHeader({onClick, onSave, undoChanges}: Props) { +
); } export default WidgetViewHeader; + +const CardViewMenu = () => { + const history = useHistory(); + const {dashboardStore, metricStore} = useStore(); + const widget = useObserver(() => metricStore.instance); + const items: MenuProps['items'] = [ + { + key: 'alert', + label: "Set Alerts", + icon: , + }, + { + key: 'remove', + danger: true, + label: 'Remove', + icon: , + }, + ]; + + const onClick: MenuProps['onClick'] = ({key}) => { + if (key === 'alert') { + message.info('Set Alerts'); + } else if (key === 'remove') { + Modal.confirm({ + title: 'Are you sure you want to remove this card?', + icon: null, + // content: 'Bla bla ...', + footer: (_, {OkBtn, CancelBtn}) => ( + <> + + + + ), + onOk: () => { + metricStore.delete(widget).then(r => { + history.goBack(); + }).catch(() => { + toast.error('Failed to remove card'); + }); + }, + }) + } + }; + + return ( +
+ +
+ ); +}; diff --git a/frontend/app/components/Dashboard/components/WidgetWrapper/AlertButton.tsx b/frontend/app/components/Dashboard/components/WidgetWrapper/AlertButton.tsx index 0b50abdd4..6ff3ddda0 100644 --- a/frontend/app/components/Dashboard/components/WidgetWrapper/AlertButton.tsx +++ b/frontend/app/components/Dashboard/components/WidgetWrapper/AlertButton.tsx @@ -1,26 +1,23 @@ import React from 'react'; import WidgetIcon from './WidgetIcon'; -import { useStore } from 'App/mstore'; +import {useStore} from 'App/mstore'; +import {Button} from "antd"; +import {BellIcon} from "lucide-react"; interface Props { seriesId: string; initAlert?: Function; } + function AlertButton(props: Props) { - const { seriesId } = props; - const { dashboardStore, alertsStore } = useStore(); + const {seriesId} = props; + const {dashboardStore, alertsStore} = useStore(); const onClick = () => { dashboardStore.toggleAlertModal(true); - alertsStore.init({ query: { left: seriesId }}) + alertsStore.init({query: {left: seriesId}}) } return ( -
- -
+
+ ); +} + +export default CardMenu; diff --git a/frontend/app/components/Dashboard/components/WidgetWrapper/WidgetWrapperNew.tsx b/frontend/app/components/Dashboard/components/WidgetWrapper/WidgetWrapperNew.tsx index b1fd54cd4..8fb7bec07 100644 --- a/frontend/app/components/Dashboard/components/WidgetWrapper/WidgetWrapperNew.tsx +++ b/frontend/app/components/Dashboard/components/WidgetWrapper/WidgetWrapperNew.tsx @@ -1,7 +1,6 @@ import React, {useRef} from 'react'; import cn from 'classnames'; import {Card, Tooltip, Button} from 'antd'; -import {ItemMenu, TextEllipsis} from 'UI'; import {useDrag, useDrop} from 'react-dnd'; import WidgetChart from '../WidgetChart'; import {observer} from 'mobx-react-lite'; @@ -9,11 +8,12 @@ import {useStore} from 'App/mstore'; import {withRouter, RouteComponentProps} from 'react-router-dom'; import {withSiteId, dashboardMetricDetails} from 'App/routes'; import TemplateOverlay from './TemplateOverlay'; -import AlertButton from './AlertButton'; import stl from './widgetWrapper.module.css'; import {FilterKey} from 'App/types/filter/filterType'; import LazyLoad from 'react-lazyload'; import {TIMESERIES} from "App/constants/card"; +import CardMenu from "Components/Dashboard/components/WidgetWrapper/CardMenu"; +import AlertButton from "Components/Dashboard/components/WidgetWrapper/AlertButton"; interface Props { className?: string; @@ -74,10 +74,6 @@ function WidgetWrapperNew(props: Props & RouteComponentProps) { }), }); - const onDelete = async () => { - dashboardStore.deleteDashboardWidget(dashboard?.dashboardId!, widget.widgetId); - }; - const onChartClick = () => { if (!isWidget || isPredefined) return; props.history.push( @@ -114,29 +110,11 @@ function WidgetWrapperNew(props: Props & RouteComponentProps) { extra={isWidget ? [
{!isPredefined && isTimeSeries && !isGridView && ( - <> - -
- + )} {!isTemplate && !isGridView && ( - + )}
] : []} diff --git a/frontend/app/mstore/types/widget.ts b/frontend/app/mstore/types/widget.ts index 283b895d6..d93ebedda 100644 --- a/frontend/app/mstore/types/widget.ts +++ b/frontend/app/mstore/types/widget.ts @@ -295,8 +295,6 @@ export default class Widget { } else if (this.metricType === TABLE) { const totalSessions = data[0]['totalSessions']; _data[0]['values'] = data[0]['values'].map((s: any) => new SessionsByRow().fromJson(s, totalSessions, this.metricOf)); - - console.log('_data[\'values\']', _data['values']) } else { if (data.hasOwnProperty('chart')) { _data['value'] = data.value;