fix ui: fix tab close calculation, fix widget preview request type
This commit is contained in:
parent
93a60de04b
commit
afc6b495c5
22 changed files with 273 additions and 328 deletions
|
|
@ -73,7 +73,7 @@ function CardsLibrary(props: Props) {
|
|||
// isPreview={true}
|
||||
metric={metric}
|
||||
isTemplate={true}
|
||||
isWidget={true}
|
||||
isSaved={true}
|
||||
/>
|
||||
</Card>
|
||||
</LazyLoad>
|
||||
|
|
|
|||
|
|
@ -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)}
|
||||
/>
|
||||
))}
|
||||
|
|
|
|||
|
|
@ -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)}
|
||||
/>
|
||||
))
|
||||
|
|
|
|||
|
|
@ -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)}
|
||||
/>
|
||||
</React.Fragment>
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ function DashboardWidgetGrid(props: Props) {
|
|||
|
||||
} dashboardId={dashboardId}
|
||||
siteId={siteId}
|
||||
isWidget={true}
|
||||
isSaved={true}
|
||||
grid="vitals"
|
||||
/>
|
||||
</React.Fragment>
|
||||
|
|
@ -102,7 +102,7 @@ function DashboardWidgetGrid(props: Props) {
|
|||
}
|
||||
dashboardId={dashboardId}
|
||||
siteId={siteId}
|
||||
isWidget={true}
|
||||
isSaved={true}
|
||||
grid="other"
|
||||
/>
|
||||
</React.Fragment>
|
||||
|
|
|
|||
|
|
@ -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))}
|
||||
/>
|
||||
</React.Fragment>
|
||||
|
|
|
|||
|
|
@ -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 <FunnelWidget metric={metric} data={data} isWidget={isWidget || isTemplate}/>;
|
||||
return <FunnelWidget metric={metric} data={data} isWidget={isSaved || isTemplate}/>;
|
||||
}
|
||||
|
||||
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}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
<>
|
||||
<div className={cn(className, 'bg-white rounded-xl border shadow-sm mt-0')}>
|
||||
<div className="flex items-center justify-between px-4 pt-2">
|
||||
<h2 className="text-xl">
|
||||
{props.name}
|
||||
</h2>
|
||||
<div className="flex items-center">
|
||||
{metric.metricType === USER_PATH && (
|
||||
<a
|
||||
href="#"
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
metric.update({hideExcess: !metric.hideExcess});
|
||||
}}
|
||||
>
|
||||
<Space>
|
||||
<Switch
|
||||
checked={metric.hideExcess}
|
||||
size="small"
|
||||
/>
|
||||
<span className="mr-4 color-gray-medium">Hide Minor Paths</span>
|
||||
</Space>
|
||||
</a>
|
||||
)}
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
className={cn(className, 'bg-white rounded-xl border shadow-sm mt-0')}
|
||||
>
|
||||
<div className="flex items-center justify-between px-4 pt-2">
|
||||
<h2 className="text-xl">{props.name}</h2>
|
||||
<div className="flex items-center">
|
||||
{metric.metricType === USER_PATH && (
|
||||
<a
|
||||
href="#"
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
metric.update({ hideExcess: !metric.hideExcess });
|
||||
}}
|
||||
>
|
||||
<Space>
|
||||
<Switch checked={metric.hideExcess} size="small" />
|
||||
<span className="mr-4 color-gray-medium">
|
||||
Hide Minor Paths
|
||||
</span>
|
||||
</Space>
|
||||
</a>
|
||||
)}
|
||||
|
||||
{/*{isTimeSeries && (*/}
|
||||
{/* <>*/}
|
||||
{/* <span className="mr-4 color-gray-medium">Visualization</span>*/}
|
||||
{/* <SegmentSelection*/}
|
||||
{/* name="viewType"*/}
|
||||
{/* className="my-3"*/}
|
||||
{/* primary*/}
|
||||
{/* size="small"*/}
|
||||
{/* onSelect={ changeViewType }*/}
|
||||
{/* value={{ value: metric.viewType }}*/}
|
||||
{/* list={ [*/}
|
||||
{/* { value: 'lineChart', name: 'Chart', icon: 'graph-up-arrow' },*/}
|
||||
{/* { value: 'progress', name: 'Progress', icon: 'hash' },*/}
|
||||
{/* ]}*/}
|
||||
{/* />*/}
|
||||
{/* </>*/}
|
||||
{/*)}*/}
|
||||
|
||||
{/*{!disableVisualization && isTable && (*/}
|
||||
{/* <>*/}
|
||||
{/* <span className="mr-4 color-gray-medium">Visualization</span>*/}
|
||||
{/* <SegmentSelection*/}
|
||||
{/* name="viewType"*/}
|
||||
{/* className="my-3"*/}
|
||||
{/* primary={true}*/}
|
||||
{/* size="small"*/}
|
||||
{/* onSelect={ changeViewType }*/}
|
||||
{/* value={{ value: metric.viewType }}*/}
|
||||
{/* list={[*/}
|
||||
{/* { value: 'table', name: 'Table', icon: 'table' },*/}
|
||||
{/* { value: 'pieChart', name: 'Chart', icon: 'pie-chart-fill' },*/}
|
||||
{/* ]}*/}
|
||||
{/* disabledMessage="Chart view is not supported"*/}
|
||||
{/* />*/}
|
||||
{/* </>*/}
|
||||
{/*)}*/}
|
||||
|
||||
{/*{isRetention && (*/}
|
||||
{/* <>*/}
|
||||
{/* <span className="mr-4 color-gray-medium">Visualization</span>*/}
|
||||
{/* <SegmentSelection*/}
|
||||
{/* name="viewType"*/}
|
||||
{/* className="my-3"*/}
|
||||
{/* primary={true}*/}
|
||||
{/* size="small"*/}
|
||||
{/* onSelect={ changeViewType }*/}
|
||||
{/* value={{ value: metric.viewType }}*/}
|
||||
{/* list={[*/}
|
||||
{/* { value: 'trend', name: 'Trend', icon: 'graph-up-arrow' },*/}
|
||||
{/* { value: 'cohort', name: 'Cohort', icon: 'dice-3' },*/}
|
||||
{/* ]}*/}
|
||||
{/* disabledMessage="Chart view is not supported"*/}
|
||||
{/* />*/}
|
||||
{/*</>*/}
|
||||
{/*)}*/}
|
||||
|
||||
<div className="mx-4"/>
|
||||
{metric.metricType === CLICKMAP ? (
|
||||
<ClickMapRagePicker/>
|
||||
) : null}
|
||||
|
||||
|
||||
{/* add to dashboard */}
|
||||
{/*{metric.exists() && (*/}
|
||||
{/* <AddToDashboardButton metricId={metric.metricId}/>*/}
|
||||
{/*)}*/}
|
||||
</div>
|
||||
</div>
|
||||
<div className="pt-0">
|
||||
<WidgetWrapper widget={metric} isPreview={true} isWidget={false} hideName/>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
<div className="mx-4" />
|
||||
{metric.metricType === CLICKMAP ? <ClickMapRagePicker /> : null}
|
||||
</div>
|
||||
</div>
|
||||
<div className="pt-0">
|
||||
<WidgetWrapper
|
||||
widget={metric}
|
||||
isPreview={true}
|
||||
isSaved={metric.exists()}
|
||||
hideName
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default observer(WidgetPreview);
|
||||
|
|
|
|||
|
|
@ -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(() => (
|
||||
<Loader loading={loading}>
|
||||
<Prompt
|
||||
when={hasChanged}
|
||||
message={(location: any) => {
|
||||
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(() => (
|
||||
<Loader loading={loading}>
|
||||
<Prompt
|
||||
when={hasChanged}
|
||||
message={(location: any) => {
|
||||
if (
|
||||
location.pathname.includes('/metrics/') ||
|
||||
location.pathname.includes('/metric/')
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
return 'You have unsaved changes. Are you sure you want to leave?';
|
||||
}}
|
||||
/>
|
||||
|
||||
<div style={{maxWidth: '1360px', margin: 'auto'}}>
|
||||
<Breadcrumb
|
||||
items={[
|
||||
{
|
||||
label: dashboardName ? dashboardName : 'Cards',
|
||||
to: dashboardId ? withSiteId('/dashboard/' + dashboardId, siteId) : withSiteId('/metrics', siteId),
|
||||
},
|
||||
{label: widget.name},
|
||||
]}
|
||||
/>
|
||||
<NoContent
|
||||
show={metricNotFound}
|
||||
title={
|
||||
<div className="flex flex-col items-center justify-between">
|
||||
<AnimatedSVG name={ICONS.EMPTY_STATE} size={100}/>
|
||||
<div className="mt-4">Metric not found!</div>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<Space direction="vertical" size={20} className="w-full">
|
||||
<WidgetViewHeader onSave={onSave} undoChanges={undoChanges}/>
|
||||
|
||||
<WidgetFormNew/>
|
||||
|
||||
{/*<div className="bg-white rounded border mt-3">*/}
|
||||
{/* <WidgetForm expanded={expanded} onDelete={onBackHandler} {...props} />*/}
|
||||
{/*</div>*/}
|
||||
|
||||
<WidgetPreview name={widget.name} isEditing={expanded}/>
|
||||
|
||||
{widget.metricOf !== FilterKey.SESSIONS && widget.metricOf !== FilterKey.ERRORS && (
|
||||
<>
|
||||
{(widget.metricType === TABLE || widget.metricType === TIMESERIES || widget.metricType === CLICKMAP || widget.metricType === INSIGHTS) &&
|
||||
<WidgetSessions/>}
|
||||
{widget.metricType === FUNNEL && <FunnelIssues/>}
|
||||
</>
|
||||
)}
|
||||
|
||||
{widget.metricType === USER_PATH && <CardIssues/>}
|
||||
{widget.metricType === RETENTION && <CardUserList/>}
|
||||
</Space>
|
||||
</NoContent>
|
||||
<div style={{ maxWidth: '1360px', margin: 'auto' }}>
|
||||
<Breadcrumb
|
||||
items={[
|
||||
{
|
||||
label: dashboardName ? dashboardName : 'Cards',
|
||||
to: dashboardId
|
||||
? withSiteId('/dashboard/' + dashboardId, siteId)
|
||||
: withSiteId('/metrics', siteId),
|
||||
},
|
||||
{ label: widget.name },
|
||||
]}
|
||||
/>
|
||||
<NoContent
|
||||
show={metricNotFound}
|
||||
title={
|
||||
<div className="flex flex-col items-center justify-between">
|
||||
<AnimatedSVG name={ICONS.EMPTY_STATE} size={100} />
|
||||
<div className="mt-4">Metric not found!</div>
|
||||
</div>
|
||||
</Loader>
|
||||
));
|
||||
}
|
||||
>
|
||||
<Space direction="vertical" size={20} className="w-full">
|
||||
<WidgetViewHeader onSave={onSave} undoChanges={undoChanges} />
|
||||
|
||||
<WidgetFormNew />
|
||||
|
||||
<WidgetPreview name={widget.name} isEditing={expanded} />
|
||||
|
||||
{widget.metricOf !== FilterKey.SESSIONS &&
|
||||
widget.metricOf !== FilterKey.ERRORS && (
|
||||
<>
|
||||
{(widget.metricType === TABLE ||
|
||||
widget.metricType === TIMESERIES ||
|
||||
widget.metricType === CLICKMAP ||
|
||||
widget.metricType === INSIGHTS) && <WidgetSessions />}
|
||||
{widget.metricType === FUNNEL && <FunnelIssues />}
|
||||
</>
|
||||
)}
|
||||
|
||||
{widget.metricType === USER_PATH && <CardIssues />}
|
||||
{widget.metricType === RETENTION && <CardUserList />}
|
||||
</Space>
|
||||
</NoContent>
|
||||
</div>
|
||||
</Loader>
|
||||
));
|
||||
}
|
||||
|
||||
export default WidgetView;
|
||||
|
|
|
|||
|
|
@ -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 && (
|
||||
<div
|
||||
className={cn(
|
||||
stl.drillDownMessage,
|
||||
|
|
@ -126,7 +126,7 @@ function WidgetWrapper(props: Props & RouteComponentProps) {
|
|||
{addOverlay && <TemplateOverlay onClick={onChartClick} isTemplate={isTemplate} />}
|
||||
<div
|
||||
className={cn('p-3 pb-4 flex items-center justify-between', {
|
||||
'cursor-move': !isTemplate && isWidget,
|
||||
'cursor-move': !isTemplate && isSaved,
|
||||
})}
|
||||
>
|
||||
{!props.hideName ? (
|
||||
|
|
@ -134,7 +134,7 @@ function WidgetWrapper(props: Props & RouteComponentProps) {
|
|||
<TextEllipsis text={widget.name} />
|
||||
</div>
|
||||
) : null}
|
||||
{isWidget && (
|
||||
{isSaved && (
|
||||
<div className="flex items-center" id="no-print">
|
||||
{!isPredefined && isTimeSeries && !isGridView && (
|
||||
<>
|
||||
|
|
@ -171,7 +171,7 @@ function WidgetWrapper(props: Props & RouteComponentProps) {
|
|||
isPreview={isPreview}
|
||||
metric={widget}
|
||||
isTemplate={isTemplate}
|
||||
isWidget={isWidget}
|
||||
isSaved={isSaved}
|
||||
/>
|
||||
</div>
|
||||
</LazyLoad>
|
||||
|
|
|
|||
|
|
@ -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 ? [
|
||||
<div className="flex items-center" id="no-print">
|
||||
{!isPredefined && isTimeSeries && !isGridView && (
|
||||
<AlertButton seriesId={widget.series[0] && widget.series[0].seriesId}/>
|
||||
|
|
@ -131,7 +131,7 @@ function WidgetWrapperNew(props: Props & RouteComponentProps) {
|
|||
},
|
||||
}}
|
||||
>
|
||||
{!isTemplate && isWidget && isPredefined && (
|
||||
{!isTemplate && isSaved && isPredefined && (
|
||||
<Tooltip title="Cannot drill down system provided metrics">
|
||||
<div
|
||||
className={cn(stl.drillDownMessage, 'disabled text-gray text-sm invisible group-hover:visible')}>
|
||||
|
|
@ -148,7 +148,7 @@ function WidgetWrapperNew(props: Props & RouteComponentProps) {
|
|||
isPreview={isPreview}
|
||||
metric={widget}
|
||||
isTemplate={isTemplate}
|
||||
isWidget={isWidget}
|
||||
isSaved={isSaved}
|
||||
/>
|
||||
</div>
|
||||
</LazyLoad>
|
||||
|
|
|
|||
|
|
@ -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)}
|
||||
|
|
|
|||
|
|
@ -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<DividerProps> = ({ customProp, ...restProps }) => {
|
||||
return <AntdDivider {...restProps} />;
|
||||
const Divider: React.FC = (props: AntdDividerProps) => {
|
||||
return <AntdDivider className={props.className} style={props.style} />;
|
||||
};
|
||||
|
||||
export default Divider;
|
||||
|
|
@ -12,7 +12,7 @@ interface Props {
|
|||
function Pdf_download(props: Props) {
|
||||
const { size = 14, width = size, height = size, fill = '' } = props;
|
||||
return (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width={ `${ width }px` } height={ `${ height }px` } viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-file-down"><path d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z"/><path d="M14 2v4a2 2 0 0 0 2 2h4"/><path d="M12 18v-6"/><path d="m9 15 3 3 3-3"/></svg>
|
||||
<svg viewBox="0 0 19 19" width={ `${ width }px` } height={ `${ height }px` } ><path d="M10.094 5.249a.594.594 0 0 0-1.188 0v4.504l-1.36-1.362a.595.595 0 0 0-.841.84l2.375 2.376a.596.596 0 0 0 .84 0l2.375-2.375a.595.595 0 0 0-.84-.841l-1.361 1.362V5.249Z"/><path d="M16.625 16.625V5.344L11.281 0H4.75a2.375 2.375 0 0 0-2.375 2.375v14.25A2.375 2.375 0 0 0 4.75 19h9.5a2.375 2.375 0 0 0 2.375-2.375ZM11.281 3.562a1.781 1.781 0 0 0 1.781 1.782h2.376v11.281a1.188 1.188 0 0 1-1.188 1.188h-9.5a1.187 1.187 0 0 1-1.188-1.188V2.375A1.188 1.188 0 0 1 4.75 1.187h6.531v2.375Z"/><path clipRule="evenodd" d="M15.58 13.49H3.42v4.37h1.789v-3.512H6.61c.282 0 .524.051.726.154.205.103.361.245.47.425.11.178.165.383.165.613 0 .226-.055.424-.164.593-.11.169-.266.3-.47.396-.203.093-.445.14-.727.14h-.554v1.191h2.37v-3.512h1.13c.238 0 .455.041.653.123a1.537 1.537 0 0 1 .854.88c.08.205.12.431.12.68v.148c0 .247-.04.474-.12.68a1.512 1.512 0 0 1-.849.88c-.193.08-.404.12-.635.121h2.046v-3.512h2.35v.654h-1.503v.808h1.365v.651h-1.365v1.399h3.108v-4.37Zm-9.524 1.512v1.013h.554c.12 0 .216-.02.29-.06a.367.367 0 0 0 .161-.167.547.547 0 0 0 .054-.244.668.668 0 0 0-.054-.267.431.431 0 0 0-.161-.198.496.496 0 0 0-.29-.077h-.554Zm3.512 2.207h-.295v-2.207h.283c.123 0 .233.021.328.065a.604.604 0 0 1 .24.195.88.88 0 0 1 .146.321c.033.127.05.275.05.444v.152c0 .225-.03.415-.089.569a.707.707 0 0 1-.256.345.696.696 0 0 1-.407.116Z"/></svg>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ interface Props {
|
|||
function Pencil(props: Props) {
|
||||
const { size = 14, width = size, height = size, fill = '' } = props;
|
||||
return (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width={ `${ width }px` } height={ `${ height }px` } viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-file-pen-line"><path d="m18 5-2.414-2.414A2 2 0 0 0 14.172 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2"/><path d="M21.378 12.626a1 1 0 0 0-3.004-3.004l-4.01 4.012a2 2 0 0 0-.506.854l-.837 2.87a.5.5 0 0 0 .62.62l2.87-.837a2 2 0 0 0 .854-.506z"/><path d="M8 18h1"/></svg>
|
||||
<svg viewBox="0 0 16 16" width={ `${ width }px` } height={ `${ height }px` } ><path d="M12.146.146a.5.5 0 0 1 .708 0l3 3a.5.5 0 0 1 0 .708l-10 10a.5.5 0 0 1-.168.11l-5 2a.5.5 0 0 1-.65-.65l2-5a.5.5 0 0 1 .11-.168l10-10zM11.207 2.5 13.5 4.793 14.793 3.5 12.5 1.207 11.207 2.5zm1.586 3L10.5 3.207 4 9.707V10h.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.5h.293l6.5-6.5zm-9.761 5.175-.106.106-1.528 3.821 3.821-1.528.106-.106A.5.5 0 0 1 5 12.5V12h-.5a.5.5 0 0 1-.5-.5V11h-.5a.5.5 0 0 1-.468-.325z"/></svg>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ interface Props {
|
|||
function Trash(props: Props) {
|
||||
const { size = 14, width = size, height = size, fill = '' } = props;
|
||||
return (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width={ `${ width }px` } height={ `${ height }px` } viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-trash"><path d="M3 6h18"/><path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6"/><path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2"/></svg>
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" width={ `${ width }px` } height={ `${ height }px` } ><path d="M3 6h18M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2"/></svg>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,8 +12,7 @@ interface Props {
|
|||
function Users(props: Props) {
|
||||
const { size = 14, width = size, height = size, fill = '' } = props;
|
||||
return (
|
||||
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width={ `${ width }px` } height={ `${ height }px` } viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-users-round"><path d="M18 21a8 8 0 0 0-16 0"/><circle cx="10" cy="8" r="5"/><path d="M22 20c0-3.37-2-6.5-4-8a5 5 0 0 0-.45-8.3"/></svg>
|
||||
<svg viewBox="0 0 16 16" width={ `${ width }px` } height={ `${ height }px` } ><path d="M15 14s1 0 1-1-1-4-5-4-5 3-5 4 1 1 1 1h8zm-7.978-1A.261.261 0 0 1 7 12.996c.001-.264.167-1.03.76-1.72C8.312 10.629 9.282 10 11 10c1.717 0 2.687.63 3.24 1.276.593.69.758 1.457.76 1.72l-.008.002a.274.274 0 0 1-.014.002H7.022zM11 7a2 2 0 1 0 0-4 2 2 0 0 0 0 4zm3-2a3 3 0 1 1-6 0 3 3 0 0 1 6 0zM6.936 9.28a5.88 5.88 0 0 0-1.23-.247A7.35 7.35 0 0 0 5 9c-4 0-5 3-5 4 0 .667.333 1 1 1h4.216A2.238 2.238 0 0 1 5 13c0-1.01.377-2.042 1.09-2.904.243-.294.526-.569.846-.816zM4.92 10A5.493 5.493 0 0 0 4 13H1c0-.26.164-1.03.76-1.724.545-.636 1.492-1.256 3.16-1.275zM1.5 5.5a3 3 0 1 1 6 0 3 3 0 0 1-6 0zm3-2a2 2 0 1 0 0 4 2 2 0 0 0 0-4z"/></svg>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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';
|
||||
|
||||
|
|
|
|||
|
|
@ -410,7 +410,7 @@ export default class DashboardStore {
|
|||
fetchMetricChartData(
|
||||
metric: Widget,
|
||||
data: any,
|
||||
isWidget: boolean = false,
|
||||
isSaved: boolean = false,
|
||||
period: Record<string, any>
|
||||
): Promise<any> {
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -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: {
|
||||
|
|
|
|||
|
|
@ -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 })
|
||||
}
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ export default class MetricService {
|
|||
.then((response: { data: any; }) => response.data || []);
|
||||
}
|
||||
|
||||
async getMetricChartData(metric: Widget, data: any, isWidget: boolean = false): Promise<any> {
|
||||
async getMetricChartData(metric: Widget, data: any, isSaved: boolean = false): Promise<any> {
|
||||
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';
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue