From b0785d14350324c23ab6626e1ec8eb5d09cc5278 Mon Sep 17 00:00:00 2001 From: Shekar Siri Date: Mon, 17 Jun 2024 14:28:58 +0200 Subject: [PATCH] feature(ui): new dashboard modal --- .../DashboardList/NewDashModal/CreateCard.tsx | 94 ++++++ .../NewDashModal/Examples/Count.tsx | 7 +- .../NewDashModal/Examples/ExCard.tsx | 4 +- .../NewDashModal/Examples/Funnel.tsx | 7 +- .../NewDashModal/Examples/Path.tsx | 90 +++--- .../NewDashModal/Examples/PerfBreakdown.tsx | 7 +- .../Examples/SessionsBy/ByBrowser.tsx | 6 +- .../Examples/SessionsBy/ByCountry.tsx | 6 +- .../Examples/SessionsBy/BySystem.tsx | 6 +- .../Examples/SessionsBy/ByUrl.tsx | 7 +- .../Examples/SessionsByErrors.tsx | 8 +- .../Examples/SessionsByIssues.tsx | 8 +- .../NewDashModal/Examples/SlowestDomain.tsx | 6 +- .../Examples/Tabs/CoreWebVitals.tsx | 20 ++ .../Examples/Tabs/PerformanceMonitoring.tsx | 20 ++ .../Examples/Tabs/ProductAnalytics.tsx | 20 ++ .../Examples/Tabs/WebAnalytics.tsx | 20 ++ .../NewDashModal/Examples/Trend.tsx | 9 +- .../NewDashModal/NewDashboardModal.tsx | 51 +++ .../DashboardList/NewDashModal/Option.tsx | 16 + .../DashboardList/NewDashModal/SelectCard.tsx | 228 ++++++++++++++ .../DashboardList/NewDashModal/index.ts | 1 + .../DashboardList/NewDashModal/index.tsx | 174 ----------- .../components/WidgetForm/CardBuilder.tsx | 292 ++++++++++++++++++ 24 files changed, 840 insertions(+), 267 deletions(-) create mode 100644 frontend/app/components/Dashboard/components/DashboardList/NewDashModal/CreateCard.tsx create mode 100644 frontend/app/components/Dashboard/components/DashboardList/NewDashModal/Examples/Tabs/CoreWebVitals.tsx create mode 100644 frontend/app/components/Dashboard/components/DashboardList/NewDashModal/Examples/Tabs/PerformanceMonitoring.tsx create mode 100644 frontend/app/components/Dashboard/components/DashboardList/NewDashModal/Examples/Tabs/ProductAnalytics.tsx create mode 100644 frontend/app/components/Dashboard/components/DashboardList/NewDashModal/Examples/Tabs/WebAnalytics.tsx create mode 100644 frontend/app/components/Dashboard/components/DashboardList/NewDashModal/NewDashboardModal.tsx create mode 100644 frontend/app/components/Dashboard/components/DashboardList/NewDashModal/Option.tsx create mode 100644 frontend/app/components/Dashboard/components/DashboardList/NewDashModal/SelectCard.tsx create mode 100644 frontend/app/components/Dashboard/components/DashboardList/NewDashModal/index.ts delete mode 100644 frontend/app/components/Dashboard/components/DashboardList/NewDashModal/index.tsx create mode 100644 frontend/app/components/Dashboard/components/WidgetForm/CardBuilder.tsx diff --git a/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/CreateCard.tsx b/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/CreateCard.tsx new file mode 100644 index 000000000..0444d163c --- /dev/null +++ b/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/CreateCard.tsx @@ -0,0 +1,94 @@ +import React from 'react'; +import {Button, Space} from "antd"; +import {ArrowLeft, ArrowRight} from "lucide-react"; +import CardBuilder from "Components/Dashboard/components/WidgetForm/CardBuilder"; +import {useHistory} from "react-router"; +import {useStore} from "App/mstore"; +import {CLICKMAP} from "App/constants/card"; +import {renderClickmapThumbnail} from "Components/Dashboard/components/WidgetForm/renderMap"; +import WidgetPreview from "Components/Dashboard/components/WidgetPreview/WidgetPreview"; + +const getTitleByType = (type: string) => { + switch (type) { + case CLICKMAP: + return 'Clickmap'; + default: + return 'Trend Single'; + } +} + +interface Props { + // cardType: string, + onBack: () => void +} + +function CreateCard(props: Props) { + const history = useHistory(); + const {metricStore, dashboardStore, aiFiltersStore} = useStore(); + const metric = metricStore.instance; + const siteId = history.location.pathname.split('/')[1]; + // const title = getTitleByType(metric.metricType) + + + const createNewDashboard = async () => { + dashboardStore.initDashboard(); + return await dashboardStore + .save(dashboardStore.dashboardInstance) + .then(async (syncedDashboard) => { + dashboardStore.selectDashboardById(syncedDashboard.dashboardId); + return syncedDashboard.dashboardId; + }); + } + + const addCardToDashboard = async (dashboardId: string, metricId: string) => { + return dashboardStore.addWidgetToDashboard( + dashboardStore.getDashboard(parseInt(dashboardId, 10))!, [metricId] + ); + } + + const createCard = async () => { + const isClickmap = metric.metricType === CLICKMAP; + if (isClickmap) { + try { + metric.thumbnail = await renderClickmapThumbnail(); + } catch (e) { + console.error(e); + } + } + + const savedMetric = await metricStore.save(metric); + return savedMetric.metricId; + } + + const createDashboardAndAddCard = async () => { + const dashboardId = await createNewDashboard(); + const cardId = await createCard(); + await addCardToDashboard(dashboardId, cardId); + + history.replace(`${history.location.pathname}/${dashboardId}`); + } + + return ( +
+
+ + +
+ {metric.name} +
+
+ +
+ + +
+ ); +} + +export default CreateCard; diff --git a/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/Examples/Count.tsx b/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/Examples/Count.tsx index 7a6543654..1f21a6c9a 100644 --- a/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/Examples/Count.tsx +++ b/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/Examples/Count.tsx @@ -16,7 +16,7 @@ const TYPES = { Users: 'users', }; -function ExampleCount({ onCard }: { onCard: (card: string) => void }) { +function ExampleCount(props: any) { const [type, setType] = React.useState(TYPES.Frustrations); const el = { @@ -26,11 +26,10 @@ function ExampleCount({ onCard }: { onCard: (card: string) => void }) { }; return ( -
Sessions by
+
{props.title}
{title}
onCard(type)}>{children}
@@ -22,4 +22,4 @@ function ExCard({ ); } -export default ExCard \ No newline at end of file +export default ExCard diff --git a/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/Examples/Funnel.tsx b/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/Examples/Funnel.tsx index 5e9f41f87..f8c0c361a 100644 --- a/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/Examples/Funnel.tsx +++ b/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/Examples/Funnel.tsx @@ -2,8 +2,9 @@ import { ArrowRight } from 'lucide-react'; import React from 'react'; import ExCard from './ExCard'; +import {FUNNEL} from "App/constants/card"; -function ExampleFunnel({ onCard }: { onCard: (card: string) => void }) { +function ExampleFunnel(props: any) { const steps = [ { progress: 500, @@ -17,9 +18,7 @@ function ExampleFunnel({ onCard }: { onCard: (card: string) => void }) { ]; return ( <> {steps.map((step, index) => ( diff --git a/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/Examples/Path.tsx b/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/Examples/Path.tsx index 52fd9c31a..70044e102 100644 --- a/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/Examples/Path.tsx +++ b/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/Examples/Path.tsx @@ -1,59 +1,59 @@ import React from 'react'; -import { ResponsiveContainer, Sankey } from 'recharts'; +import {ResponsiveContainer, Sankey} from 'recharts'; import CustomLink from 'App/components/shared/Insights/SankeyChart/CustomLink'; import CustomNode from 'App/components/shared/Insights/SankeyChart/CustomNode'; import ExCard from './ExCard'; +import {USER_PATH} from "App/constants/card"; -function ExamplePath({ onCard }: { onCard: (card: string) => void }) { - const data = { - nodes: [ - { idd: 0, name: 'Home' }, - { idd: 1, name: 'Google' }, - { idd: 2, name: 'Facebook' }, - { idd: 3, name: 'Search' }, - { idd: 4, name: 'Product' }, - { idd: 5, name: 'Chart' }, - ], - links: [ - { source: 0, target: 3, value: 40 }, - { source: 0, target: 4, value: 60 }, +function ExamplePath(props: any) { + const data = { + nodes: [ + {idd: 0, name: 'Home'}, + {idd: 1, name: 'Google'}, + {idd: 2, name: 'Facebook'}, + {idd: 3, name: 'Search'}, + {idd: 4, name: 'Product'}, + {idd: 5, name: 'Chart'}, + ], + links: [ + {source: 0, target: 3, value: 40}, + {source: 0, target: 4, value: 60}, - { source: 1, target: 3, value: 100 }, - { source: 2, target: 3, value: 100 }, + {source: 1, target: 3, value: 100}, + {source: 2, target: 3, value: 100}, - { source: 3, target: 4, value: 50 }, - { source: 3, target: 5, value: 50 }, + {source: 3, target: 4, value: 50}, + {source: 3, target: 5, value: 50}, - { source: 4, target: 5, value: 15 }, - ], - }; - return ( - - - } - link={(linkProps) => } - data={data} + {source: 4, target: 5, value: 15}, + ], + }; + + return ( + - - - - - - - - - - ); + + } + link={(linkProps) => } + data={data} + > + + + + + + + + + + ); } export default ExamplePath diff --git a/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/Examples/PerfBreakdown.tsx b/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/Examples/PerfBreakdown.tsx index d070b10e4..0bb569006 100644 --- a/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/Examples/PerfBreakdown.tsx +++ b/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/Examples/PerfBreakdown.tsx @@ -2,8 +2,9 @@ import { GitCommitHorizontal } from 'lucide-react'; import React from 'react'; import ExCard from './ExCard'; +import {PERFORMANCE} from "App/constants/card"; -function PerfBreakdown({ onCard }: { onCard: (card: string) => void }) { +function PerfBreakdown(props: any) { const rows = [ ['5K', '1K'], ['4K', '750'], @@ -22,9 +23,7 @@ function PerfBreakdown({ onCard }: { onCard: (card: string) => void }) { const bgs = ['#E2E4F6', '#A7BFFF', '#394EFF']; return (
diff --git a/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/Examples/SessionsBy/ByBrowser.tsx b/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/Examples/SessionsBy/ByBrowser.tsx index 2416c7768..3f83e8e0a 100644 --- a/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/Examples/SessionsBy/ByBrowser.tsx +++ b/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/Examples/SessionsBy/ByBrowser.tsx @@ -5,7 +5,7 @@ import { Icon } from 'UI'; import ExCard from '../ExCard'; import ByComponent from './Component'; -function ByBrowser({ onCard }: { onCard: (card: string) => void }) { +function ByBrowser(props: any) { const rows = [ { label: 'Chrome', @@ -42,9 +42,7 @@ function ByBrowser({ onCard }: { onCard: (card: string) => void }) { const lineWidth = 200; return ( diff --git a/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/Examples/SessionsBy/ByCountry.tsx b/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/Examples/SessionsBy/ByCountry.tsx index 920258f6e..61381824b 100644 --- a/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/Examples/SessionsBy/ByCountry.tsx +++ b/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/Examples/SessionsBy/ByCountry.tsx @@ -4,7 +4,7 @@ import { Icon } from 'UI'; import ByComponent from './Component'; -function ByCountry({ onCard }: { onCard: (card: string) => void }) { +function ByCountry(props: any) { const rows = [ { label: 'United States', @@ -41,10 +41,8 @@ function ByCountry({ onCard }: { onCard: (card: string) => void }) { return ( ); } diff --git a/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/Examples/SessionsBy/BySystem.tsx b/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/Examples/SessionsBy/BySystem.tsx index 5700d568f..21a138315 100644 --- a/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/Examples/SessionsBy/BySystem.tsx +++ b/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/Examples/SessionsBy/BySystem.tsx @@ -4,7 +4,7 @@ import { Icon } from 'UI'; import ByComponent from './Component'; -function BySystem({ onCard }: { onCard: (card: string) => void }) { +function BySystem(props: any) { const rows = [ { label: 'Windows', @@ -41,9 +41,7 @@ function BySystem({ onCard }: { onCard: (card: string) => void }) { const lineWidth = 200; return ( diff --git a/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/Examples/SessionsBy/ByUrl.tsx b/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/Examples/SessionsBy/ByUrl.tsx index f648beef9..1b2de44e2 100644 --- a/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/Examples/SessionsBy/ByUrl.tsx +++ b/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/Examples/SessionsBy/ByUrl.tsx @@ -5,7 +5,7 @@ import React from 'react'; import { Circle } from '../Count'; import ExCard from '../ExCard'; -function ByUrl({ onCard }: { onCard: (card: string) => void }) { +function ByUrl(props: any) { const [mode, setMode] = React.useState(0); const rows = [ { @@ -48,11 +48,10 @@ function ByUrl({ onCard }: { onCard: (card: string) => void }) { const lineWidth = 240; return ( -
Sessions by
+
{props.title}
void }) { +function SessionsByErrors(props: any) { return ( ); } -export default SessionsByErrors \ No newline at end of file +export default SessionsByErrors diff --git a/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/Examples/SessionsByIssues.tsx b/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/Examples/SessionsByIssues.tsx index 044f4c4c3..ab8ec58c2 100644 --- a/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/Examples/SessionsByIssues.tsx +++ b/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/Examples/SessionsByIssues.tsx @@ -2,16 +2,14 @@ import React from 'react' import ExCard from "./ExCard"; import { Frustrations } from "./Count"; -function SessionsByIssues({ onCard }: { onCard: (card: string) => void }) { +function SessionsByIssues(props: any) { return ( ); } -export default SessionsByIssues \ No newline at end of file +export default SessionsByIssues diff --git a/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/Examples/SlowestDomain.tsx b/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/Examples/SlowestDomain.tsx index 3f055b078..d39062eb2 100644 --- a/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/Examples/SlowestDomain.tsx +++ b/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/Examples/SlowestDomain.tsx @@ -4,7 +4,7 @@ import React from 'react'; import { Circle } from './Count'; import ExCard from './ExCard'; -function SlowestDomain({ onCard }: { onCard: (card: string) => void }) { +function SlowestDomain(props: any) { const rows = [ { label: 'kroger.com', @@ -42,9 +42,7 @@ function SlowestDomain({ onCard }: { onCard: (card: string) => void }) { return (
{rows.map((r) => ( diff --git a/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/Examples/Tabs/CoreWebVitals.tsx b/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/Examples/Tabs/CoreWebVitals.tsx new file mode 100644 index 000000000..3cd3d7603 --- /dev/null +++ b/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/Examples/Tabs/CoreWebVitals.tsx @@ -0,0 +1,20 @@ +import React from 'react'; +import PerfBreakdown from '../PerfBreakdown'; +import SlowestDomain from '../SlowestDomain'; +import SessionsByIssues from '../SessionsByIssues'; +import SessionsByErrors from '../SessionsByErrors'; + +interface ExampleProps { + onCard: (card: string) => void; +} + +const CoreWebVitals: React.FC = ({onCard}) => ( + <> + + + + + +); + +export default CoreWebVitals; diff --git a/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/Examples/Tabs/PerformanceMonitoring.tsx b/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/Examples/Tabs/PerformanceMonitoring.tsx new file mode 100644 index 000000000..2836f706a --- /dev/null +++ b/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/Examples/Tabs/PerformanceMonitoring.tsx @@ -0,0 +1,20 @@ +import React from 'react'; +import PerfBreakdown from '../PerfBreakdown'; +import SlowestDomain from '../SlowestDomain'; +import SessionsByErrors from '../SessionsByErrors'; +import SessionsByIssues from '../SessionsByIssues'; + +interface ExampleProps { + onCard: (card: string) => void; +} + +const PerformanceMonitoring: React.FC = ({onCard}) => ( + <> + + + + + +); + +export default PerformanceMonitoring; diff --git a/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/Examples/Tabs/ProductAnalytics.tsx b/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/Examples/Tabs/ProductAnalytics.tsx new file mode 100644 index 000000000..d0f0c1caf --- /dev/null +++ b/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/Examples/Tabs/ProductAnalytics.tsx @@ -0,0 +1,20 @@ +import React from 'react'; +import ExampleFunnel from '../Funnel'; +import ExamplePath from '../Path'; +import ExampleTrend from '../Trend'; +import ExampleCount from '../Count'; + +interface ExampleProps { + onCard: (card: string) => void; +} + +const ProductAnalytics: React.FC = ({ onCard }) => ( + <> + + + + + +); + +export default ProductAnalytics; diff --git a/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/Examples/Tabs/WebAnalytics.tsx b/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/Examples/Tabs/WebAnalytics.tsx new file mode 100644 index 000000000..3fef1ab7a --- /dev/null +++ b/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/Examples/Tabs/WebAnalytics.tsx @@ -0,0 +1,20 @@ +import React from 'react'; +import ByBrowser from '../SessionsBy/ByBrowser'; +import BySystem from '../SessionsBy/BySystem'; +import ByCountry from '../SessionsBy/ByCountry'; +import ByUrl from '../SessionsBy/ByUrl'; + +interface ExampleProps { + onCard: (card: string) => void; +} + +const WebAnalytics: React.FC = ({onCard}) => ( + <> + + + + + +); + +export default WebAnalytics; diff --git a/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/Examples/Trend.tsx b/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/Examples/Trend.tsx index c9b925ba9..5de714619 100644 --- a/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/Examples/Trend.tsx +++ b/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/Examples/Trend.tsx @@ -3,18 +3,19 @@ import React from 'react'; import ExCard from './ExCard'; -function ExampleTrend({ onCard }: { onCard: (card: string) => void }) { +function ExampleTrend(props: any) { const rows = [50, 40, 30, 20, 10]; const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May']; const [isMulti, setIsMulti] = React.useState(false); return ( -
Trend
+
{props.title}
void; + open: boolean; +} + +const NewDashboardModal: React.FC = ({onClose, open}) => { + const [step, setStep] = React.useState(0); + const [selectedCard, setSelectedCard] = React.useState('trend-single'); + const {metricStore} = useStore(); + + const onCard = (card: any) => { + setStep(step + 1); + // setSelectedCard(card); + // console.log('Selected card:', card) + console.log('Selected card:', card) + metricStore.merge({ + name: card.title, + }); + metricStore.changeType(card.cardType); + }; + + const [modalOpen, setModalOpen] = React.useState(false); + + useEffect(() => { + return () => { + setStep(1); + } + }, [open]); + + return ( + <> + +
+
+ {step === 0 && } + {step === 1 && setStep(0)}/>} +
+
+
+ + ); +}; + +export default NewDashboardModal; diff --git a/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/Option.tsx b/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/Option.tsx new file mode 100644 index 000000000..7c08512ca --- /dev/null +++ b/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/Option.tsx @@ -0,0 +1,16 @@ +import React from 'react'; +import {LucideIcon} from "lucide-react"; + +interface OptionProps { + label: string; + Icon: LucideIcon; +} + +const Option: React.FC = ({label, Icon}) => ( +
+ +
{label}
+
+); + +export default Option; diff --git a/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/SelectCard.tsx b/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/SelectCard.tsx new file mode 100644 index 000000000..0e4af66f3 --- /dev/null +++ b/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/SelectCard.tsx @@ -0,0 +1,228 @@ +import React, {useMemo} from 'react'; +import {Segmented} from 'antd'; +import Option from './Option'; +// import ProductAnalytics from './Examples/ProductAnalytics'; +// import PerformanceMonitoring from './Examples/PerformanceMonitoring'; +// import WebAnalytics from './Examples/WebAnalytics'; +// import CoreWebVitals from './Examples/CoreWebVitals'; +import {TrendingUp, Activity, BarChart, TableCellsMerge} from "lucide-react"; +import ExampleFunnel from "Components/Dashboard/components/DashboardList/NewDashModal/Examples/Funnel"; +import ExamplePath from "Components/Dashboard/components/DashboardList/NewDashModal/Examples/Path"; +import ExampleTrend from "Components/Dashboard/components/DashboardList/NewDashModal/Examples/Trend"; +import ExampleCount from "Components/Dashboard/components/DashboardList/NewDashModal/Examples/Count"; +import PerfBreakdown from "Components/Dashboard/components/DashboardList/NewDashModal/Examples/PerfBreakdown"; +import SlowestDomain from "Components/Dashboard/components/DashboardList/NewDashModal/Examples/SlowestDomain"; +import SessionsByErrors from "Components/Dashboard/components/DashboardList/NewDashModal/Examples/SessionsByErrors"; +import SessionsByIssues from "Components/Dashboard/components/DashboardList/NewDashModal/Examples/SessionsByIssues"; +import ByBrowser from "Components/Dashboard/components/DashboardList/NewDashModal/Examples/SessionsBy/ByBrowser"; +import BySystem from "Components/Dashboard/components/DashboardList/NewDashModal/Examples/SessionsBy/BySystem"; +import ByCountry from "Components/Dashboard/components/DashboardList/NewDashModal/Examples/SessionsBy/ByCountry"; +import ByUrl from "Components/Dashboard/components/DashboardList/NewDashModal/Examples/SessionsBy/ByUrl"; +import {ERRORS, FUNNEL, TIMESERIES, USER_PATH} from "App/constants/card"; + +interface SelectCardProps { + onClose: () => void; + onCard: (card: any) => void; +} + +const CARD_CATEGORY = { + PRODUCT_ANALYTICS: 'product-analytics', + PERFORMANCE_MONITORING: 'performance-monitoring', + WEB_ANALYTICS: 'web-analytics', + CORE_WEB_VITALS: 'core-web-vitals', +} + +const segmentedOptions = [ + {label: 'Product Analytics', Icon: TrendingUp, value: CARD_CATEGORY.PRODUCT_ANALYTICS}, + {label: 'Performance Monitoring', Icon: Activity, value: CARD_CATEGORY.PERFORMANCE_MONITORING}, + {label: 'Web Analytics', Icon: BarChart, value: CARD_CATEGORY.WEB_ANALYTICS}, + {label: 'Core Web Vitals', Icon: TableCellsMerge, value: CARD_CATEGORY.CORE_WEB_VITALS}, +]; + +const TYPE = { + FUNNEL: 'funnel', + PATH_FINDER: 'path-finder', + TREND: 'trend', + SESSIONS_BY: 'sessions-by', + BREAKDOWN: 'breakdown', + SLOWEST_DOMAIN: 'slowest-domain', + SESSIONS_BY_ERRORS: 'sessions-by-errors', + SESSIONS_BY_ISSUES: 'sessions-by-issues', + SESSIONS_BY_BROWSER: 'sessions-by-browser', + SESSIONS_BY_SYSTEM: 'sessions-by-system', + SESSIONS_BY_COUNTRY: 'sessions-by-country', + SESSIONS_BY_URL: 'sessions-by-url', +} + +const CARD_TYPE_MAP = { + [TYPE.FUNNEL]: FUNNEL, + [TYPE.PATH_FINDER]: USER_PATH, + [TYPE.TREND]: TIMESERIES, + [TYPE.SESSIONS_BY]: TIMESERIES, + [TYPE.BREAKDOWN]: TIMESERIES, + [TYPE.SLOWEST_DOMAIN]: TIMESERIES, + [TYPE.SESSIONS_BY_ERRORS]: ERRORS, + [TYPE.SESSIONS_BY_ISSUES]: TIMESERIES, + [TYPE.SESSIONS_BY_BROWSER]: TIMESERIES, + [TYPE.SESSIONS_BY_SYSTEM]: TIMESERIES, + [TYPE.SESSIONS_BY_COUNTRY]: TIMESERIES, + [TYPE.SESSIONS_BY_URL]: TIMESERIES, +} + +export const CARD_LIST = [ + { + title: 'Funnel', + key: TYPE.FUNNEL, + cardType: FUNNEL, + category: CARD_CATEGORY.PRODUCT_ANALYTICS, + example: ExampleFunnel, + }, + { + title: 'Path Finder', + key: TYPE.PATH_FINDER, + cardType: USER_PATH, + category: CARD_CATEGORY.PRODUCT_ANALYTICS, + example: ExamplePath, + }, + { + title: 'Trend', + key: TYPE.TREND, + cardType: TIMESERIES, + category: CARD_CATEGORY.PRODUCT_ANALYTICS, + example: ExampleTrend, + }, + { + title: 'Sessions by', + key: TYPE.SESSIONS_BY, + cardType: TIMESERIES, + category: CARD_CATEGORY.PRODUCT_ANALYTICS, + example: ExampleCount, + }, + { + title: 'Breakdown', + key: TYPE.BREAKDOWN, + cardType: TIMESERIES, + category: CARD_CATEGORY.PERFORMANCE_MONITORING, + example: PerfBreakdown, + }, + { + title: 'Slowest Domain', + key: TYPE.SLOWEST_DOMAIN, + cardType: TIMESERIES, + category: CARD_CATEGORY.PERFORMANCE_MONITORING, + example: SlowestDomain, + }, + { + title: 'Sessions by Errors', + key: TYPE.SESSIONS_BY_ERRORS, + cardType: TIMESERIES, + category: CARD_CATEGORY.PERFORMANCE_MONITORING, + example: SessionsByErrors, + }, + { + title: 'Sessions by Issues', + key: TYPE.SESSIONS_BY_ISSUES, + cardType: TIMESERIES, + category: CARD_CATEGORY.PERFORMANCE_MONITORING, + example: SessionsByIssues, + }, + + { + title: 'Sessions by Browser', + key: TYPE.SESSIONS_BY_BROWSER, + cardType: TIMESERIES, + category: CARD_CATEGORY.WEB_ANALYTICS, + example: ByBrowser, + }, + { + title: 'Sessions by System', + key: TYPE.SESSIONS_BY_SYSTEM, + cardType: TIMESERIES, + category: CARD_CATEGORY.WEB_ANALYTICS, + example: BySystem, + }, + { + title: 'Sessions by Country', + key: TYPE.SESSIONS_BY_COUNTRY, + cardType: TIMESERIES, + category: CARD_CATEGORY.WEB_ANALYTICS, + example: ByCountry, + }, + { + title: 'Sessions by URL', + key: TYPE.SESSIONS_BY_URL, + cardType: TIMESERIES, + category: CARD_CATEGORY.WEB_ANALYTICS, + example: ByUrl, + }, + + // { + // title: 'Breakdown', + // key: TYPE.BREAKDOWN, + // category: CARD_CATEGORY.CORE_WEB_VITALS, + // example: PerfBreakdown, + // }, + // { + // title: 'Slowest Domain', + // key: TYPE.SLOWEST_DOMAIN, + // category: CARD_CATEGORY.CORE_WEB_VITALS, + // example: SlowestDomain, + // }, + // { + // title: 'Sessions by Issues', + // key: TYPE.SESSIONS_BY_ISSUES, + // category: CARD_CATEGORY.CORE_WEB_VITALS, + // example: SessionsByIssues, + // }, + // { + // title: 'Sessions by Errors', + // key: TYPE.SESSIONS_BY_ISSUES, + // category: CARD_CATEGORY.CORE_WEB_VITALS, + // example: SessionsByErrors, + // }, +] + +const SelectCard: React.FC = (props: SelectCardProps) => { + const [selected, setSelected] = React.useState('product-analytics'); + // const item = getSelectedItem(selected, onCard); + + const onCard = (card: string) => { + const _card = CARD_LIST.find((c) => c.key === card); + props.onCard(_card); + // props.onClose(); + } + + + const item = useMemo(() => { + return CARD_LIST.filter((card) => card.category === selected).map((card) => ( +
+ +
+ )); + }, [selected]); + + return ( + <> +
+
+ Select your first card type to add to the dashboard +
+
+
+ ({ + label:
+
+ {item} +
+ + ); +}; + +export default SelectCard; diff --git a/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/index.ts b/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/index.ts new file mode 100644 index 000000000..8854c0779 --- /dev/null +++ b/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/index.ts @@ -0,0 +1 @@ +export {default} from './NewDashboardModal'; diff --git a/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/index.tsx b/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/index.tsx deleted file mode 100644 index 42b7714a2..000000000 --- a/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/index.tsx +++ /dev/null @@ -1,174 +0,0 @@ -import { Segmented } from 'antd'; -import { Activity, BarChart, TableCellsMerge, TrendingUp } from 'lucide-react'; -import React from 'react'; - -import { Modal } from 'UI'; - -import ExampleCount from './Examples/Count'; -import ExampleFunnel from './Examples/Funnel'; -import ExamplePath from './Examples/Path'; -import PerfBreakdown from './Examples/PerfBreakdown'; -import ByBrowser from './Examples/SessionsBy/ByBrowser'; -import ByCountry from './Examples/SessionsBy/ByCountry'; -import BySystem from './Examples/SessionsBy/BySystem'; -import ByUrl from './Examples/SessionsBy/ByUrl'; -import SessionsByErrors from './Examples/SessionsByErrors'; -import SessionsByIssues from './Examples/SessionsByIssues'; -import SlowestDomain from './Examples/SlowestDomain'; -import ExampleTrend from './Examples/Trend'; - -function NewDashboardModal(props: { onClose: () => void; open: boolean }) { - const [step, setStep] = React.useState(0); - - const onCard = (card: string) => { - console.log(card); - }; - return ( - - -
- {step === 0 ? ( - - ) : null} -
-
-
- ); -} - -function SelectCard({ - onClose, - onCard, -}: { - onClose: () => void; - onCard: (card: string) => void; -}) { - const initial = 'product-analytics'; - const [selected, setSelected] = React.useState(initial); - let item; - switch (selected) { - case 'product-analytics': - item = ; - break; - case 'performance-monitoring': - item = ; - break; - case 'web-analytics': - item = ; - break; - case 'core-web-vitals': - item = ; - break; - default: - item =
under construction
; - break; - } - return ( - <> -
-
- Select your first card type to add to the dashboard -
-
- Close -
-
-
- - -
Product Analytics
-
- ), - value: 'product-analytics', - }, - { - label: ( -
- -
Performance Monitoring
-
- ), - value: 'performance-monitoring', - }, - { - label: ( -
- -
Web Analytics
-
- ), - value: 'web-analytics', - }, - { - label: ( -
- -
Core Web Vitals
-
- ), - value: 'core-web-vitals', - }, - ]} - onChange={(v) => setSelected(v)} - /> - -
- {item} -
-
- - ); -} - -function ProductAnalytics({ onCard }: { onCard: (card: string) => void }) { - return ( - <> - - - - - - ); -} - -function PerformanceMonitoring({ onCard }: { onCard: (card: string) => void }) { - return ( - <> - - - - - - ); -} - -function WebAnalytics({ onCard }: { onCard: (card: string) => void }) { - return ( - <> - - - - - - ); -} - -function CoreWebVitals({ onCard }: { onCard: (card: string) => void }) { - return ( - <> - - - - - - ); -} - -export default NewDashboardModal; diff --git a/frontend/app/components/Dashboard/components/WidgetForm/CardBuilder.tsx b/frontend/app/components/Dashboard/components/WidgetForm/CardBuilder.tsx new file mode 100644 index 000000000..464a3d2f5 --- /dev/null +++ b/frontend/app/components/Dashboard/components/WidgetForm/CardBuilder.tsx @@ -0,0 +1,292 @@ +import React, {useEffect, useState, useCallback} from 'react'; +import {observer} from 'mobx-react-lite'; +import {useStore} from 'App/mstore'; +import {metricOf, issueOptions, issueCategories} from 'App/constants/filterOptions'; +import {FilterKey} from 'Types/filter/filterType'; +import {withSiteId, dashboardMetricDetails, metricDetails} from 'App/routes'; +import {Icon, confirm} from 'UI'; +import {Card, Input, Space, Button} from 'antd'; +import {AudioWaveform} from "lucide-react"; +import FilterSeries from '../FilterSeries'; +import Select from 'Shared/Select'; +import MetricTypeDropdown from './components/MetricTypeDropdown'; +import MetricSubtypeDropdown from './components/MetricSubtypeDropdown'; +import {eventKeys} from 'App/types/filter/newFilter'; +import {renderClickmapThumbnail} from './renderMap'; +import FilterItem from 'Shared/Filters/FilterItem'; +import { + TIMESERIES, TABLE, CLICKMAP, FUNNEL, ERRORS, RESOURCE_MONITORING, + PERFORMANCE, WEB_VITALS, INSIGHTS, USER_PATH, RETENTION +} from 'App/constants/card'; +import {useParams} from 'react-router-dom'; +import {useHistory} from "react-router"; + +const AIInput = ({value, setValue, placeholder, onEnter}) => ( + setValue(e.target.value)} + className='w-full mb-2' + onKeyDown={(e) => e.key === 'Enter' && onEnter()} + /> +); + +const PredefinedMessage = () => ( +
+ +
Filtering and drill-downs will be supported soon for this card type.
+
+); + +const MetricOptions = ({metric, writeOption}) => { + const isUserPath = metric.metricType === USER_PATH; + + return ( +
+
+ Card showing + + + {isUserPath && ( + <> + + + + )} + {metric.metricOf === FilterKey.ISSUE && metric.metricType === TABLE && ( + <> + issue type + + + )} + {metric.metricType === TABLE && + !(metric.metricOf === FilterKey.ERRORS || metric.metricOf === FilterKey.SESSIONS) && ( + <> + showing +