diff --git a/frontend/app/components/Dashboard/components/AddCardSelectionModal.tsx b/frontend/app/components/Dashboard/components/AddCardSelectionModal.tsx
new file mode 100644
index 000000000..e9bb29a64
--- /dev/null
+++ b/frontend/app/components/Dashboard/components/AddCardSelectionModal.tsx
@@ -0,0 +1,56 @@
+import React from 'react';
+import {Card, Col, Modal, Row, Typography} from "antd";
+import {Grid2X2, Plus} from "lucide-react";
+import NewDashboardModal from "Components/Dashboard/components/DashboardList/NewDashModal";
+
+interface Props {
+ open: boolean;
+ onClose?: () => void;
+}
+
+function AddCardSelectionModal(props: Props) {
+ const [open, setOpen] = React.useState(false);
+ const [isLibrary, setIsLibrary] = React.useState(false);
+
+ const onCloseModal = () => {
+ setOpen(false);
+ // props.onClose && props.onClose();
+ }
+
+ const onClick = (isLibrary: boolean) => {
+ setIsLibrary(isLibrary);
+ setOpen(true);
+ }
+ return (
+
+
+
+ onClick(true)}>
+
+
+
Add from library
+
Select from 12 available
+
+
+
+
+ onClick(false)}>
+
+
+
+
+
+ {open && }
+
+ );
+}
+
+export default AddCardSelectionModal;
diff --git a/frontend/app/components/Dashboard/components/DashboardHeader/DashboardHeader.tsx b/frontend/app/components/Dashboard/components/DashboardHeader/DashboardHeader.tsx
index 072e2bf44..29950a0cd 100644
--- a/frontend/app/components/Dashboard/components/DashboardHeader/DashboardHeader.tsx
+++ b/frontend/app/components/Dashboard/components/DashboardHeader/DashboardHeader.tsx
@@ -1,134 +1,145 @@
import React from 'react';
import Breadcrumb from 'Shared/Breadcrumb';
-import { withSiteId } from 'App/routes';
-import { withRouter, RouteComponentProps } from 'react-router-dom';
-import { Button, PageTitle, confirm, Tooltip } from 'UI';
+import {withSiteId} from 'App/routes';
+import {withRouter, RouteComponentProps} from 'react-router-dom';
+import {Button, PageTitle, confirm, Tooltip} from 'UI';
import SelectDateRange from 'Shared/SelectDateRange';
-import { useStore } from 'App/mstore';
-import { useModal } from 'App/components/Modal';
+import {useStore} from 'App/mstore';
+import {useModal} from 'App/components/Modal';
import DashboardOptions from '../DashboardOptions';
import withModal from 'App/components/Modal/withModal';
-import { observer } from 'mobx-react-lite';
+import {observer} from 'mobx-react-lite';
import DashboardEditModal from '../DashboardEditModal';
import AddCardModal from '../AddCardModal';
+import AddCardSelectionModal from "Components/Dashboard/components/AddCardSelectionModal";
interface IProps {
- dashboardId: string;
- siteId: string;
- renderReport?: any;
+ dashboardId: string;
+ siteId: string;
+ renderReport?: any;
}
type Props = IProps & RouteComponentProps;
const MAX_CARDS = 29;
-function DashboardHeader(props: Props) {
- const { siteId, dashboardId } = props;
- const { dashboardStore } = useStore();
- const { showModal } = useModal();
- const [focusTitle, setFocusedInput] = React.useState(true);
- const [showEditModal, setShowEditModal] = React.useState(false);
- const period = dashboardStore.period;
- const dashboard: any = dashboardStore.selectedDashboard;
- const canAddMore: boolean = dashboard?.widgets?.length <= MAX_CARDS;
+function AddCard(props: { disabled: boolean }) {
+ const [open, setOpen] = React.useState(false);
- const onEdit = (isTitle: boolean) => {
- dashboardStore.initDashboard(dashboard);
- setFocusedInput(isTitle);
- setShowEditModal(true);
- };
-
- const onDelete = async () => {
- if (
- await confirm({
- header: 'Confirm',
- confirmButton: 'Yes, delete',
- confirmation: `Are you sure you want to permanently delete this Dashboard?`,
- })
- ) {
- dashboardStore.deleteDashboard(dashboard).then(() => {
- props.history.push(withSiteId(`/dashboard`, siteId));
- });
- }
- };
- return (
-
-
setShowEditModal(false)}
- focusTitle={focusTitle}
- />
-
-
-
-
- {dashboard?.name}
-
- }
- onDoubleClick={() => onEdit(true)}
- className="mr-3 select-none border-b border-b-borderColor-transparent hover:border-dotted hover:border-gray-medium cursor-pointer"
- />
-
-
-
+ // showModal(, {right: true})
+ return <>
+
-
-
-
- dashboardStore.setPeriod(period)}
- right={true}
- />
-
-
-
-
-
-
-
-
- {/* @ts-ignore */}
-
- onEdit(false)}
- >
- {dashboard?.description || 'Describe the purpose of this dashboard'}
-
-
-
- );
+ setOpen(false)}/>
+ >;
+}
+
+function DashboardHeader(props: Props) {
+ const {siteId, dashboardId} = props;
+ const {dashboardStore} = useStore();
+ const {showModal} = useModal();
+ const [focusTitle, setFocusedInput] = React.useState(true);
+ const [showEditModal, setShowEditModal] = React.useState(false);
+ const period = dashboardStore.period;
+
+ const dashboard: any = dashboardStore.selectedDashboard;
+ const canAddMore: boolean = dashboard?.widgets?.length <= MAX_CARDS;
+
+ const onEdit = (isTitle: boolean) => {
+ dashboardStore.initDashboard(dashboard);
+ setFocusedInput(isTitle);
+ setShowEditModal(true);
+ };
+
+ const onDelete = async () => {
+ if (
+ await confirm({
+ header: 'Confirm',
+ confirmButton: 'Yes, delete',
+ confirmation: `Are you sure you want to permanently delete this Dashboard?`,
+ })
+ ) {
+ dashboardStore.deleteDashboard(dashboard).then(() => {
+ props.history.push(withSiteId(`/dashboard`, siteId));
+ });
+ }
+ };
+ return (
+
+
setShowEditModal(false)}
+ focusTitle={focusTitle}
+ />
+
+
+
+
+ {dashboard?.name}
+
+ }
+ onDoubleClick={() => onEdit(true)}
+ className="mr-3 select-none border-b border-b-borderColor-transparent hover:border-dotted hover:border-gray-medium cursor-pointer"
+ />
+
+
+
+
+
+ dashboardStore.setPeriod(period)}
+ right={true}
+ />
+
+
+
+
+
+
+
+
+ {/* @ts-ignore */}
+
+ onEdit(false)}
+ >
+ {dashboard?.description || 'Describe the purpose of this dashboard'}
+
+
+
+
+ );
}
export default withRouter(withModal(observer(DashboardHeader)));
diff --git a/frontend/app/components/Dashboard/components/DashboardList/Header.tsx b/frontend/app/components/Dashboard/components/DashboardList/Header.tsx
index afc478e49..5b0062ea4 100644
--- a/frontend/app/components/Dashboard/components/DashboardList/Header.tsx
+++ b/frontend/app/components/Dashboard/components/DashboardList/Header.tsx
@@ -1,62 +1,47 @@
-import { PlusOutlined } from '@ant-design/icons';
-import { Button } from 'antd';
-import { observer } from 'mobx-react-lite';
+import {PlusOutlined} from '@ant-design/icons';
+import {Button} from 'antd';
+import {observer} from 'mobx-react-lite';
import React from 'react';
-import { useStore } from 'App/mstore';
-import { withSiteId } from 'App/routes';
-import { PageTitle } from 'UI';
+import {PageTitle} from 'UI';
import DashboardSearch from './DashboardSearch';
import NewDashboardModal from './NewDashModal';
-function Header({ history, siteId }: { history: any; siteId: string }) {
- const [showModal, setShowModal] = React.useState(false);
- const { dashboardStore } = useStore();
+function Header() {
+ const [showModal, setShowModal] = React.useState(true);
- const onSaveDashboard = () => {
- dashboardStore.initDashboard();
- dashboardStore
- .save(dashboardStore.dashboardInstance)
- .then(async (syncedDashboard) => {
- dashboardStore.selectDashboardById(syncedDashboard.dashboardId);
- history.push(
- withSiteId(`/dashboard/${syncedDashboard.dashboardId}`, siteId)
- );
- });
- };
+ const onAddDashboardClick = () => {
+ setShowModal(true);
+ };
- const onAddDashboardClick = () => {
- setShowModal(true);
- };
+ const onClose = () => {
+ setShowModal(false);
+ };
- const onClose = () => {
- setShowModal(false);
- };
-
- return (
- <>
-
-
-
-
}
- type="primary"
- onClick={onAddDashboardClick}
- >
- Create Dashboard
-
-
-
-
-
-
-
-
- >
- );
+ return (
+ <>
+
+
+
+
+
+
+
+
+
+
+
+ >
+ );
}
export default observer(Header);
diff --git a/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/CardsLibrary.tsx b/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/CardsLibrary.tsx
new file mode 100644
index 000000000..3465b71e6
--- /dev/null
+++ b/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/CardsLibrary.tsx
@@ -0,0 +1,76 @@
+import React, {useEffect, useMemo} from 'react';
+import {useStore} from "App/mstore";
+import WidgetWrapper from "Components/Dashboard/components/WidgetWrapper/WidgetWrapper";
+import {observer} from "mobx-react-lite";
+import {Loader} from "UI";
+import WidgetChart from "Components/Dashboard/components/WidgetChart/WidgetChart";
+import LazyLoad from 'react-lazyload';
+import {Card} from "antd";
+import {CARD_CATEGORIES} from "Components/Dashboard/components/DashboardList/NewDashModal/ExampleCards";
+
+const CARD_TYPES_MAP = CARD_CATEGORIES.reduce((acc: any, category: any) => {
+ acc[category.key] = category.types;
+ return acc;
+}, {});
+
+interface Props {
+ category?: string;
+ selectedList: any;
+ onCard: (metricId: number) => void;
+}
+
+function CardsLibrary(props: Props) {
+ const {selectedList} = props;
+ const {metricStore, dashboardStore} = useStore();
+
+ const cards = useMemo(() => {
+ return metricStore.filteredCards.filter((card: any) => {
+ return CARD_TYPES_MAP[props.category || 'default'].includes(card.metricType);
+ });
+ }, [metricStore.filteredCards, props.category]);
+
+ useEffect(() => {
+ metricStore.fetchList();
+ }, []);
+
+ const onItemClick = (metricId: number) => {
+ props.onCard(metricId);
+ }
+
+ return (
+
+
+ {cards.map((metric: any) => (
+
+ onItemClick(metric.metricId)}>
+
+
+
+
+
+
+
+ ))}
+
+
+ );
+}
+
+export default observer(CardsLibrary);
diff --git a/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/CreateCard.tsx b/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/CreateCard.tsx
index 0444d163c..7ca9a826f 100644
--- a/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/CreateCard.tsx
+++ b/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/CreateCard.tsx
@@ -7,6 +7,7 @@ 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";
+import {number} from "Player/player/localStorage";
const getTitleByType = (type: string) => {
switch (type) {
@@ -26,10 +27,10 @@ function CreateCard(props: Props) {
const history = useHistory();
const {metricStore, dashboardStore, aiFiltersStore} = useStore();
const metric = metricStore.instance;
- const siteId = history.location.pathname.split('/')[1];
+ const siteId: string = history.location.pathname.split('/')[1];
+ const dashboardId: string = history.location.pathname.split('/')[4];
// const title = getTitleByType(metric.metricType)
-
const createNewDashboard = async () => {
dashboardStore.initDashboard();
return await dashboardStore
diff --git a/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/ExampleCards.tsx b/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/ExampleCards.tsx
new file mode 100644
index 000000000..618a31ab4
--- /dev/null
+++ b/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/ExampleCards.tsx
@@ -0,0 +1,142 @@
+import ExampleFunnel from "./Examples/Funnel";
+import ExamplePath from "./Examples/Path";
+import ExampleTrend from "./Examples/Trend";
+import ExampleCount from "./Examples/Count";
+import PerfBreakdown from "./Examples/PerfBreakdown";
+import SlowestDomain from "./Examples/SlowestDomain";
+import SessionsByErrors from "./Examples/SessionsByErrors";
+import SessionsByIssues from "./Examples/SessionsByIssues";
+import ByBrowser from "./Examples/SessionsBy/ByBrowser";
+import BySystem from "./Examples/SessionsBy/BySystem";
+import ByCountry from "./Examples/SessionsBy/ByCountry";
+import ByUrl from "./Examples/SessionsBy/ByUrl";
+import {ERRORS, FUNNEL, PERFORMANCE, TABLE, TIMESERIES, USER_PATH, WEB_VITALS} from "App/constants/card";
+import {FilterKey} from "Types/filter/filterType";
+import {Activity, BarChart, TableCellsMerge, TrendingUp} from "lucide-react";
+
+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',
+}
+
+export const CARD_CATEGORIES = [
+ {
+ key: 'product-analytics', label: 'Product Analytics', icon: TrendingUp, types: [USER_PATH, ERRORS]
+ },
+ {key: 'performance-monitoring', label: 'Performance Monitoring', icon: Activity, types: [TIMESERIES]},
+ {key: 'web-analytics', label: 'Web Analytics', icon: BarChart, types: [TABLE]},
+ {key: 'core-web-vitals', label: 'Core Web Vitals', icon: TableCellsMerge, types: [WEB_VITALS]}
+];
+
+export interface CardType {
+ title: string;
+ key: string;
+ cardType: string;
+ category: string;
+ example: any;
+ metricOf?: string;
+}
+
+export const CARD_LIST: CardType[] = [
+ {
+ title: 'Funnel',
+ key: TYPE.FUNNEL,
+ cardType: FUNNEL,
+ category: CARD_CATEGORIES[0].key,
+ example: ExampleFunnel,
+ },
+ {
+ title: 'Path Finder',
+ key: TYPE.PATH_FINDER,
+ cardType: USER_PATH,
+ category: CARD_CATEGORIES[0].key,
+ example: ExamplePath,
+ },
+ {
+ title: 'Trend',
+ key: TYPE.TREND,
+ cardType: TIMESERIES,
+ category: CARD_CATEGORIES[0].key,
+ example: ExampleTrend,
+ },
+ {
+ title: 'Sessions by',
+ key: TYPE.SESSIONS_BY,
+ cardType: TABLE,
+ metricOf: 'userBrowser',
+ category: CARD_CATEGORIES[0].key,
+ example: ExampleCount,
+ },
+
+ {
+ title: 'Breakdown',
+ key: TYPE.BREAKDOWN,
+ cardType: PERFORMANCE,
+ category: CARD_CATEGORIES[1].key,
+ example: PerfBreakdown,
+ },
+ {
+ title: 'Slowest Domain',
+ key: TYPE.SLOWEST_DOMAIN,
+ cardType: TIMESERIES,
+ category: CARD_CATEGORIES[1].key,
+ example: SlowestDomain,
+ },
+ {
+ title: 'Sessions by Errors',
+ key: TYPE.SESSIONS_BY_ERRORS,
+ cardType: TIMESERIES,
+ category: CARD_CATEGORIES[1].key,
+ example: SessionsByErrors,
+ },
+ {
+ title: 'Sessions by Issues',
+ key: TYPE.SESSIONS_BY_ISSUES,
+ cardType: TIMESERIES,
+ category: CARD_CATEGORIES[1].key,
+ example: SessionsByIssues,
+ },
+
+ {
+ title: 'Sessions by Browser',
+ key: TYPE.SESSIONS_BY_BROWSER,
+ cardType: TABLE,
+ metricOf: FilterKey.USER_BROWSER,
+ category: CARD_CATEGORIES[2].key,
+ example: ByBrowser,
+ },
+ {
+ title: 'Sessions by System',
+ key: TYPE.SESSIONS_BY_SYSTEM,
+ cardType: TABLE,
+ metricOf: FilterKey.USER_OS,
+ category: CARD_CATEGORIES[2].key,
+ example: BySystem,
+ },
+ {
+ title: 'Sessions by Country',
+ key: TYPE.SESSIONS_BY_COUNTRY,
+ cardType: TABLE,
+ metricOf: FilterKey.USER_COUNTRY,
+ category: CARD_CATEGORIES[2].key,
+ example: ByCountry,
+ },
+ {
+ title: 'Sessions by URL',
+ key: TYPE.SESSIONS_BY_URL,
+ cardType: TABLE,
+ metricOf: FilterKey.LOCATION,
+ category: CARD_CATEGORIES[2].key,
+ example: ByUrl,
+ },
+]
diff --git a/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/NewDashboardModal.tsx b/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/NewDashboardModal.tsx
index f414aea5b..9c0eaad8f 100644
--- a/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/NewDashboardModal.tsx
+++ b/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/NewDashboardModal.tsx
@@ -2,35 +2,29 @@ import React, {useEffect} from 'react';
import {Modal} from 'antd';
import SelectCard from './SelectCard';
import CreateCard from "Components/Dashboard/components/DashboardList/NewDashModal/CreateCard";
-import {useStore} from "App/mstore";
-import {TIMESERIES} from "App/constants/card";
interface NewDashboardModalProps {
onClose: () => void;
open: boolean;
+ isAddingFromLibrary?: boolean;
+ isCreatingNewCard?: boolean;
}
-const NewDashboardModal: React.FC = ({onClose, open}) => {
+const NewDashboardModal: React.FC = ({
+ onClose,
+ open,
+ isAddingFromLibrary = false,
+ isCreatingNewCard = false
+ }) => {
const [step, setStep] = React.useState(0);
- const [selectedCard, setSelectedCard] = React.useState('trend-single');
- const {metricStore} = useStore();
- const onCard = (card: any) => {
+ const onCard = () => {
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);
+ setStep(0);
}
}, [open]);
@@ -39,7 +33,7 @@ const NewDashboardModal: React.FC = ({onClose, open}) =>
- {step === 0 && }
+ {step === 0 && }
{step === 1 && setStep(0)}/>}
diff --git a/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/SelectCard.tsx b/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/SelectCard.tsx
index 0e4af66f3..9c21a58ed 100644
--- a/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/SelectCard.tsx
+++ b/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/SelectCard.tsx
@@ -1,228 +1,109 @@
import React, {useMemo} from 'react';
-import {Segmented} from 'antd';
+import {Button, Segmented} from 'antd';
+import {CARD_LIST, CARD_CATEGORIES, CardType} from './ExampleCards';
+import {useStore} from 'App/mstore';
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";
+import CardsLibrary from "Components/Dashboard/components/DashboardList/NewDashModal/CardsLibrary";
interface SelectCardProps {
onClose: () => void;
- onCard: (card: any) => void;
+ onCard: () => void;
+ isLibrary?: boolean;
}
-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 SelectCard: React.FC = ({onCard, isLibrary = false}) => {
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 [selectedCards, setSelectedCards] = React.useState([]);
+ const {metricStore, dashboardStore} = useStore();
+ const dashboardId = window.location.pathname.split('/')[4];
- const item = useMemo(() => {
+ const handleCardSelection = (card: string) => {
+ const selectedCard = CARD_LIST.find((c) => c.key === card) as CardType;
+ metricStore.merge({
+ metricType: selectedCard.cardType,
+ name: selectedCard.title,
+ metricOf: selectedCard.metricOf,
+ });
+ onCard();
+ };
+
+ const cardItems = useMemo(() => {
return CARD_LIST.filter((card) => card.category === selected).map((card) => (
-
+
));
}, [selected]);
+ const onCardClick = (cardId: number) => {
+ if (selectedCards.includes(cardId)) {
+ setSelectedCards(selectedCards.filter((id) => id !== cardId));
+ } else {
+ setSelectedCards([...selectedCards, cardId]);
+ }
+ }
+
+ const onAddSelected = () => {
+ console.log(selectedCards);
+ dashboardStore.addWidgetToDashboard(dashboardId, selectedCards);
+ }
+
return (
<>
-
-
- Select your first card type to add to the dashboard
-
-
-
- ({
- label:
-
- {item}
-
+
+
+ {isLibrary ? :
+ }
>
);
};
+interface HeaderProps {
+ selectedCount?: number,
+ onAdd?: () => void;
+}
+
+const Header: React.FC = ({selectedCount = 0, onAdd = () => null}) => (
+
+
+ Select your first card type to add to the dashboard
+
+
+ {selectedCount > 0 ? (
+
+ ) : ''}
+
+
+);
+
+interface CategorySelectorProps {
+ setSelected: React.Dispatch>;
+}
+
+const CategorySelector: React.FC = ({setSelected}) => (
+ ({
+ label: