fix(ui) - click maps count and percentage, dropdown

This commit is contained in:
Shekar Siri 2022-07-21 15:35:01 +02:00
parent b368dc3adf
commit a4f0b323c5
4 changed files with 133 additions and 134 deletions

View file

@ -1,6 +1,5 @@
import React, { useEffect, useState } from 'react';
import { Dropdown, Loader, Icon } from 'UI';
import DateRange from 'Shared/DateRange';
import { Loader, Icon } from 'UI';
import { connect } from 'react-redux';
import { fetchInsights } from 'Duck/sessions';
import SelectorsList from './components/SelectorsList/SelectorsList';
@ -11,100 +10,103 @@ import Period from 'Types/app/period';
const JUMP_OFFSET = 1000;
interface Props {
filters: any
fetchInsights: (filters: Record<string, any>) => void
urls: []
insights: any
events: Array<any>
urlOptions: Array<any>
loading: boolean
host: string
setActiveTab: (tab: string) => void
filters: any;
fetchInsights: (filters: Record<string, any>) => void;
urls: [];
insights: any;
events: Array<any>;
urlOptions: Array<any>;
loading: boolean;
host: string;
setActiveTab: (tab: string) => void;
}
function PageInsightsPanel({
filters, fetchInsights, events = [], insights, urlOptions, host, loading = true, setActiveTab
}: Props) {
const [insightsFilters, setInsightsFilters] = useState(filters)
const defaultValue = (urlOptions && urlOptions[0]) ? urlOptions[0].value : ''
function PageInsightsPanel({ filters, fetchInsights, events = [], insights, urlOptions, host, loading = true, setActiveTab }: Props) {
const [insightsFilters, setInsightsFilters] = useState(filters);
const defaultValue = urlOptions && urlOptions[0] ? urlOptions[0].value : '';
const period = new Period({
start: insightsFilters.startDate,
end: insightsFilters.endDate,
rangeName: insightsFilters.rangeValue
});
const period = Period({
start: insightsFilters.startDate,
end: insightsFilters.endDate,
rangeName: insightsFilters.rangeValue,
});
const onDateChange = (e) => {
const { startDate, endDate, rangeValue } = e.toJSON();
setInsightsFilters({ ...insightsFilters, startDate, endDate, rangeValue })
}
const onDateChange = (e: any) => {
const { startDate, endDate, rangeValue } = e.toJSON();
setInsightsFilters({ ...insightsFilters, startDate, endDate, rangeValue });
};
useEffect(() => {
markTargets(insights.toJS());
return () => {
markTargets(null)
}
}, [insights])
useEffect(() => {
markTargets(insights.toJS());
return () => {
markTargets(null);
};
}, [insights]);
useEffect(() => {
if (urlOptions && urlOptions[0]) {
const url = insightsFilters.url ? insightsFilters.url : host + urlOptions[0].value;
Player.pause();
fetchInsights({ ...insightsFilters, url })
}
}, [insightsFilters])
useEffect(() => {
if (urlOptions && urlOptions[0]) {
const url = insightsFilters.url ? insightsFilters.url : host + urlOptions[0].value;
Player.pause();
fetchInsights({ ...insightsFilters, url });
}
}, [insightsFilters]);
const onPageSelect = ({ value }: { value: Array<any> }) => {
const event = events.find(item => item.url === value)
Player.jump(event.time + JUMP_OFFSET)
setInsightsFilters({ ...insightsFilters, url: host + value })
markTargets([])
};
const onPageSelect = ({ value }: any) => {
const event = events.find((item) => item.url === value.value);
Player.jump(event.time + JUMP_OFFSET);
setInsightsFilters({ ...insightsFilters, url: host + value.value });
markTargets([]);
};
return (
<div className="p-4 bg-white">
<div className="pb-3 flex items-center" style={{ maxWidth: '241px', paddingTop: '5px' }}>
<div className="flex items-center">
<span className="mr-1 text-xl">Clicks</span>
<SelectDateRange period={period} onChange={onDateChange} disableCustom />
return (
<div className="p-4 bg-white">
<div className="pb-3 flex items-center" style={{ maxWidth: '241px', paddingTop: '5px' }}>
<div className="flex items-center">
<span className="mr-1 text-xl">Clicks</span>
<SelectDateRange period={period} onChange={onDateChange} disableCustom />
</div>
<div
onClick={() => {
setActiveTab('');
}}
className="ml-auto flex items-center justify-center bg-white cursor-pointer"
>
<Icon name="close" size="18" />
</div>
</div>
<div className="mb-4 flex items-center">
<div className="mr-2 flex-shrink-0">In Page</div>
<Select
isSearchable={true}
right
placeholder="change"
options={urlOptions}
name="url"
defaultValue={defaultValue}
onChange={onPageSelect}
id="change-dropdown"
className="w-full"
style={{ width: '100%' }}
/>
</div>
<Loader loading={loading}>
<SelectorsList />
</Loader>
</div>
<div
onClick={() => { setActiveTab(''); }}
className="ml-auto flex items-center justify-center bg-white cursor-pointer"
>
<Icon name="close" size="18" />
</div>
</div>
<div className="mb-4 flex items-center">
<div className="mr-2 flex-shrink-0">In Page</div>
<Select
isSearchable={true}
right
placeholder="change"
options={ urlOptions }
name="url"
defaultValue={defaultValue}
onChange={ onPageSelect }
id="change-dropdown"
className="w-full"
style={{ width: '100%' }}
/>
</div>
<Loader loading={ loading }>
<SelectorsList />
</Loader>
</div>
)
);
}
export default connect(state => {
const events = state.getIn([ 'sessions', 'visitedEvents' ])
return {
filters: state.getIn(['sessions', 'insightFilters']),
host: state.getIn([ 'sessions', 'host' ]),
insights: state.getIn([ 'sessions', 'insights' ]),
events: events,
urlOptions: events.map(({ url, host }: any) => ({ label: url, value: url, host })),
loading: state.getIn([ 'sessions', 'fetchInsightsRequest', 'loading' ]),
}
}, { fetchInsights })(PageInsightsPanel);
export default connect(
(state) => {
const events = state.getIn(['sessions', 'visitedEvents']);
return {
filters: state.getIn(['sessions', 'insightFilters']),
host: state.getIn(['sessions', 'host']),
insights: state.getIn(['sessions', 'insights']),
events: events,
urlOptions: events.map(({ url, host }: any) => ({ label: url, value: url, host })),
loading: state.getIn(['sessions', 'fetchInsightsRequest', 'loading']),
};
},
{ fetchInsights }
)(PageInsightsPanel);

View file

@ -1,30 +1,34 @@
import React, { useState } from 'react'
import stl from './SelectorCard.module.css'
import React, { useState } from 'react';
import stl from './SelectorCard.module.css';
import cn from 'classnames';
import type { MarkedTarget } from 'Player/MessageDistributor/StatedScreen/StatedScreen';
import { activeTarget } from 'Player';
import { Tooltip } from 'react-tippy';
interface Props {
index?: number,
target: MarkedTarget,
showContent: boolean
index?: number;
target: MarkedTarget;
showContent: boolean;
}
export default function SelectorCard({ index = 1, target, showContent } : Props) {
return (
<div className={cn(stl.wrapper, { [stl.active]: showContent })} onClick={() => activeTarget(index)}>
<div className={stl.top}>
{/* @ts-ignore */}
<Tooltip position='top' title="Rank of the most clicked element"><div className={stl.index}>{index + 1}</div></Tooltip>
<div className="truncate">{target.selector}</div>
</div>
{ showContent && (
<div className={stl.counts}>
<div>{target.count} Clicks - {target.percent}%</div>
<div className="color-gray-medium">TOTAL CLICKS</div>
export default function SelectorCard({ index = 1, target, showContent }: Props) {
return (
<div className={cn(stl.wrapper, { [stl.active]: showContent })} onClick={() => activeTarget(index)}>
<div className={stl.top}>
{/* @ts-ignore */}
<Tooltip position="top" title="Rank of the most clicked element">
<div className={stl.index}>{index + 1}</div>
</Tooltip>
<div className="truncate">{target.selector}</div>
</div>
{showContent && (
<div className={stl.counts}>
<div>
{target.count} Clicks - {target.percent}%
</div>
<div className="color-gray-medium">TOTAL CLICKS</div>
</div>
)}
</div>
) }
</div>
)
);
}

View file

@ -1,33 +1,26 @@
import React, { useState } from 'react'
import { NoContent } from 'UI'
import React from 'react';
import { NoContent } from 'UI';
import { connectPlayer } from 'Player/store';
import SelectorCard from '../SelectorCard/SelectorCard';
import type { MarkedTarget } from 'Player/MessageDistributor/StatedScreen/StatedScreen';
import stl from './selectorList.module.css'
import stl from './selectorList.module.css';
interface Props {
targets: Array<MarkedTarget>,
activeTargetIndex: number
targets: Array<MarkedTarget>;
activeTargetIndex: number;
}
function SelectorsList({ targets, activeTargetIndex }: Props) {
return (
<NoContent
title="No data available."
size="small"
show={ targets && targets.length === 0 }
>
<div className={stl.wrapper}>
{ targets && targets.map((target, index) => (
<SelectorCard target={target} index={index} showContent={activeTargetIndex === index} />
))}
</div>
</NoContent>
)
function SelectorsList({ targets, activeTargetIndex }: Props) {
return (
<NoContent title="No data available." size="small" show={targets && targets.length === 0}>
<div className={stl.wrapper}>
{targets && targets.map((target, index) => <SelectorCard target={target} index={index} showContent={activeTargetIndex === index} />)}
</div>
</NoContent>
);
}
export default connectPlayer(state => ({
targets: state.markedTargets,
activeTargetIndex: state.activeTargetIndex,
}))(SelectorsList)
export default connectPlayer((state: any) => ({
targets: state.markedTargets,
activeTargetIndex: state.activeTargetIndex,
}))(SelectorsList);

View file

@ -145,9 +145,9 @@ export default class StatedScreen extends Screen {
...s,
el,
index: index++,
percent: 0,
percent: Math.round((s.count * 100) / totalCount),
boundingRect: this.calculateRelativeBoundingRect(el),
count: Math.round((s.count * 100) / totalCount)
count: s.count,
})
});