Commit f52b52b1 by feitianbubu

fix: align dynamic pricing style with log details dialog sections

parent 4ae34175
......@@ -59,6 +59,11 @@ type DynamicPricingBreakdownProps = {
* call they are inspecting. Defaults to false (show all configured prices).
*/
hideCacheColumns?: boolean
/**
* Dense rendering for the usage-log details dialog: drops the colored
* icon header and uses the dialog's small text sizes. Defaults to false.
*/
compact?: boolean
}
const VAR_LABELS: Record<string, string> = {
......@@ -152,6 +157,7 @@ export function DynamicPricingBreakdown({
billingExpr,
matchedTierLabel,
hideCacheColumns = false,
compact = false,
}: DynamicPricingBreakdownProps) {
const { t } = useTranslation()
const expr = billingExpr || ''
......@@ -190,20 +196,22 @@ export function DynamicPricingBreakdown({
if (!hasTiers) {
return (
<section className='min-w-0 py-4'>
<div className='mb-3 flex items-center gap-2'>
<span className='inline-flex size-6 items-center justify-center rounded-lg bg-amber-100 text-amber-700 shadow-sm dark:bg-amber-500/20 dark:text-amber-300'>
<TagIcon className='size-3.5' />
</span>
<div>
<div className='text-foreground text-base font-medium'>
{t('Special billing expression')}
</div>
<div className='text-muted-foreground text-xs'>
{t('Unable to parse structured pricing')}
<section className={cn('min-w-0', !compact && 'py-4')}>
{!compact && (
<div className='mb-3 flex items-center gap-2'>
<span className='inline-flex size-6 items-center justify-center rounded-lg bg-amber-100 text-amber-700 shadow-sm dark:bg-amber-500/20 dark:text-amber-300'>
<TagIcon className='size-3.5' />
</span>
<div>
<div className='text-foreground text-base font-medium'>
{t('Special billing expression')}
</div>
<div className='text-muted-foreground text-xs'>
{t('Unable to parse structured pricing')}
</div>
</div>
</div>
</div>
)}
<div className='text-muted-foreground mb-1 text-[10px] font-medium tracking-wider uppercase'>
{t('Raw expression')}
</div>
......@@ -223,24 +231,32 @@ export function DynamicPricingBreakdown({
})
return (
<section className='min-w-0 py-3 sm:py-4'>
<div className='mb-3 flex items-start gap-2 sm:mb-4'>
<span className='mt-0.5 inline-flex size-6 items-center justify-center rounded-lg bg-amber-100 text-amber-700 shadow-sm dark:bg-amber-500/20 dark:text-amber-300'>
<TagIcon className='size-3.5' />
</span>
<div>
<div className='text-foreground text-base font-medium'>
{t('Dynamic Pricing')}
</div>
<div className='text-muted-foreground text-xs'>
{t('Prices vary by usage tier and request conditions')}
<section className={cn('min-w-0', !compact && 'py-3 sm:py-4')}>
{!compact && (
<div className='mb-3 flex items-start gap-2 sm:mb-4'>
<span className='mt-0.5 inline-flex size-6 items-center justify-center rounded-lg bg-amber-100 text-amber-700 shadow-sm dark:bg-amber-500/20 dark:text-amber-300'>
<TagIcon className='size-3.5' />
</span>
<div>
<div className='text-foreground text-base font-medium'>
{t('Dynamic Pricing')}
</div>
<div className='text-muted-foreground text-xs'>
{t('Prices vary by usage tier and request conditions')}
</div>
</div>
</div>
</div>
)}
{hasTiers && (
<div className='mb-3 sm:mb-4'>
<div className='text-foreground mb-2 text-sm font-semibold'>
<div className={cn(compact ? cn(hasRules && 'mb-2') : 'mb-3 sm:mb-4')}>
<div
className={
compact
? 'text-muted-foreground mb-1.5 text-xs font-medium'
: 'text-foreground mb-2 text-sm font-semibold'
}
>
{t('Tiered price table')}
</div>
<div className='space-y-1.5 sm:hidden'>
......@@ -289,7 +305,12 @@ export function DynamicPricingBreakdown({
<div className='text-muted-foreground truncate text-[10px] font-medium tracking-wider uppercase'>
{t(v.shortLabel)}
</div>
<div className='truncate font-mono text-sm font-semibold'>
<div
className={cn(
'truncate font-mono',
compact ? 'text-xs' : 'text-sm font-semibold'
)}
>
{value > 0
? `${symbol}${(value * rate).toFixed(4)}`
: '-'}
......@@ -304,7 +325,11 @@ export function DynamicPricingBreakdown({
</div>
<StaticDataTable
className='hidden rounded-none border-0 sm:block'
tableClassName='text-sm'
tableClassName={
compact
? '[&_td]:text-xs [&_td_*]:text-xs [&_th]:text-xs [&_th_*]:text-xs'
: 'text-sm'
}
headerRowClassName='hover:bg-transparent'
data={tiers}
getRowKey={(_tier, index) => `tier-${index}`}
......@@ -321,8 +346,11 @@ export function DynamicPricingBreakdown({
{
id: 'tier',
header: t('Tier'),
className: 'text-muted-foreground py-2 font-medium',
cellClassName: 'py-2.5 align-top',
className: cn(
'text-muted-foreground py-2 font-medium',
compact && 'h-8'
),
cellClassName: cn('align-top', compact ? 'py-2' : 'py-2.5'),
cell: (tier) => {
const condSummary = formatConditionSummary(tier.conditions, t)
const isMatched =
......@@ -359,14 +387,20 @@ export function DynamicPricingBreakdown({
...visiblePriceFields.map((v, index) => ({
id: v.field ?? `price-${index}`,
header: t(v.shortLabel),
className: 'text-muted-foreground py-2 text-right font-medium',
cellClassName: 'py-2.5 text-right align-top font-mono',
className: cn(
'text-muted-foreground py-2 text-right font-medium',
compact && 'h-8'
),
cellClassName: cn(
'text-right align-top font-mono',
compact ? 'py-2' : 'py-2.5'
),
cell: (tier: ParsedTier) => {
const value = Number(
tier[v.field as string as keyof ParsedTier] || 0
)
return value > 0 ? (
<span className='font-semibold'>
<span className={cn(!compact && 'font-semibold')}>
{`${symbol}${(value * rate).toFixed(4)}`}
</span>
) : (
......@@ -381,7 +415,13 @@ export function DynamicPricingBreakdown({
{hasRules && (
<div>
<div className='text-foreground mb-2 text-sm font-semibold'>
<div
className={
compact
? 'text-muted-foreground mb-1.5 text-xs font-medium'
: 'text-foreground mb-2 text-sm font-semibold'
}
>
{t('Conditional multipliers')}
</div>
<ul className='space-y-1.5'>
......@@ -390,7 +430,12 @@ export function DynamicPricingBreakdown({
key={`group-${gi}`}
className='bg-muted/50 flex items-center justify-between gap-3 rounded-md px-3 py-2'
>
<span className='text-foreground text-sm break-all'>
<span
className={cn(
'text-foreground break-all',
compact ? 'text-xs' : 'text-sm'
)}
>
{describeGroup(group, t)}
</span>
<Badge
......
......@@ -966,13 +966,14 @@ export function DetailsDialog(props: DetailsDialogProps) {
{/* Tiered pricing breakdown (when billing_mode is tiered_expr) */}
{isTieredBilling && other?.expr_b64 && (
<div className='bg-muted/30 min-w-0 overflow-hidden rounded-md border px-3 max-sm:px-2'>
<DetailSection label={t('Dynamic Pricing')}>
<DynamicPricingBreakdown
compact
billingExpr={decodeBillingExprB64(other.expr_b64)}
matchedTierLabel={other.matched_tier}
hideCacheColumns={!hasAnyCacheTokens(other)}
/>
</div>
</DetailSection>
)}
{/* Admin billing mode indicator for non-consume */}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment