change(ui): slowest domains card change

This commit is contained in:
Shekar Siri 2024-07-01 15:41:13 +02:00
parent 6fcef5dff5
commit 20ccee48d1
8 changed files with 260 additions and 157 deletions

View file

@ -4,11 +4,11 @@ import cn from "classnames";
interface Props {
list: any;
selected: any;
onClickHandler: (event: any, data: any) => void;
selected?: any;
onClickHandler?: (event: any, data: any) => void;
}
function CardSessionsByList({ list, selected, onClickHandler }: Props) {
function CardSessionsByList({ list, selected, onClickHandler = () => null }: Props) {
return (
<List
dataSource={list}

View file

@ -1,88 +1,88 @@
import React from 'react';
import {Button, Space} from 'antd';
import {filtersMap} from 'Types/filter/newFilter';
import {Icon} from 'UI';
import {Empty} from 'antd';
import {ArrowRight} from "lucide-react";
import CardSessionsByList from "Components/Dashboard/Widgets/CardSessionsByList";
import {useModal} from "Components/ModalContext";
import { Button, Space } from 'antd';
import { filtersMap } from 'Types/filter/newFilter';
import { Icon } from 'UI';
import { Empty } from 'antd';
import { ArrowRight } from 'lucide-react';
import CardSessionsByList from 'Components/Dashboard/Widgets/CardSessionsByList';
import { useModal } from 'Components/ModalContext';
interface Props {
metric?: any;
data: any;
onClick?: (filters: any) => void;
isTemplate?: boolean;
metric?: any;
data: any;
onClick?: (filters: any) => void;
isTemplate?: boolean;
}
function SessionsBy(props: Props) {
const {metric = {}, data = {values: []}, onClick = () => null, isTemplate} = props;
const [selected, setSelected] = React.useState<any>(null);
const total = data.values.length
const {openModal, closeModal} = useModal();
const { metric = {}, data = { values: [] }, onClick = () => null, isTemplate } = props;
const [selected, setSelected] = React.useState<any>(null);
const total = data.values.length;
const { openModal, closeModal } = useModal();
const onClickHandler = (event: any, data: any) => {
const filters = Array<any>();
let filter = {...filtersMap[metric.metricOf]};
filter.value = [data.name];
filter.type = filter.key;
delete filter.key;
delete filter.operatorOptions;
delete filter.category;
delete filter.icon;
delete filter.label;
delete filter.options;
const onClickHandler = (event: any, data: any) => {
const filters = Array<any>();
let filter = { ...filtersMap[metric.metricOf] };
filter.value = [data.name];
filter.type = filter.key;
delete filter.key;
delete filter.operatorOptions;
delete filter.category;
delete filter.icon;
delete filter.label;
delete filter.options;
setSelected(data.name)
setSelected(data.name);
filters.push(filter);
onClick(filters);
}
filters.push(filter);
onClick(filters);
};
const showMore = () => {
openModal(
<CardSessionsByList list={data.values} onClickHandler={(e, item) => {
closeModal();
onClickHandler(null, item)
}} selected={selected}/>, {
title: metric.name,
width: 600,
})
}
const showMore = () => {
openModal(
<CardSessionsByList list={data.values} onClickHandler={(e, item) => {
closeModal();
onClickHandler(null, item);
}} selected={selected} />, {
title: metric.name,
width: 600
});
};
return (
<div>
{data.values && data.values.length === 0 ? (
<Empty
image={null}
style={{minHeight: 220}}
className="flex flex-col items-center justify-center"
imageStyle={{height: 60}}
description={
<div className="flex items-center justify-center">
<Icon name="info-circle" className="mr-2" size="18"/>
No data for the selected time period
</div>
}
/>
) : (
<div className="flex flex-col justify-between w-full" style={{height: 220}}>
<CardSessionsByList list={data.values.slice(0, 3)}
selected={selected}
onClickHandler={onClickHandler}/>
{total > 3 && (
<div className="flex">
<Button type="link" onClick={showMore}>
<Space className='flex font-medium gap-1'>
{total - 5} More
<ArrowRight size={16}/>
</Space>
</Button>
</div>
)}
</div>
)}
return (
<div>
{data.values && data.values.length === 0 ? (
<Empty
image={null}
style={{ minHeight: 220 }}
className="flex flex-col items-center justify-center"
imageStyle={{ height: 60 }}
description={
<div className="flex items-center justify-center">
<Icon name="info-circle" className="mr-2" size="18" />
No data for the selected time period
</div>
}
/>
) : (
<div className="flex flex-col justify-between w-full" style={{ height: 220 }}>
<CardSessionsByList list={data.values.slice(0, 3)}
selected={selected}
onClickHandler={onClickHandler} />
{total > 3 && (
<div className="flex">
<Button type="link" onClick={showMore}>
<Space className="flex font-medium gap-1">
{total - 5} More
<ArrowRight size={16} />
</Space>
</Button>
</div>
)}
</div>
);
)}
</div>
);
}
export default SessionsBy;

View file

@ -1,38 +1,83 @@
import React from 'react';
import { NoContent } from 'UI';
import { Icon, NoContent } from 'UI';
import { Styles } from '../../common';
import { numberWithCommas } from 'App/utils';
import Bar from './Bar';
import { NO_METRIC_DATA } from 'App/constants/messages'
import { NO_METRIC_DATA } from 'App/constants/messages';
import CardSessionsByList from 'Components/Dashboard/Widgets/CardSessionsByList';
import { List, Progress, Typography } from 'antd';
import cn from 'classnames';
interface Props {
data: any
metric?: any
data: any;
}
function SlowestDomains(props: Props) {
const { data, metric } = props;
const firstAvg = metric.data.chart[0] && metric.data.chart[0].value;
return (
<NoContent
size="small"
show={ metric.data.chart.length === 0 }
style={{ minHeight: 220 }}
title={NO_METRIC_DATA}
>
<div className="w-full" style={{ height: '240px' }}>
{metric.data.chart.map((item, i) =>
<Bar
key={i}
className="mb-2"
avg={numberWithCommas(Math.round(item.value))}
width={Math.round((item.value * 100) / firstAvg) - 10}
domain={item.domain}
color={Styles.colors[i]}
const { data } = props;
// TODO - move this to the store
const highest = data.chart[0].value;
const list = data.chart.slice(0, 4).map((item: any) => ({
name: item.domain,
icon: <Icon name="link-45deg" size={24} />,
value: Math.round(item.value) + 'ms',
progress: Math.round((item.value * 100) / highest)
}));
return (
<NoContent
size="small"
show={list.length === 0}
style={{ minHeight: 220 }}
title={NO_METRIC_DATA}
>
<div className="w-full" style={{ height: '240px' }}>
<List
dataSource={list}
split={false}
renderItem={(row: any) => (
<List.Item
key={row.domain}
// onClick={(e) => onClickHandler(e, row)} // Remove onClick handler to disable click interaction
style={{
borderBottom: '1px dotted rgba(0, 0, 0, 0.05)',
padding: '4px 10px',
lineHeight: '1px'
}}
className={cn('rounded')} // Remove hover:bg-active-blue and cursor-pointer
>
<List.Item.Meta
className="m-0"
avatar={row.icon ? row.icon : null}
title={(
<div className="m-0">
<div className="flex justify-between m-0 p-0">
<Typography.Text>{row.name}</Typography.Text>
<Typography.Text type="secondary"> {row.value}</Typography.Text>
</div>
<Progress
percent={row.progress}
showInfo={false}
strokeColor={{
'0%': '#394EFF',
'100%': '#394EFF'
}}
size={['small', 2]}
style={{
padding: '0 0px',
margin: '0 0px',
height: 4
}}
/>
</div>
)}
/>
)}
</div>
</NoContent>
);
</List.Item>
)}
/>
</div>
</NoContent>
);
}
export default SlowestDomains;

View file

@ -21,6 +21,8 @@ import CallsWithErrorsExample
from "Components/Dashboard/components/DashboardList/NewDashModal/Examples/CallsWithErrorsExample";
import SessionsPerBrowserExample
from 'Components/Dashboard/components/DashboardList/NewDashModal/Examples/SessionsPerBrowserExample';
import SlowestDomains
from 'Components/Dashboard/components/DashboardList/NewDashModal/Examples/SessionsBy/SlowestDomains';
export const CARD_CATEGORY = {
PRODUCT_ANALYTICS: 'product-analytics',
@ -256,7 +258,7 @@ export const CARD_LIST: CardType[] = [
},
{
title: 'Sessions per Browser',
title: 'Sessions by Browser & Version',
key: FilterKey.SESSIONS_PER_BROWSER,
cardType: PERFORMANCE,
metricOf: FilterKey.SESSIONS_PER_BROWSER,
@ -271,8 +273,8 @@ export const CARD_LIST: CardType[] = [
cardType: PERFORMANCE,
metricOf: FilterKey.SLOWEST_DOMAINS,
category: CARD_CATEGORIES[1].key,
data: generateRandomBarsData(),
example: Bars,
// data: generateRandomBarsData(),
example: SlowestDomains,
},
{

View file

@ -4,6 +4,7 @@ import React from 'react';
import { Circle } from '../Count';
import ExCard from '../ExCard';
import ByComponent from 'Components/Dashboard/components/DashboardList/NewDashModal/Examples/SessionsBy/Component';
function ByUrl(props: any) {
const [mode, setMode] = React.useState(0);
@ -47,57 +48,62 @@ function ByUrl(props: any) {
const lineWidth = 240;
return (
<ExCard
{...props}
title={
<div className={'flex gap-2 items-center'}>
<div>{props.title}</div>
<div className={'font-normal'}><Segmented
options={[
{ label: 'URL', value: '0' },
{ label: 'Page Title', value: '1' },
]}
onChange={(v) => setMode(Number(v))}
size='small'
/>
</div>
</div>
}
>
<div className={'flex gap-1 flex-col'}>
{rows.map((r) => (
<div
className={
'flex items-center gap-2 border-b border-dotted last:border-0 py-2 first:pt-0 last:pb-0'
}
>
<Circle badgeType={1}>{r.icon}</Circle>
<div className={'ml-2 flex flex-col gap-0'}>
<div>{mode === 0 ? r.label : r.ptitle}</div>
<div style={{ display: 'flex' }}>
<div
style={{
height: 2,
width: lineWidth * (0.01 * r.progress),
background: '#394EFF',
}}
className={'rounded-l'}
/>
<div
style={{
height: 2,
width: lineWidth - lineWidth * (0.01 * r.progress),
background: '#E2E4F6',
}}
className={'rounded-r'}
/>
</div>
</div>
<div className={'min-w-8 ml-auto'}>{r.value}</div>
</div>
))}
</div>
</ExCard>
<ByComponent
{...props}
rows={rows}
lineWidth={lineWidth}
/>
// <ExCard
// {...props}
// title={
// <div className={'flex gap-2 items-center'}>
// <div>{props.title}</div>
// <div className={'font-normal'}><Segmented
// options={[
// { label: 'URL', value: '0' },
// { label: 'Page Title', value: '1' },
// ]}
// onChange={(v) => setMode(Number(v))}
// size='small'
// />
// </div>
// </div>
// }
// >
// <div className={'flex gap-1 flex-col'}>
// {rows.map((r) => (
// <div
// className={
// 'flex items-center gap-2 border-b border-dotted last:border-0 py-2 first:pt-0 last:pb-0'
// }
// >
// <Circle badgeType={1}>{r.icon}</Circle>
// <div className={'ml-2 flex flex-col gap-0'}>
// <div>{mode === 0 ? r.label : r.ptitle}</div>
// <div style={{ display: 'flex' }}>
// <div
// style={{
// height: 2,
// width: lineWidth * (0.01 * r.progress),
// background: '#394EFF',
// }}
// className={'rounded-l'}
// />
// <div
// style={{
// height: 2,
// width: lineWidth - lineWidth * (0.01 * r.progress),
// background: '#E2E4F6',
// }}
// className={'rounded-r'}
// />
// </div>
// </div>
// <div className={'min-w-8 ml-auto'}>{r.value}</div>
// </div>
// ))}
// </div>
// </ExCard>
);
}

View file

@ -0,0 +1,49 @@
import React from 'react';
import ByComponent from './Component';
import { LinkOutlined } from '@ant-design/icons';
function SlowestDomains(props: any) {
const rows = [
{
label: 'res.cloudinary.com',
value: '500',
progress: 75,
icon: <LinkOutlined size={12} />
},
{
label: 'mintbase.vercel.app',
value: '306',
progress: 60,
icon: <LinkOutlined size={12} />
},
{
label: 'downloads.intercomcdn.com',
value: '198',
progress: 30,
icon: <LinkOutlined size={12} />
},
{
label: 'static.intercomassets.com',
value: '47',
progress: 15,
icon: <LinkOutlined size={12} />
},
{
label: 'mozbar.moz.com',
value: '5',
progress: 5,
icon: <LinkOutlined size={12} />
}
];
const lineWidth = 200;
return (
<ByComponent
{...props}
rows={rows}
lineWidth={lineWidth}
/>
);
}
export default SlowestDomains;

View file

@ -4,6 +4,7 @@ import React from 'react';
import { Circle } from './Count';
import ExCard from './ExCard';
// TODO - delete this
function SlowestDomain(props: any) {
const rows = [
{

View file

@ -78,7 +78,7 @@ function WidgetPredefinedChart(props: Props) {
case FilterKey.SESSIONS_PER_BROWSER:
return <SessionsPerBrowser data={data} />
case FilterKey.SLOWEST_DOMAINS:
return <SlowestDomains data={data} metric={metric} />
return <SlowestDomains data={data} />
case FilterKey.TIME_TO_RENDER:
return <TimeToRender data={data} metric={metric} />