Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
phsl
/
new-api
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Unverified
Commit
1ae75747
authored
Jul 04, 2026
by
同語
Committed by
GitHub
Jul 04, 2026
Browse files
Options
Browse Files
Download
Plain Diff
fix: align dynamic pricing style with log details dialog sections
Merge pull request #5905 from feitianbubu/pr/e9fa595c7
parents
4ae34175
f52b52b1
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
83 additions
and
37 deletions
+83
-37
web/default/src/features/pricing/components/dynamic-pricing-breakdown.tsx
+80
-35
web/default/src/features/usage-logs/components/dialogs/details-dialog.tsx
+3
-2
No files found.
web/default/src/features/pricing/components/dynamic-pricing-breakdown.tsx
View file @
1ae75747
...
...
@@ -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
...
...
web/default/src/features/usage-logs/components/dialogs/details-dialog.tsx
View file @
1ae75747
...
...
@@ -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 */
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment