import React, { useState, useEffect, useMemo } from 'react'; import { FixedSizeList } from 'react-window'; import { useSpring, animated, config } from 'react-spring'; import classNames from 'classnames'; import Button from 'components/common/Button'; import Arrow from 'assets/arrow-right.svg'; import { get } from 'lib/web'; import { percentFilter } from 'lib/filters'; import { formatNumber, formatLongNumber } from 'lib/format'; import styles from './MetricsTable.module.css'; export default function MetricsTable({ title, metric, websiteId, startDate, endDate, type, className, dataFilter, filterOptions, limit, headerComponent, onDataLoad = () => {}, onExpand = () => {}, labelRenderer = e => e, }) { const [data, setData] = useState(); const [format, setFormat] = useState(true); const formatFunc = format ? formatLongNumber : formatNumber; const shouldAnimate = limit > 0; const rankings = useMemo(() => { if (data) { const items = percentFilter(dataFilter ? dataFilter(data, filterOptions) : data); if (limit) { return items.filter((e, i) => i < limit); } return items; } return []; }, [data, dataFilter, filterOptions]); async function loadData() { const data = await get(`/api/website/${websiteId}/rankings`, { start_at: +startDate, end_at: +endDate, type, }); setData(data); onDataLoad(data); } function handleSetFormat() { setFormat(state => !state); } function getRow(x, y, z) { return ( ); } const Row = ({ index, style }) => { const { x, y, z } = rankings[index]; return
{getRow(x, y, z)}
; }; useEffect(() => { if (websiteId) { loadData(); } }, [websiteId, startDate, endDate, type]); if (!data) { return null; } return (
{title}
{headerComponent}
{metric}
{limit ? ( rankings.map(({ x, y, z }) => getRow(x, y, z)) ) : ( {Row} )}
{limit && data.length > limit && ( )}
); } const AnimatedRow = ({ label, value = 0, percent, animate, format, onClick, labelRenderer }) => { const props = useSpring({ width: percent, y: value, from: { width: 0, y: 0 }, config: animate ? config.default : { duration: 0 }, }); return (
{labelRenderer(decodeURI(label))}
{props.y?.interpolate(format)}
`${n}%`) }} /> {props.width.interpolate(n => `${n.toFixed(0)}%`)}
); };