import React, { useEffect } from 'react'; import Widget from 'App/mstore/types/widget'; import Funnelbar, { UxTFunnelBar } from "./FunnelBar"; import Funnel from 'App/mstore/types/funnel' import cn from 'classnames'; import stl from './FunnelWidget.module.css'; import { observer } from 'mobx-react-lite'; import { NoContent, Icon } from 'UI'; import { Tag, Tooltip } from 'antd'; import { useModal } from 'App/components/Modal'; import { useStore } from '@/mstore'; import Filter from '@/mstore/types/filter'; interface Props { metric?: Widget; isWidget?: boolean; data: { funnel: Funnel }; compData: { funnel: Funnel }; } function FunnelWidget(props: Props) { const { dashboardStore, searchStore } = useStore(); const [focusedFilter, setFocusedFilter] = React.useState(null); const { isWidget = false, data, metric, compData } = props; const funnel = data.funnel || { stages: [] }; const totalSteps = funnel.stages.length; const stages = isWidget ? [...funnel.stages.slice(0, 1), funnel.stages[funnel.stages.length - 1]] : funnel.stages; const hasMoreSteps = funnel.stages.length > 2; const lastStage = funnel.stages[funnel.stages.length - 1]; const remainingSteps = totalSteps - 2; const { hideModal } = useModal(); const metricLabel = metric?.metricFormat == 'userCount' ? 'Users' : 'Sessions'; const drillDownFilter = dashboardStore.drillDownFilter; const drillDownPeriod = dashboardStore.drillDownPeriod; const comparisonPeriod = metric ? dashboardStore.comparisonPeriods[metric.metricId] : undefined const metricFilters = metric?.series[0]?.filter.filters || []; const applyDrillDown = (index: number, isComp?: boolean) => { const filter = new Filter().fromData({ filters: metricFilters.slice(0, index + 1) }); const periodTimestamps = isComp && index > -1 ? comparisonPeriod.toTimestamps() : drillDownPeriod.toTimestamps(); drillDownFilter.merge({ filters: filter.toJson().filters, startTimestamp: periodTimestamps.startTimestamp, endTimestamp: periodTimestamps.endTimestamp }); }; useEffect(() => { return () => { if (isWidget) return; hideModal(); }; }, []); const focusStage = (index: number, isComp?: boolean) => { funnel.stages.forEach((s, i) => { // turning on all filters if one was focused already if (focusedFilter === index) { s.updateKey('isActive', true); setFocusedFilter(null); } else { setFocusedFilter(index); if (i === index) { s.updateKey('isActive', true); } else { s.updateKey('isActive', false); } } }); applyDrillDown(focusedFilter === index ? -1 : index, isComp); }; const shownStages = React.useMemo(() => { const stages: { data: Funnel['stages'][0], compData?: Funnel['stages'][0] }[] = []; for (let i = 0; i < funnel.stages.length; i++) { const stage: any = { data: funnel.stages[i], compData: undefined } const compStage = compData?.funnel.stages[i]; if (compStage) { stage.compData = compStage; } stages.push(stage) } return stages; }, [data, compData]) const viewType = metric?.viewType; const isHorizontal = viewType === 'columnChart'; return ( No data available for the selected period. } show={!stages || stages.length === 0} >
{!isWidget && shownStages.map((stage: any, index: any) => ( ))} {isWidget && ( <> {hasMoreSteps && ( <> )} {funnel.stages.length > 1 && ( )} )}
Total conversion {funnel.totalConversions}
Lost conversion {funnel.lostConversions}
{funnel.totalDropDueToIssues > 0 && (
{' '} {funnel.totalDropDueToIssues} sessions dropped due to issues.
)}
); } export const EmptyStage = observer(({ total }: any) => { return (
{`+${total} ${total > 1 ? 'steps' : 'step'}`}
); }); export const Stage = observer(({ metricLabel, stage, index, uxt, focusStage, focusedFilter, compData, isHorizontal, }: any) => { return stage ? (
{!uxt ? : }
) : null }) export const IndexNumber = observer(({ index }: any) => { return (
{index === 0 ? : index}
); }) export default observer(FunnelWidget);