diff --git a/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/CardsLibrary.tsx b/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/CardsLibrary.tsx index 13b5e7d35..887b82299 100644 --- a/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/CardsLibrary.tsx +++ b/frontend/app/components/Dashboard/components/DashboardList/NewDashModal/CardsLibrary.tsx @@ -73,7 +73,7 @@ function CardsLibrary(props: Props) { // isPreview={true} metric={metric} isTemplate={true} - isWidget={true} + isSaved={true} /> diff --git a/frontend/app/components/Dashboard/components/DashboardMetricSelection/DashboardMetricSelection.tsx b/frontend/app/components/Dashboard/components/DashboardMetricSelection/DashboardMetricSelection.tsx index 67284b59c..28c950d07 100644 --- a/frontend/app/components/Dashboard/components/DashboardMetricSelection/DashboardMetricSelection.tsx +++ b/frontend/app/components/Dashboard/components/DashboardMetricSelection/DashboardMetricSelection.tsx @@ -137,7 +137,7 @@ function DashboardMetricSelection(props: IProps) { widget={widget} active={selectedWidgetIds.includes(widget.metricId)} isTemplate={true} - isWidget={widget.metricType === 'predefined'} + isSaved={widget.metricType === 'predefined'} onClick={() => dashboardStore.toggleWidgetSelection(widget)} /> ))} diff --git a/frontend/app/components/Dashboard/components/DashboardWidgetGrid/AddMetric.tsx b/frontend/app/components/Dashboard/components/DashboardWidgetGrid/AddMetric.tsx index 6f3b85572..d42cd23be 100644 --- a/frontend/app/components/Dashboard/components/DashboardWidgetGrid/AddMetric.tsx +++ b/frontend/app/components/Dashboard/components/DashboardWidgetGrid/AddMetric.tsx @@ -83,7 +83,7 @@ function AddMetric({ history, siteId, title, description }: IProps) { widget={metric} active={selectedWidgetIds.includes(metric.metricId)} isTemplate={true} - isWidget={metric.metricType === 'predefined'} + isSaved={metric.metricType === 'predefined'} onClick={() => dashboardStore.toggleWidgetSelection(metric)} /> )) diff --git a/frontend/app/components/Dashboard/components/DashboardWidgetGrid/AddPredefinedMetric.tsx b/frontend/app/components/Dashboard/components/DashboardWidgetGrid/AddPredefinedMetric.tsx index 59316a7a2..e30f9f612 100644 --- a/frontend/app/components/Dashboard/components/DashboardWidgetGrid/AddPredefinedMetric.tsx +++ b/frontend/app/components/Dashboard/components/DashboardWidgetGrid/AddPredefinedMetric.tsx @@ -129,7 +129,7 @@ function AddPredefinedMetric({ history, siteId, title, description }: IProps) { widget={metric} active={selectedWidgetIds.includes(metric.metricId)} isTemplate={true} - isWidget={metric.metricType === 'predefined'} + isSaved={metric.metricType === 'predefined'} onClick={() => dashboardStore.toggleWidgetSelection(metric)} /> diff --git a/frontend/app/components/Dashboard/components/DashboardWidgetGrid/DashboardWidgetGrid.tsx b/frontend/app/components/Dashboard/components/DashboardWidgetGrid/DashboardWidgetGrid.tsx index b318855ef..587348fdd 100644 --- a/frontend/app/components/Dashboard/components/DashboardWidgetGrid/DashboardWidgetGrid.tsx +++ b/frontend/app/components/Dashboard/components/DashboardWidgetGrid/DashboardWidgetGrid.tsx @@ -75,7 +75,7 @@ function DashboardWidgetGrid(props: Props) { } dashboardId={dashboardId} siteId={siteId} - isWidget={true} + isSaved={true} grid="vitals" /> @@ -102,7 +102,7 @@ function DashboardWidgetGrid(props: Props) { } dashboardId={dashboardId} siteId={siteId} - isWidget={true} + isSaved={true} grid="other" /> diff --git a/frontend/app/components/Dashboard/components/MetricsList/GridView.tsx b/frontend/app/components/Dashboard/components/MetricsList/GridView.tsx index ab3f770f0..195a6f65f 100644 --- a/frontend/app/components/Dashboard/components/MetricsList/GridView.tsx +++ b/frontend/app/components/Dashboard/components/MetricsList/GridView.tsx @@ -24,7 +24,7 @@ function GridView(props: Props) { widget={metric} isGridView={true} active={selectedList.includes(metric.metricId)} - isWidget={true} + isSaved={true} onClick={() => onItemClick(parseInt(metric.metricId))} /> diff --git a/frontend/app/components/Dashboard/components/WidgetChart/WidgetChart.tsx b/frontend/app/components/Dashboard/components/WidgetChart/WidgetChart.tsx index c36d44558..577f66732 100644 --- a/frontend/app/components/Dashboard/components/WidgetChart/WidgetChart.tsx +++ b/frontend/app/components/Dashboard/components/WidgetChart/WidgetChart.tsx @@ -37,13 +37,13 @@ import SessionsBy from "Components/Dashboard/Widgets/CustomMetricsWidgets/Sessio interface Props { metric: any; - isWidget?: boolean; + isSaved?: boolean; isTemplate?: boolean; isPreview?: boolean; } function WidgetChart(props: Props) { - const {isWidget = false, metric, isTemplate} = props; + const {isSaved = false, metric, isTemplate} = props; const {dashboardStore, metricStore, sessionStore} = useStore(); const _metric: any = metricStore.instance; const period = dashboardStore.period; @@ -93,10 +93,10 @@ function WidgetChart(props: Props) { ..._metric.series, ..._metric.excludes, ..._metric.startPoint, hideExcess: _metric.hideExcess }); - const fetchMetricChartData = (metric: any, payload: any, isWidget: any, period: any) => { + const fetchMetricChartData = (metric: any, payload: any, isSaved: any, period: any) => { if (!isMounted()) return; setLoading(true); - dashboardStore.fetchMetricChartData(metric, payload, isWidget, period).then((res: any) => { + dashboardStore.fetchMetricChartData(metric, payload, isSaved, period).then((res: any) => { if (isMounted()) setData(res); }).finally(() => { setLoading(false); @@ -111,8 +111,8 @@ function WidgetChart(props: Props) { } prevMetricRef.current = metric; const timestmaps = drillDownPeriod.toTimestamps(); - const payload = isWidget ? {...params} : {...metricParams, ...timestmaps, ...metric.toJson()}; - debounceRequest(metric, payload, isWidget, !isWidget ? drillDownPeriod : period); + const payload = isSaved ? {...params} : {...metricParams, ...timestmaps, ...metric.toJson()}; + debounceRequest(metric, payload, isSaved, !isSaved ? drillDownPeriod : period); }; useEffect(() => { _metric.updateKey('page', 1); @@ -126,7 +126,7 @@ function WidgetChart(props: Props) { const metricWithData = {...metric, data}; if (metricType === FUNNEL) { - return ; + return ; } if (metricType === 'predefined' || metricType === ERRORS || metricType === PERFORMANCE || metricType === RESOURCE_MONITORING || metricType === WEB_VITALS) { @@ -166,7 +166,7 @@ function WidgetChart(props: Props) { metric={metric} data={data} isTemplate={isTemplate} - isEdit={!isWidget && !isTemplate} + isEdit={!isSaved && !isTemplate} /> ); } @@ -176,7 +176,7 @@ function WidgetChart(props: Props) { metric={metric} data={data} // isTemplate={isTemplate} - isEdit={!isWidget && !isTemplate} + isEdit={!isSaved && !isTemplate} /> ); } diff --git a/frontend/app/components/Dashboard/components/WidgetPreview/WidgetPreview.tsx b/frontend/app/components/Dashboard/components/WidgetPreview/WidgetPreview.tsx index 2420319a4..0f235bb62 100644 --- a/frontend/app/components/Dashboard/components/WidgetPreview/WidgetPreview.tsx +++ b/frontend/app/components/Dashboard/components/WidgetPreview/WidgetPreview.tsx @@ -1,137 +1,65 @@ -import React from 'react'; +import { Space, Switch } from 'antd'; import cn from 'classnames'; +import { observer } from 'mobx-react-lite'; +import React from 'react'; + +import { CLICKMAP, USER_PATH } from 'App/constants/card'; +import { useStore } from 'App/mstore'; +import ClickMapRagePicker from 'Components/Dashboard/components/ClickMapRagePicker'; + import WidgetWrapper from '../WidgetWrapper'; -import {useStore} from 'App/mstore'; -// import {SegmentSelection, Button, Icon} from 'UI'; -import {observer} from 'mobx-react-lite'; -// import {FilterKey} from 'Types/filter/filterType'; -// import WidgetDateRange from '../WidgetDateRange/WidgetDateRange'; -import ClickMapRagePicker from "Components/Dashboard/components/ClickMapRagePicker"; -// import DashboardSelectionModal from '../DashboardSelectionModal/DashboardSelectionModal'; -import {CLICKMAP, TABLE, TIMESERIES, RETENTION, USER_PATH} from 'App/constants/card'; -import {Space, Switch} from 'antd'; -// import AddToDashboardButton from "Components/Dashboard/components/AddToDashboardButton"; interface Props { - className?: string; - name: string; - isEditing?: boolean; + className?: string; + name: string; + isEditing?: boolean; } function WidgetPreview(props: Props) { - const {className = ''} = props; - const {metricStore, dashboardStore} = useStore(); - // const dashboards = dashboardStore.dashboards; - const metric: any = metricStore.instance; - // const isTimeSeries = metric.metricType === TIMESERIES; - // const isTable = metric.metricType === TABLE; - // const isRetention = metric.metricType === RETENTION; - // const disableVisualization = metric.metricOf === FilterKey.SESSIONS || metric.metricOf === FilterKey.ERRORS; - // - // const changeViewType = (_, {name, value}: any) => { - // metric.update({[name]: value}); - // } + const { className = '' } = props; + const { metricStore, dashboardStore } = useStore(); + const metric: any = metricStore.instance; - return ( - <> -
-
-

- {props.name} -

-
- {metric.metricType === USER_PATH && ( - { - e.preventDefault(); - metric.update({hideExcess: !metric.hideExcess}); - }} - > - - - Hide Minor Paths - - - )} + return ( + <> +
+
+

{props.name}

+
+ {metric.metricType === USER_PATH && ( + { + e.preventDefault(); + metric.update({ hideExcess: !metric.hideExcess }); + }} + > + + + + Hide Minor Paths + + + + )} - {/*{isTimeSeries && (*/} - {/* <>*/} - {/* Visualization*/} - {/* */} - {/* */} - {/*)}*/} - - {/*{!disableVisualization && isTable && (*/} - {/* <>*/} - {/* Visualization*/} - {/* */} - {/* */} - {/*)}*/} - - {/*{isRetention && (*/} - {/* <>*/} - {/* Visualization*/} - {/* */} - {/**/} - {/*)}*/} - -
- {metric.metricType === CLICKMAP ? ( - - ) : null} - - - {/* add to dashboard */} - {/*{metric.exists() && (*/} - {/* */} - {/*)}*/} -
-
-
- -
-
- - ); +
+ {metric.metricType === CLICKMAP ? : null} +
+
+
+ +
+
+ + ); } export default observer(WidgetPreview); diff --git a/frontend/app/components/Dashboard/components/WidgetView/WidgetView.tsx b/frontend/app/components/Dashboard/components/WidgetView/WidgetView.tsx index 02e586420..31516da65 100644 --- a/frontend/app/components/Dashboard/components/WidgetView/WidgetView.tsx +++ b/frontend/app/components/Dashboard/components/WidgetView/WidgetView.tsx @@ -1,168 +1,183 @@ -import React, {useState} from 'react'; -import {useStore} from 'App/mstore'; -import {Icon, Loader, NoContent} from 'UI'; -import WidgetPreview from '../WidgetPreview'; -import WidgetSessions from '../WidgetSessions'; -import {useObserver} from 'mobx-react-lite'; -import {dashboardMetricDetails, metricDetails, withSiteId} from 'App/routes'; -import FunnelIssues from '../Funnels/FunnelIssues/FunnelIssues'; -import Breadcrumb from 'Shared/Breadcrumb'; -import {FilterKey} from 'Types/filter/filterType'; -import {Prompt, useHistory} from 'react-router'; -import AnimatedSVG, {ICONS} from 'Shared/AnimatedSVG/AnimatedSVG'; +import { FilterKey } from 'Types/filter/filterType'; +import { Space } from 'antd'; +import { useObserver } from 'mobx-react-lite'; +import React, { useState } from 'react'; +import { Prompt, useHistory } from 'react-router'; + import { - TIMESERIES, - TABLE, - CLICKMAP, - FUNNEL, - INSIGHTS, - USER_PATH, - RETENTION, + CLICKMAP, + FUNNEL, + INSIGHTS, + RETENTION, + TABLE, + TIMESERIES, + USER_PATH, } from 'App/constants/card'; +import { useStore } from 'App/mstore'; +import Widget from 'App/mstore/types/widget'; +import { dashboardMetricDetails, metricDetails, withSiteId } from 'App/routes'; +import WidgetFormNew from 'Components/Dashboard/components/WidgetForm/WidgetFormNew'; +import { renderClickmapThumbnail } from 'Components/Dashboard/components/WidgetForm/renderMap'; +import WidgetViewHeader from 'Components/Dashboard/components/WidgetView/WidgetViewHeader'; +import { Icon, Loader, NoContent } from 'UI'; + +import AnimatedSVG, { ICONS } from 'Shared/AnimatedSVG/AnimatedSVG'; +import Breadcrumb from 'Shared/Breadcrumb'; + import CardIssues from '../CardIssues'; import CardUserList from '../CardUserList/CardUserList'; -import WidgetViewHeader from "Components/Dashboard/components/WidgetView/WidgetViewHeader"; -import WidgetFormNew from "Components/Dashboard/components/WidgetForm/WidgetFormNew"; -import {Space} from "antd"; -import {renderClickmapThumbnail} from "Components/Dashboard/components/WidgetForm/renderMap"; -import Widget from "App/mstore/types/widget"; +import FunnelIssues from '../Funnels/FunnelIssues/FunnelIssues'; +import WidgetPreview from '../WidgetPreview'; +import WidgetSessions from '../WidgetSessions'; interface Props { - history: any; - match: any; - siteId: any; + history: any; + match: any; + siteId: any; } function WidgetView(props: Props) { - const { - match: { - params: {siteId, dashboardId, metricId}, - }, - } = props; - // const siteId = location.pathname.split('/')[1]; - // const dashboardId = location.pathname.split('/')[3]; - const {metricStore, dashboardStore} = useStore(); - const widget = useObserver(() => metricStore.instance); - const loading = useObserver(() => metricStore.isLoading); - const [expanded, setExpanded] = useState(!metricId || metricId === 'create'); - const hasChanged = useObserver(() => widget.hasChanged); - const dashboards = useObserver(() => dashboardStore.dashboards); - const dashboard = useObserver(() => dashboards.find((d: any) => d.dashboardId == dashboardId)); - const dashboardName = dashboard ? dashboard.name : null; - const [metricNotFound, setMetricNotFound] = useState(false); - const history = useHistory(); - const [initialInstance, setInitialInstance] = useState(); - const isClickMap = widget.metricType === CLICKMAP; + const { + match: { + params: { siteId, dashboardId, metricId }, + }, + } = props; + // const siteId = location.pathname.split('/')[1]; + // const dashboardId = location.pathname.split('/')[3]; + const { metricStore, dashboardStore } = useStore(); + const widget = useObserver(() => metricStore.instance); + const loading = useObserver(() => metricStore.isLoading); + const [expanded, setExpanded] = useState(!metricId || metricId === 'create'); + const hasChanged = useObserver(() => widget.hasChanged); + const dashboards = useObserver(() => dashboardStore.dashboards); + const dashboard = useObserver(() => + dashboards.find((d: any) => d.dashboardId == dashboardId) + ); + const dashboardName = dashboard ? dashboard.name : null; + const [metricNotFound, setMetricNotFound] = useState(false); + const history = useHistory(); + const [initialInstance, setInitialInstance] = useState(); + const isClickMap = widget.metricType === CLICKMAP; - React.useEffect(() => { - if (metricId && metricId !== 'create') { - metricStore.fetch(metricId, dashboardStore.period).catch((e) => { - if (e.response.status === 404 || e.response.status === 422) { - setMetricNotFound(true); - } - }); - } else { - metricStore.init(); + React.useEffect(() => { + if (metricId && metricId !== 'create') { + metricStore.fetch(metricId, dashboardStore.period).catch((e) => { + if (e.response.status === 404 || e.response.status === 422) { + setMetricNotFound(true); } - }, []); + }); + } else { + metricStore.init(); + } + }, []); - // const onBackHandler = () => { - // props.history.goBack(); - // }; - // - // const openEdit = () => { - // if (expanded) return; - // setExpanded(true); - // }; + // const onBackHandler = () => { + // props.history.goBack(); + // }; + // + // const openEdit = () => { + // if (expanded) return; + // setExpanded(true); + // }; - const undoChanges = () => { - const w = new Widget(); - metricStore.merge(w.fromJson(initialInstance), false); - }; + const undoChanges = () => { + const w = new Widget(); + metricStore.merge(w.fromJson(initialInstance), false); + }; - const onSave = async () => { - const wasCreating = !widget.exists(); - if (isClickMap) { - try { - widget.thumbnail = await renderClickmapThumbnail(); - } catch (e) { - console.error(e); - } - } - const savedMetric = await metricStore.save(widget); - setInitialInstance(widget.toJson()); - if (wasCreating) { - if (parseInt(dashboardId, 10) > 0) { - history.replace( - withSiteId(dashboardMetricDetails(dashboardId, savedMetric.metricId), siteId) - ); - void dashboardStore.addWidgetToDashboard( - dashboardStore.getDashboard(parseInt(dashboardId, 10))!, - [savedMetric.metricId] - ); - } else { - history.replace(withSiteId(metricDetails(savedMetric.metricId), siteId)); - } - } - }; + const onSave = async () => { + const wasCreating = !widget.exists(); + if (isClickMap) { + try { + widget.sessionId = widget.data.sessionId; + widget.thumbnail = await renderClickmapThumbnail(); + } catch (e) { + console.error(e); + } + } + const savedMetric = await metricStore.save(widget); + setInitialInstance(widget.toJson()); + if (wasCreating) { + if (parseInt(dashboardId, 10) > 0) { + history.replace( + withSiteId( + dashboardMetricDetails(dashboardId, savedMetric.metricId), + siteId + ) + ); + void dashboardStore.addWidgetToDashboard( + dashboardStore.getDashboard(parseInt(dashboardId, 10))!, + [savedMetric.metricId] + ); + } else { + history.replace( + withSiteId(metricDetails(savedMetric.metricId), siteId) + ); + } + } + }; - return useObserver(() => ( - - { - if (location.pathname.includes('/metrics/') || location.pathname.includes('/metric/')) { - return true; - } - return 'You have unsaved changes. Are you sure you want to leave?'; - }} - /> + return useObserver(() => ( + + { + if ( + location.pathname.includes('/metrics/') || + location.pathname.includes('/metric/') + ) { + return true; + } + return 'You have unsaved changes. Are you sure you want to leave?'; + }} + /> -
- - - -
Metric not found!
-
- } - > - - - - - - {/*
*/} - {/* */} - {/*
*/} - - - - {widget.metricOf !== FilterKey.SESSIONS && widget.metricOf !== FilterKey.ERRORS && ( - <> - {(widget.metricType === TABLE || widget.metricType === TIMESERIES || widget.metricType === CLICKMAP || widget.metricType === INSIGHTS) && - } - {widget.metricType === FUNNEL && } - - )} - - {widget.metricType === USER_PATH && } - {widget.metricType === RETENTION && } -
- +
+ + + +
Metric not found!
-
- )); + } + > + + + + + + + + {widget.metricOf !== FilterKey.SESSIONS && + widget.metricOf !== FilterKey.ERRORS && ( + <> + {(widget.metricType === TABLE || + widget.metricType === TIMESERIES || + widget.metricType === CLICKMAP || + widget.metricType === INSIGHTS) && } + {widget.metricType === FUNNEL && } + + )} + + {widget.metricType === USER_PATH && } + {widget.metricType === RETENTION && } + + +
+ + )); } export default WidgetView; diff --git a/frontend/app/components/Dashboard/components/WidgetWrapper/WidgetWrapper.tsx b/frontend/app/components/Dashboard/components/WidgetWrapper/WidgetWrapper.tsx index 0a342af52..85e9588d8 100644 --- a/frontend/app/components/Dashboard/components/WidgetWrapper/WidgetWrapper.tsx +++ b/frontend/app/components/Dashboard/components/WidgetWrapper/WidgetWrapper.tsx @@ -26,7 +26,7 @@ interface Props { active?: boolean; history?: any; onClick?: () => void; - isWidget?: boolean; + isSaved?: boolean; hideName?: boolean; grid?: string; isGridView?: boolean; @@ -34,7 +34,7 @@ interface Props { function WidgetWrapper(props: Props & RouteComponentProps) { const { dashboardStore } = useStore(); const { - isWidget = false, + isSaved = false, active = false, index = 0, moveListItem = null, @@ -78,7 +78,7 @@ function WidgetWrapper(props: Props & RouteComponentProps) { }; const onChartClick = () => { - if (!isWidget || isPredefined) return; + if (!isSaved || isPredefined) return; props.history.push( withSiteId(dashboardMetricDetails(dashboard?.dashboardId, widget.metricId), siteId) @@ -90,7 +90,7 @@ function WidgetWrapper(props: Props & RouteComponentProps) { const addOverlay = isTemplate || (!isPredefined && - isWidget && + isSaved && widget.metricOf !== FilterKey.ERRORS && widget.metricOf !== FilterKey.SESSIONS); @@ -99,7 +99,7 @@ function WidgetWrapper(props: Props & RouteComponentProps) { className={cn( 'relative rounded bg-white border group rounded-lg', 'col-span-' + widget.config.col, - { 'hover:shadow-border-gray': !isTemplate && isWidget }, + { 'hover:shadow-border-gray': !isTemplate && isSaved }, { 'hover:shadow-border-main': isTemplate } )} style={{ @@ -112,7 +112,7 @@ function WidgetWrapper(props: Props & RouteComponentProps) { onClick={props.onClick ? props.onClick : () => {}} id={`widget-${widget.widgetId}`} > - {!isTemplate && isWidget && isPredefined && ( + {!isTemplate && isSaved && isPredefined && (
}
{!props.hideName ? ( @@ -134,7 +134,7 @@ function WidgetWrapper(props: Props & RouteComponentProps) {
) : null} - {isWidget && ( + {isSaved && (
{!isPredefined && isTimeSeries && !isGridView && ( <> @@ -171,7 +171,7 @@ function WidgetWrapper(props: Props & RouteComponentProps) { isPreview={isPreview} metric={widget} isTemplate={isTemplate} - isWidget={isWidget} + isSaved={isSaved} />
diff --git a/frontend/app/components/Dashboard/components/WidgetWrapper/WidgetWrapperNew.tsx b/frontend/app/components/Dashboard/components/WidgetWrapper/WidgetWrapperNew.tsx index 8fb7bec07..a740b0f2f 100644 --- a/frontend/app/components/Dashboard/components/WidgetWrapper/WidgetWrapperNew.tsx +++ b/frontend/app/components/Dashboard/components/WidgetWrapper/WidgetWrapperNew.tsx @@ -27,7 +27,7 @@ interface Props { active?: boolean; history?: any; onClick?: () => void; - isWidget?: boolean; + isSaved?: boolean; hideName?: boolean; grid?: string; isGridView?: boolean; @@ -36,7 +36,7 @@ interface Props { function WidgetWrapperNew(props: Props & RouteComponentProps) { const {dashboardStore} = useStore(); const { - isWidget = false, + isSaved = false, active = false, index = 0, moveListItem = null, @@ -75,7 +75,7 @@ function WidgetWrapperNew(props: Props & RouteComponentProps) { }); const onChartClick = () => { - if (!isWidget || isPredefined) return; + if (!isSaved || isPredefined) return; props.history.push( withSiteId(dashboardMetricDetails(dashboard?.dashboardId, widget.metricId), siteId) ); @@ -86,7 +86,7 @@ function WidgetWrapperNew(props: Props & RouteComponentProps) { const addOverlay = isTemplate || (!isPredefined && - isWidget && + isSaved && widget.metricOf !== FilterKey.ERRORS && widget.metricOf !== FilterKey.SESSIONS); @@ -95,7 +95,7 @@ function WidgetWrapperNew(props: Props & RouteComponentProps) { className={cn( 'relative group', 'col-span-' + widget.config.col, - {'hover:shadow': !isTemplate && isWidget}, + {'hover:shadow': !isTemplate && isSaved}, )} style={{ userSelect: 'none', @@ -107,7 +107,7 @@ function WidgetWrapperNew(props: Props & RouteComponentProps) { onClick={props.onClick ? props.onClick : () => null} id={`widget-${widget.widgetId}`} title={!props.hideName ? widget.name : null} - extra={isWidget ? [ + extra={isSaved ? [
{!isPredefined && isTimeSeries && !isGridView && ( @@ -131,7 +131,7 @@ function WidgetWrapperNew(props: Props & RouteComponentProps) { }, }} > - {!isTemplate && isWidget && isPredefined && ( + {!isTemplate && isSaved && isPredefined && (
@@ -148,7 +148,7 @@ function WidgetWrapperNew(props: Props & RouteComponentProps) { isPreview={isPreview} metric={widget} isTemplate={isTemplate} - isWidget={isWidget} + isSaved={isSaved} />
diff --git a/frontend/app/components/shared/Filters/FilterList/FilterList.tsx b/frontend/app/components/shared/Filters/FilterList/FilterList.tsx index c02d49d00..72cd8bbf0 100644 --- a/frontend/app/components/shared/Filters/FilterList/FilterList.tsx +++ b/frontend/app/components/shared/Filters/FilterList/FilterList.tsx @@ -147,7 +147,7 @@ function FilterList(props: Props) { width: 'calc(100% + 2.5rem)', }} className={ - 'hover:bg-active-blue px-5 gap-2 items-center flex' + 'hover:bg-active-blue px-5 gap-2 items-center flex z-10' } id={`${filter.key}-${filterIndex}`} onDragOver={(e) => handleDragOverEv(e, filterIndex)} diff --git a/frontend/app/components/ui/Divider.tsx b/frontend/app/components/ui/Divider.tsx index ce612d700..14d98b5bc 100644 --- a/frontend/app/components/ui/Divider.tsx +++ b/frontend/app/components/ui/Divider.tsx @@ -1,13 +1,8 @@ import React from 'react'; import { Divider as AntdDivider, DividerProps as AntdDividerProps } from 'antd'; - -interface DividerProps extends AntdDividerProps { - customProp?: boolean; -} - -const Divider: React.FC = ({ customProp, ...restProps }) => { - return ; +const Divider: React.FC = (props: AntdDividerProps) => { + return ; }; export default Divider; \ No newline at end of file diff --git a/frontend/app/components/ui/Icons/pdf_download.tsx b/frontend/app/components/ui/Icons/pdf_download.tsx index f7f773277..16ea79523 100644 --- a/frontend/app/components/ui/Icons/pdf_download.tsx +++ b/frontend/app/components/ui/Icons/pdf_download.tsx @@ -12,7 +12,7 @@ interface Props { function Pdf_download(props: Props) { const { size = 14, width = size, height = size, fill = '' } = props; return ( - + ); } diff --git a/frontend/app/components/ui/Icons/pencil.tsx b/frontend/app/components/ui/Icons/pencil.tsx index 1c9714adf..aa38965da 100644 --- a/frontend/app/components/ui/Icons/pencil.tsx +++ b/frontend/app/components/ui/Icons/pencil.tsx @@ -12,7 +12,7 @@ interface Props { function Pencil(props: Props) { const { size = 14, width = size, height = size, fill = '' } = props; return ( - + ); } diff --git a/frontend/app/components/ui/Icons/trash.tsx b/frontend/app/components/ui/Icons/trash.tsx index ded64f33b..286f4a6e0 100644 --- a/frontend/app/components/ui/Icons/trash.tsx +++ b/frontend/app/components/ui/Icons/trash.tsx @@ -12,7 +12,7 @@ interface Props { function Trash(props: Props) { const { size = 14, width = size, height = size, fill = '' } = props; return ( - + ); } diff --git a/frontend/app/components/ui/Icons/users.tsx b/frontend/app/components/ui/Icons/users.tsx index b5bc58d21..bc6a852d6 100644 --- a/frontend/app/components/ui/Icons/users.tsx +++ b/frontend/app/components/ui/Icons/users.tsx @@ -12,8 +12,7 @@ interface Props { function Users(props: Props) { const { size = 14, width = size, height = size, fill = '' } = props; return ( - - + ); } diff --git a/frontend/app/layout/SideMenu.tsx b/frontend/app/layout/SideMenu.tsx index e96cdc297..6875a83ef 100644 --- a/frontend/app/layout/SideMenu.tsx +++ b/frontend/app/layout/SideMenu.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { Divider, Menu, Typography } from 'antd'; +import { Menu, Typography } from 'antd'; import SVG from 'UI/SVG'; import * as routes from 'App/routes'; import { bookmarks, client, CLIENT_DEFAULT_TAB, CLIENT_TABS, fflags, notes, sessions, withSiteId } from 'App/routes'; @@ -8,7 +8,7 @@ import { categories as main_menu, MENU, preferences, PREFERENCES_MENU } from './ import { connect } from 'react-redux'; import { MODULES } from 'Components/Client/Modules'; import cn from 'classnames'; -import { Icon } from 'UI'; +import { Icon, Divider } from 'UI'; import SupportModal from 'App/layout/SupportModal'; import { setActiveTab } from 'Duck/search'; diff --git a/frontend/app/mstore/dashboardStore.ts b/frontend/app/mstore/dashboardStore.ts index 1a0456d55..0c1464815 100644 --- a/frontend/app/mstore/dashboardStore.ts +++ b/frontend/app/mstore/dashboardStore.ts @@ -410,7 +410,7 @@ export default class DashboardStore { fetchMetricChartData( metric: Widget, data: any, - isWidget: boolean = false, + isSaved: boolean = false, period: Record ): Promise { period = period.toTimestamps(); @@ -425,7 +425,7 @@ export default class DashboardStore { this.pendingRequests += 1; try { - const data = await metricService.getMetricChartData(metric, params, isWidget); + const data = await metricService.getMetricChartData(metric, params, isSaved); resolve(metric.setData(data, period)); } catch (error) { reject(error); diff --git a/frontend/app/mstore/types/widget.ts b/frontend/app/mstore/types/widget.ts index 90606c99f..a9955bb3c 100644 --- a/frontend/app/mstore/types/widget.ts +++ b/frontend/app/mstore/types/widget.ts @@ -85,6 +85,7 @@ export default class Widget { page: number = 1; limit: number = 5; thumbnail?: string; + sessionId?: string; params: any = {density: 70}; startType: string = 'start'; startPoint: FilterItem = new FilterItem(filtersMap[FilterKey.LOCATION]); @@ -165,6 +166,7 @@ export default class Widget { this.predefinedKey = json.predefinedKey; this.category = json.category; this.thumbnail = json.thumbnail; + this.sessionId = json.sessionId; this.isPublic = json.isPublic; if (this.metricType === FUNNEL) { @@ -220,6 +222,7 @@ export default class Widget { name: this.name, series: this.series.map((series: any) => series.toJson()), thumbnail: this.thumbnail, + sessionId: this.sessionId, page: this.page, limit: this.limit, config: { diff --git a/frontend/app/player/web/MessageManager.ts b/frontend/app/player/web/MessageManager.ts index 43e033690..91e6b6817 100644 --- a/frontend/app/player/web/MessageManager.ts +++ b/frontend/app/player/web/MessageManager.ts @@ -202,10 +202,15 @@ export default class MessageManager { namesObj[tabId] = '' } } + lastMsgArr.sort((a, b) => a[1] - b[1]) - lastMsgArr.forEach(([tabId, lastMessageTs]) => { - this.tabCloseManager.append({ tabId, time: lastMessageTs }) - }) + if (Object.keys(namesObj).length === 1) { + this.tabCloseManager.append({ tabId: lastMsgArr[0][0], time: this.session.durationMs - 250 }) + } else { + lastMsgArr.forEach(([tabId, lastMessageTs]) => { + this.tabCloseManager.append({ tabId, time: lastMessageTs }) + }) + } this.state.update({ tabNames: namesObj }) } diff --git a/frontend/app/services/MetricService.ts b/frontend/app/services/MetricService.ts index db97ec27c..97db7dccd 100644 --- a/frontend/app/services/MetricService.ts +++ b/frontend/app/services/MetricService.ts @@ -72,7 +72,7 @@ export default class MetricService { .then((response: { data: any; }) => response.data || []); } - async getMetricChartData(metric: Widget, data: any, isWidget: boolean = false): Promise { + async getMetricChartData(metric: Widget, data: any, isSaved: boolean = false): Promise { if ( metric.metricType === CLICKMAP && document.location.pathname.split('/').pop() === 'metrics' @@ -80,7 +80,7 @@ export default class MetricService { ) { return Promise.resolve({}); } - const path = isWidget ? `/cards/${metric.metricId}/chart` : `/cards/try`; + const path = isSaved ? `/cards/${metric.metricId}/chart` : `/cards/try`; if (metric.metricType === USER_PATH) { data.density = 5; data.metricOf = 'sessionCount';