mirror of
https://github.com/MadcowD/ell.git
synced 2024-09-22 16:14:36 +03:00
improved ux
This commit is contained in:
@@ -1,15 +1,15 @@
|
|||||||
import React, { useMemo } from 'react';
|
import React, { useMemo } from 'react';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import { FiClock, FiTag, FiGitCommit, FiZap, FiHash, FiCalendar, FiChevronRight } from 'react-icons/fi';
|
import { FiClock, FiTag, FiZap, FiHash, FiChevronRight, FiCode } from 'react-icons/fi';
|
||||||
import { getTimeAgo } from '../utils/lmpUtils';
|
import { getTimeAgo } from '../utils/lmpUtils';
|
||||||
import VersionBadge from './VersionBadge';
|
import VersionBadge from './VersionBadge';
|
||||||
import { useInvocationsFromLMP } from '../hooks/useBackend';
|
import { useInvocationsFromLMP } from '../hooks/useBackend';
|
||||||
import { LMPCardTitle } from './depgraph/LMPCardTitle';
|
import { LMPCardTitle } from './depgraph/LMPCardTitle';
|
||||||
import { format } from 'date-fns';
|
import { format } from 'date-fns';
|
||||||
import SidePanel from './common/SidePanel';
|
import SidePanel from './common/SidePanel';
|
||||||
import StatItem from './common/StatItem';
|
import MetricChart from './MetricChart';
|
||||||
import MetricCard from './common/MetricCard';
|
|
||||||
import { motion } from 'framer-motion';
|
import { motion } from 'framer-motion';
|
||||||
|
import {Card} from './common/Card';
|
||||||
|
|
||||||
function LMPDetailsSidePanel({ lmp, uses, versionHistory }) {
|
function LMPDetailsSidePanel({ lmp, uses, versionHistory }) {
|
||||||
const { data: invocations } = useInvocationsFromLMP(lmp.name, lmp.lmp_id, 0, 100);
|
const { data: invocations } = useInvocationsFromLMP(lmp.name, lmp.lmp_id, 0, 100);
|
||||||
@@ -38,52 +38,72 @@ function LMPDetailsSidePanel({ lmp, uses, versionHistory }) {
|
|||||||
initial={{ opacity: 0, y: 20 }}
|
initial={{ opacity: 0, y: 20 }}
|
||||||
animate={{ opacity: 1, y: 0 }}
|
animate={{ opacity: 1, y: 0 }}
|
||||||
transition={{ duration: 0.3 }}
|
transition={{ duration: 0.3 }}
|
||||||
className="space-y-6"
|
className="space-y-2 text-sm"
|
||||||
>
|
>
|
||||||
<div className="bg-card p-4 rounded-lg shadow-md">
|
<div className="bg-card p-2 rounded">
|
||||||
<div className="flex justify-between items-center mb-4">
|
<div className="flex justify-between items-center mb-1">
|
||||||
<h3 className="text-lg font-semibold text-card-foreground">Version Info</h3>
|
<h3 className="text-sm font-semibold text-card-foreground">Version Info</h3>
|
||||||
<VersionBadge version={lmp.version_number + 1} hash={lmp.lmp_id} />
|
<VersionBadge version={lmp.version_number + 1} hash={lmp.lmp_id} />
|
||||||
</div>
|
</div>
|
||||||
<div className="grid grid-cols-2 gap-4">
|
<div className="grid grid-cols-2 gap-y-0.5">
|
||||||
<StatItem icon={FiClock} label="Created" value={getTimeAgo(new Date(lmp.created_at))} />
|
<div className="flex items-center">
|
||||||
<StatItem icon={FiTag} label="Is LMP" value={lmp.is_lm ? 'Yes' : 'No'} />
|
<FiClock className="mr-1 text-muted-foreground" size={12} />
|
||||||
<StatItem icon={FiZap} label="Total Invocations" value={totalInvocations} />
|
<span className="text-muted-foreground">Created:</span>
|
||||||
<StatItem icon={FiHash} label="Avg. Latency" value={`${avgLatency.toFixed(2)}ms`} />
|
</div>
|
||||||
|
<div className="text-right">{getTimeAgo(new Date(lmp.created_at))}</div>
|
||||||
|
<div className="flex items-center">
|
||||||
|
<FiTag className="mr-1 text-muted-foreground" size={12} />
|
||||||
|
<span className="text-muted-foreground">Is LMP:</span>
|
||||||
|
</div>
|
||||||
|
<div className="text-right">{lmp.is_lm ? 'Yes' : 'No'}</div>
|
||||||
|
<div className="flex items-center">
|
||||||
|
<FiZap className="mr-1 text-muted-foreground" size={12} />
|
||||||
|
<span className="text-muted-foreground">Invocations:</span>
|
||||||
|
</div>
|
||||||
|
<div className="text-right">{totalInvocations}</div>
|
||||||
|
<div className="flex items-center">
|
||||||
|
<FiHash className="mr-1 text-muted-foreground" size={12} />
|
||||||
|
<span className="text-muted-foreground">Avg. Latency:</span>
|
||||||
|
</div>
|
||||||
|
<div className="text-right">{avgLatency.toFixed(2)}ms</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{lmp.lm_kwargs && (
|
{lmp.lm_kwargs && (
|
||||||
<div className="bg-card p-4 rounded-lg shadow-md">
|
<div className="bg-card p-2 rounded">
|
||||||
<h3 className="text-lg font-semibold text-card-foreground mb-3">LM Keywords</h3>
|
<h3 className="text-sm font-semibold text-card-foreground mb-1 flex items-center">
|
||||||
<pre className="overflow-x-auto text-sm text-muted-foreground bg-muted p-3 rounded-md">
|
<FiCode className="mr-1" size={14} /> LM Keywords
|
||||||
|
</h3>
|
||||||
|
<pre className="overflow-x-auto text-xs text-muted-foreground bg-muted p-1 rounded">
|
||||||
<code>{JSON.stringify(lmp.lm_kwargs, null, 2)}</code>
|
<code>{JSON.stringify(lmp.lm_kwargs, null, 2)}</code>
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<div className="bg-card p-4 rounded-lg shadow-md">
|
<div className="bg-card p-2 rounded">
|
||||||
<h3 className="text-lg font-semibold text-card-foreground mb-3">Uses</h3>
|
<h3 className="text-sm font-semibold text-card-foreground mb-1">Uses</h3>
|
||||||
{uses && uses.length > 0 ? (
|
{uses && uses.length > 0 ? (
|
||||||
<ul className="space-y-2">
|
<ul className="space-y-0.5">
|
||||||
{uses.filter(use => !!use).map((use) => (
|
{uses.filter(use => !!use).map((use) => (
|
||||||
<motion.li
|
<motion.li
|
||||||
key={use.lmp_id}
|
key={use.lmp_id}
|
||||||
whileHover={{ scale: 1.02 }}
|
whileHover={{ scale: 1.01 }}
|
||||||
className="text-sm bg-muted p-2 rounded-md"
|
className=" p-0.5 rounded"
|
||||||
>
|
>
|
||||||
<Link to={`/lmp/${use.name}/${use.lmp_id}`} className="text-primary hover:text-primary/80 transition-colors">
|
<Link to={`/lmp/${use.name}/${use.lmp_id}`} className="text-primary hover:text-primary/80 transition-colors">
|
||||||
<LMPCardTitle lmp={use} displayVersion scale={50} shortVersion={true} />
|
<Card>
|
||||||
|
<LMPCardTitle lmp={use} displayVersion scale={50} />
|
||||||
|
</Card>
|
||||||
</Link>
|
</Link>
|
||||||
</motion.li>
|
</motion.li>
|
||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
) : (
|
) : (
|
||||||
<p className="text-sm text-muted-foreground">No dependencies</p>
|
<p className="text-muted-foreground">No dependencies</p>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<MetricCard
|
<MetricChart
|
||||||
title="Invocations"
|
title="Invocations"
|
||||||
rawData={chartData}
|
rawData={chartData}
|
||||||
dataKey="count"
|
dataKey="count"
|
||||||
@@ -91,7 +111,7 @@ function LMPDetailsSidePanel({ lmp, uses, versionHistory }) {
|
|||||||
yAxisLabel="Count"
|
yAxisLabel="Count"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<MetricCard
|
<MetricChart
|
||||||
title="Latency"
|
title="Latency"
|
||||||
rawData={chartData}
|
rawData={chartData}
|
||||||
dataKey="latency"
|
dataKey="latency"
|
||||||
@@ -99,35 +119,32 @@ function LMPDetailsSidePanel({ lmp, uses, versionHistory }) {
|
|||||||
aggregation="avg"
|
aggregation="avg"
|
||||||
yAxisLabel="ms"
|
yAxisLabel="ms"
|
||||||
/>
|
/>
|
||||||
|
{/*
|
||||||
<div className="bg-card p-4 rounded-lg shadow-md">
|
<div className="bg-card p-2 rounded">
|
||||||
<h3 className="text-lg font-semibold text-card-foreground mb-3">Version History</h3>
|
<h3 className="text-sm font-semibold text-card-foreground mb-1">Version History</h3>
|
||||||
<div className="space-y-2 max-h-64 overflow-y-auto pr-2">
|
<div className="space-y-0.5 max-h-40 overflow-y-auto pr-1">
|
||||||
{versionHistory.map((version, index) => (
|
{versionHistory.map((version, index) => (
|
||||||
<motion.div
|
<motion.div
|
||||||
key={version.lmp_id}
|
key={version.lmp_id}
|
||||||
whileHover={{ scale: 1.02 }}
|
whileHover={{ scale: 1.01 }}
|
||||||
className={`p-3 rounded-md text-sm ${
|
className={`p-0.5 rounded ${
|
||||||
version.lmp_id === lmp.lmp_id
|
version.lmp_id === lmp.lmp_id
|
||||||
? 'bg-primary/10'
|
? 'bg-primary/10 border-l-2 border-primary'
|
||||||
: 'bg-muted hover:bg-muted/80'
|
: 'bg-muted hover:bg-muted/80'
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<Link to={`/lmp/${version.name}/${version.lmp_id}`} className="block">
|
<Link to={`/lmp/${version.name}/${version.lmp_id}`} className="block">
|
||||||
<div className="flex justify-between items-center">
|
<div className="flex items-center justify-between">
|
||||||
<span className={`font-medium ${
|
<div className="flex items-center space-x-1">
|
||||||
version.lmp_id === lmp.lmp_id ? 'text-primary' : 'text-card-foreground'
|
<span className="font-semibold">v{versionHistory.length - index}</span>
|
||||||
}`}>
|
<span className="text-xs text-muted-foreground">
|
||||||
v{versionHistory.length - index}
|
{format(new Date(version.created_at), 'MMM d, yyyy HH:mm')}
|
||||||
</span>
|
</span>
|
||||||
<span className="text-muted-foreground">
|
</div>
|
||||||
<FiCalendar className="inline mr-1" size={12} />
|
<FiChevronRight className="text-muted-foreground" size={12} />
|
||||||
{format(new Date(version.created_at), 'MMM d, yyyy')}
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
{version.commit_message && (
|
{version.commit_message && (
|
||||||
<p className="text-muted-foreground mt-1 truncate">
|
<p className="text-xs text-muted-foreground truncate">
|
||||||
<FiGitCommit className="inline mr-1" size={12} />
|
|
||||||
{version.commit_message}
|
{version.commit_message}
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
@@ -135,7 +152,7 @@ function LMPDetailsSidePanel({ lmp, uses, versionHistory }) {
|
|||||||
</motion.div>
|
</motion.div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div> */}
|
||||||
</motion.div>
|
</motion.div>
|
||||||
</SidePanel>
|
</SidePanel>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -149,11 +149,11 @@ function MetricChart({ rawData, dataKey, color, yAxisLabel, aggregation="sum", t
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="bg-card p-4 rounded-lg shadow-md">
|
<div className="bg-card p-2 rounded">
|
||||||
<div className="flex justify-between items-center mb-4">
|
<div className="flex justify-between items-center mb-2">
|
||||||
<h3 className="text-lg font-semibold text-card-foreground">{title}</h3>
|
<h3 className="text-sm font-semibold text-card-foreground">{title}</h3>
|
||||||
<select
|
<select
|
||||||
className="bg-muted text-muted-foreground text-sm border border-input rounded px-2 py-1"
|
className="bg-muted text-muted-foreground text-xs border border-input rounded px-1 py-0.5"
|
||||||
value={selectedTimeRange}
|
value={selectedTimeRange}
|
||||||
onChange={(e) => setSelectedTimeRange(e.target.value)}
|
onChange={(e) => setSelectedTimeRange(e.target.value)}
|
||||||
>
|
>
|
||||||
@@ -164,11 +164,11 @@ function MetricChart({ rawData, dataKey, color, yAxisLabel, aggregation="sum", t
|
|||||||
))}
|
))}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div className="h-64">
|
<div className="h-48">
|
||||||
<ResponsiveContainer width="100%" height="100%">
|
<ResponsiveContainer width="100%" height="100%">
|
||||||
<AreaChart
|
<AreaChart
|
||||||
data={aggregatedData}
|
data={aggregatedData}
|
||||||
margin={{ top: 10, right: 30, left: 0, bottom: 0 }}
|
margin={{ top: 5, right: 5, left: 0, bottom: 0 }}
|
||||||
>
|
>
|
||||||
<defs>
|
<defs>
|
||||||
<linearGradient id={`color${dataKey}`} x1="0" y1="0" x2="0" y2="1">
|
<linearGradient id={`color${dataKey}`} x1="0" y1="0" x2="0" y2="1">
|
||||||
@@ -179,18 +179,18 @@ function MetricChart({ rawData, dataKey, color, yAxisLabel, aggregation="sum", t
|
|||||||
<XAxis
|
<XAxis
|
||||||
dataKey="date"
|
dataKey="date"
|
||||||
stroke="#718096"
|
stroke="#718096"
|
||||||
tick={{ fill: "#718096", fontSize: 10 }}
|
tick={{ fill: "#718096", fontSize: 9 }}
|
||||||
tickFormatter={formatXAxis}
|
tickFormatter={formatXAxis}
|
||||||
/>
|
/>
|
||||||
<YAxis
|
<YAxis
|
||||||
stroke="#718096"
|
stroke="#718096"
|
||||||
tick={{ fill: "#718096", fontSize: 10 }}
|
tick={{ fill: "#718096", fontSize: 9 }}
|
||||||
label={{
|
label={{
|
||||||
value: yAxisLabel,
|
value: yAxisLabel,
|
||||||
angle: -90,
|
angle: -90,
|
||||||
position: "insideLeft",
|
position: "insideLeft",
|
||||||
fill: "#718096",
|
fill: "#718096",
|
||||||
fontSize: 12,
|
fontSize: 10,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<CartesianGrid strokeDasharray="3 3" stroke="#4A5568" />
|
<CartesianGrid strokeDasharray="3 3" stroke="#4A5568" />
|
||||||
@@ -199,7 +199,7 @@ function MetricChart({ rawData, dataKey, color, yAxisLabel, aggregation="sum", t
|
|||||||
backgroundColor: "#2D3748",
|
backgroundColor: "#2D3748",
|
||||||
border: "1px solid #4A5568",
|
border: "1px solid #4A5568",
|
||||||
color: "#E2E8F0",
|
color: "#E2E8F0",
|
||||||
fontSize: 12,
|
fontSize: 10,
|
||||||
}}
|
}}
|
||||||
labelFormatter={(label) => format(new Date(label), "PPpp")}
|
labelFormatter={(label) => format(new Date(label), "PPpp")}
|
||||||
formatter={formatTooltip}
|
formatter={formatTooltip}
|
||||||
@@ -213,7 +213,7 @@ function MetricChart({ rawData, dataKey, color, yAxisLabel, aggregation="sum", t
|
|||||||
/>
|
/>
|
||||||
<Brush
|
<Brush
|
||||||
dataKey="date"
|
dataKey="date"
|
||||||
height={20}
|
height={15}
|
||||||
stroke={color}
|
stroke={color}
|
||||||
fill="#2D3748"
|
fill="#2D3748"
|
||||||
tickFormatter={formatXAxis}
|
tickFormatter={formatXAxis}
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { FiZap, FiClock, FiHash, FiUsers, FiPercent, FiBox } from 'react-icons/fi';
|
import { FiZap, FiClock, FiHash, FiUsers, FiPercent, FiBox } from 'react-icons/fi';
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
import SidePanel from '../common/SidePanel';
|
import SidePanel from '../common/SidePanel';
|
||||||
import StatItem from '../common/StatItem';
|
import MetricChart from '../MetricChart';
|
||||||
import MetricCard from '../common/MetricCard';
|
|
||||||
import { motion } from 'framer-motion';
|
import { motion } from 'framer-motion';
|
||||||
|
import { LMPCardTitle } from '../depgraph/LMPCardTitle';
|
||||||
|
import { Card } from '../common/Card';
|
||||||
|
|
||||||
const InvocationsAnalyticsSidePanel = ({ aggregateData, sidebarMetrics }) => {
|
const InvocationsAnalyticsSidePanel = ({ aggregateData, sidebarMetrics }) => {
|
||||||
if (!aggregateData || !sidebarMetrics) return null;
|
if (!aggregateData || !sidebarMetrics) return null;
|
||||||
@@ -14,21 +16,45 @@ const InvocationsAnalyticsSidePanel = ({ aggregateData, sidebarMetrics }) => {
|
|||||||
initial={{ opacity: 0, y: 20 }}
|
initial={{ opacity: 0, y: 20 }}
|
||||||
animate={{ opacity: 1, y: 0 }}
|
animate={{ opacity: 1, y: 0 }}
|
||||||
transition={{ duration: 0.3 }}
|
transition={{ duration: 0.3 }}
|
||||||
className="space-y-6"
|
className="space-y-2 text-sm"
|
||||||
>
|
>
|
||||||
<div className="bg-card p-4 rounded-lg shadow-md">
|
<div className="bg-card p-2 rounded">
|
||||||
<h3 className="text-lg font-semibold text-card-foreground mb-4">Overview</h3>
|
<h3 className="text-sm font-semibold text-card-foreground mb-1">Overview</h3>
|
||||||
<div className="grid grid-cols-2 gap-4">
|
<div className="grid grid-cols-2 gap-y-0.5">
|
||||||
<StatItem icon={FiZap} label="Total Invocations" value={sidebarMetrics.totalInvocations} />
|
<div className="flex items-center">
|
||||||
<StatItem icon={FiClock} label="Avg. Latency" value={`${sidebarMetrics.avgLatency.toFixed(2)}ms`} />
|
<FiZap className="mr-1 text-muted-foreground" size={12} />
|
||||||
<StatItem icon={FiHash} label="Total Tokens" value={sidebarMetrics.totalTokens} />
|
<span className="text-muted-foreground">Total Invocations:</span>
|
||||||
<StatItem icon={FiUsers} label="Unique LMPs" value={sidebarMetrics.uniqueLMPs} />
|
</div>
|
||||||
<StatItem icon={FiPercent} label="Success Rate" value={`${sidebarMetrics.successRate.toFixed(2)}%`} />
|
<div className="text-right">{sidebarMetrics.totalInvocations}</div>
|
||||||
<StatItem icon={FiBox} label="Avg Tokens/Invocation" value={(sidebarMetrics.totalTokens / sidebarMetrics.totalInvocations).toFixed(2)} />
|
<div className="flex items-center">
|
||||||
|
<FiClock className="mr-1 text-muted-foreground" size={12} />
|
||||||
|
<span className="text-muted-foreground">Avg. Latency:</span>
|
||||||
|
</div>
|
||||||
|
<div className="text-right">{sidebarMetrics.avgLatency?.toFixed(2)}ms</div>
|
||||||
|
<div className="flex items-center">
|
||||||
|
<FiHash className="mr-1 text-muted-foreground" size={12} />
|
||||||
|
<span className="text-muted-foreground">Total Tokens:</span>
|
||||||
|
</div>
|
||||||
|
<div className="text-right">{sidebarMetrics.totalTokens}</div>
|
||||||
|
<div className="flex items-center">
|
||||||
|
<FiUsers className="mr-1 text-muted-foreground" size={12} />
|
||||||
|
<span className="text-muted-foreground">Unique LMPs:</span>
|
||||||
|
</div>
|
||||||
|
<div className="text-right">{sidebarMetrics.uniqueLMPs}</div>
|
||||||
|
<div className="flex items-center">
|
||||||
|
<FiPercent className="mr-1 text-muted-foreground" size={12} />
|
||||||
|
<span className="text-muted-foreground">Success Rate:</span>
|
||||||
|
</div>
|
||||||
|
<div className="text-right">{sidebarMetrics.successRate.toFixed(2)}%</div>
|
||||||
|
<div className="flex items-center">
|
||||||
|
<FiBox className="mr-1 text-muted-foreground" size={12} />
|
||||||
|
<span className="text-muted-foreground">Avg Tokens/Invocation:</span>
|
||||||
|
</div>
|
||||||
|
<div className="text-right">{(sidebarMetrics.totalTokens / sidebarMetrics.totalInvocations)?.toFixed(2)}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<MetricCard
|
<MetricChart
|
||||||
title="Invocations Over Time"
|
title="Invocations Over Time"
|
||||||
rawData={aggregateData.graph_data}
|
rawData={aggregateData.graph_data}
|
||||||
dataKey="count"
|
dataKey="count"
|
||||||
@@ -37,7 +63,7 @@ const InvocationsAnalyticsSidePanel = ({ aggregateData, sidebarMetrics }) => {
|
|||||||
yAxisLabel="Count"
|
yAxisLabel="Count"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<MetricCard
|
<MetricChart
|
||||||
title="Latency Over Time"
|
title="Latency Over Time"
|
||||||
rawData={aggregateData.graph_data}
|
rawData={aggregateData.graph_data}
|
||||||
dataKey="avg_latency"
|
dataKey="avg_latency"
|
||||||
@@ -46,7 +72,7 @@ const InvocationsAnalyticsSidePanel = ({ aggregateData, sidebarMetrics }) => {
|
|||||||
yAxisLabel="ms"
|
yAxisLabel="ms"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<MetricCard
|
<MetricChart
|
||||||
title="Tokens Over Time"
|
title="Tokens Over Time"
|
||||||
rawData={aggregateData.graph_data}
|
rawData={aggregateData.graph_data}
|
||||||
dataKey="tokens"
|
dataKey="tokens"
|
||||||
@@ -54,24 +80,37 @@ const InvocationsAnalyticsSidePanel = ({ aggregateData, sidebarMetrics }) => {
|
|||||||
yAxisLabel="Tokens"
|
yAxisLabel="Tokens"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div className="bg-card p-4 rounded-lg shadow-md">
|
{/* <div className="bg-card p-2 rounded">
|
||||||
<h3 className="text-lg font-semibold text-card-foreground mb-3">Top 5 LMPs</h3>
|
<h3 className="text-sm font-semibold text-card-foreground mb-1">Top 5 LMPs</h3>
|
||||||
<ul className="space-y-2">
|
<ul className="space-y-0.5">
|
||||||
{sidebarMetrics.topLMPs.map(([lmp, count], index) => (
|
{sidebarMetrics.topLMPs.map(([lmpName, count], index) => (
|
||||||
<motion.li
|
<motion.li
|
||||||
key={lmp}
|
key={lmpName}
|
||||||
whileHover={{ scale: 1.02 }}
|
whileHover={{ scale: 1.01 }}
|
||||||
className="flex justify-between items-center text-sm bg-muted p-2 rounded-md"
|
className="p-0.5 rounded"
|
||||||
>
|
>
|
||||||
<span className="text-card-foreground">
|
<Link to={`/lmp/${lmpName}`} className="text-primary hover:text-primary/80 transition-colors">
|
||||||
<span className="text-primary mr-2">{index + 1}.</span>
|
<Card className="relative">
|
||||||
{lmp}
|
<LMPCardTitle
|
||||||
</span>
|
lmp={{ name: lmpName, is_lm: false }} // Assuming we don't have full LMP data here
|
||||||
<span className="text-muted-foreground">{count} invocations</span>
|
displayVersion={false}
|
||||||
|
scale={50}
|
||||||
|
/>
|
||||||
|
<div className="absolute top-0 right-0 bg-muted text-muted-foreground text-xs px-1 rounded-bl">
|
||||||
|
{count} invocations
|
||||||
|
</div>
|
||||||
|
<div className="mt-1 bg-primary/5 h-1 rounded-full overflow-hidden">
|
||||||
|
<div
|
||||||
|
className="bg-primary h-full"
|
||||||
|
style={{ width: `${(count / sidebarMetrics.totalInvocations) * 100}%` }}
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
</Link>
|
||||||
</motion.li>
|
</motion.li>
|
||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div> */}
|
||||||
</motion.div>
|
</motion.div>
|
||||||
</SidePanel>
|
</SidePanel>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -104,4 +104,5 @@
|
|||||||
to {
|
to {
|
||||||
stroke-dashoffset: -10;
|
stroke-dashoffset: -10;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user