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
d98f0e8a
authored
May 06, 2026
by
yyhhyyyyyy
Committed by
GitHub
May 06, 2026
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix: migrate select to Base UI items API (#4655)
parent
38a3314b
Show whitespace changes
Inline
Side-by-side
Showing
38 changed files
with
789 additions
and
87 deletions
+789
-87
web/default/src/components/data-table/pagination.tsx
+10
-1
web/default/src/components/ui/select.tsx
+1
-1
web/default/src/features/channels/components/dialogs/channel-test-dialog.tsx
+10
-1
web/default/src/features/channels/components/dialogs/edit-tag-dialog.tsx
+10
-1
web/default/src/features/channels/components/dialogs/multi-key-manage-dialog.tsx
+10
-1
web/default/src/features/channels/components/dialogs/param-override-editor-dialog.tsx
+69
-8
web/default/src/features/channels/components/drawers/channel-mutate-drawer.tsx
+69
-7
web/default/src/features/dashboard/components/models/models-chart-preferences.tsx
+37
-4
web/default/src/features/dashboard/components/models/models-filter-dialog.tsx
+10
-1
web/default/src/features/models/components/dialogs/create-deployment-drawer.tsx
+17
-2
web/default/src/features/models/components/dialogs/upstream-conflict-dialog.tsx
+10
-1
web/default/src/features/models/components/dialogs/view-logs-dialog.tsx
+33
-2
web/default/src/features/models/components/drawers/model-mutate-drawer.tsx
+23
-3
web/default/src/features/models/components/drawers/prefill-group-form-drawer.tsx
+23
-2
web/default/src/features/profile/components/language-preferences-card.tsx
+10
-1
web/default/src/features/subscriptions/components/dialogs/subscription-purchase-dialog.tsx
+10
-1
web/default/src/features/subscriptions/components/dialogs/user-subscriptions-dialog.tsx
+15
-1
web/default/src/features/subscriptions/components/subscriptions-mutate-drawer.tsx
+26
-3
web/default/src/features/system-settings/auth/custom-oauth/components/preset-selector.tsx
+10
-1
web/default/src/features/system-settings/auth/custom-oauth/components/provider-form-dialog.tsx
+10
-1
web/default/src/features/system-settings/auth/passkey-section.tsx
+28
-5
web/default/src/features/system-settings/content/announcements-section.tsx
+21
-2
web/default/src/features/system-settings/content/api-info-section.tsx
+21
-2
web/default/src/features/system-settings/content/dashboard-section.tsx
+10
-1
web/default/src/features/system-settings/general/channel-affinity/rule-editor-dialog.tsx
+7
-1
web/default/src/features/system-settings/general/pricing-section.tsx
+14
-2
web/default/src/features/system-settings/general/system-info-section.tsx
+15
-2
web/default/src/features/system-settings/integrations/creem-product-dialog.tsx
+12
-2
web/default/src/features/system-settings/maintenance/performance-section.tsx
+16
-2
web/default/src/features/system-settings/models/channel-selector-dialog.tsx
+10
-1
web/default/src/features/system-settings/models/group-special-usable-editor.tsx
+36
-1
web/default/src/features/system-settings/models/tiered-pricing-editor.tsx
+65
-8
web/default/src/features/system-settings/models/upstream-ratio-sync-table.tsx
+11
-1
web/default/src/features/system-settings/request-limits/ssrf-section.tsx
+27
-2
web/default/src/features/usage-logs/components/common-logs-filter-bar.tsx
+16
-6
web/default/src/features/users/components/users-mutate-drawer.tsx
+17
-2
web/default/src/features/wallet/components/dialogs/billing-history-dialog.tsx
+10
-1
web/default/src/features/wallet/components/subscription-plans-card.tsx
+40
-3
No files found.
web/default/src/components/data-table/pagination.tsx
View file @
d98f0e8a
...
...
@@ -11,6 +11,7 @@ import { Button } from '@/components/ui/button'
import
{
Select
,
SelectContent
,
SelectGroup
,
SelectItem
,
SelectTrigger
,
SelectValue
,
...
...
@@ -45,6 +46,12 @@ export function DataTablePagination<TData>({
</
div
>
<
div
className=
'flex items-center gap-2 @max-2xl/content:flex-row-reverse'
>
<
Select
items=
{
[
...[
10
,
20
,
30
,
40
,
50
,
100
].
map
((
pageSize
)
=>
({
value
:
`${pageSize}`
,
label
:
pageSize
,
})),
]
}
value=
{
`${table.getState().pagination.pageSize}`
}
onValueChange=
{
(
value
)
=>
{
table
.
setPageSize
(
Number
(
value
))
...
...
@@ -53,12 +60,14 @@ export function DataTablePagination<TData>({
<
SelectTrigger
className=
'h-8 w-[64px] sm:w-[70px]'
>
<
SelectValue
placeholder=
{
table
.
getState
().
pagination
.
pageSize
}
/>
</
SelectTrigger
>
<
SelectContent
side=
'top'
>
<
SelectContent
side=
'top'
alignItemWithTrigger=
{
false
}
>
<
SelectGroup
>
{
[
10
,
20
,
30
,
40
,
50
,
100
].
map
((
pageSize
)
=>
(
<
SelectItem
key=
{
pageSize
}
value=
{
`${pageSize}`
}
>
{
pageSize
}
</
SelectItem
>
))
}
</
SelectGroup
>
</
SelectContent
>
</
Select
>
<
p
className=
'hidden text-sm font-medium sm:block'
>
...
...
web/default/src/components/ui/select.tsx
View file @
d98f0e8a
...
...
@@ -93,7 +93,7 @@ function SelectContent({
data
-
slot=
'select-content'
data
-
align
-
trigger=
{
alignItemWithTrigger
}
className=
{
cn
(
'
dark
bg-popover text-popover-foreground ring-foreground/10 data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95 relative isolate z-50 max-h-(--available-height) w-(--anchor-width) min-w-36 origin-(--transform-origin) overflow-x-hidden overflow-y-auto rounded-lg shadow-md ring-1 duration-100 data-[align-trigger=true]:animate-none'
,
'bg-popover text-popover-foreground ring-foreground/10 data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95 relative isolate z-50 max-h-(--available-height) w-(--anchor-width) min-w-36 origin-(--transform-origin) overflow-x-hidden overflow-y-auto rounded-lg shadow-md ring-1 duration-100 data-[align-trigger=true]:animate-none'
,
className
)
}
{
...
props
}
...
...
web/default/src/features/channels/components/dialogs/channel-test-dialog.tsx
View file @
d98f0e8a
...
...
@@ -25,6 +25,7 @@ import { Label } from '@/components/ui/label'
import
{
Select
,
SelectContent
,
SelectGroup
,
SelectItem
,
SelectTrigger
,
SelectValue
,
...
...
@@ -431,13 +432,20 @@ export function ChannelTestDialog({
<
div
className=
'grid gap-2'
>
<
Label
htmlFor=
'endpoint-type'
>
{
t
(
'Endpoint Type'
)
}
</
Label
>
<
Select
items=
{
[
...
endpointTypeOptions
.
map
((
option
)
=>
{
const
itemValue
=
option
.
value
return
{
value
:
itemValue
,
label
:
t
(
option
.
label
)
}
}),
]
}
value=
{
endpointType
}
onValueChange=
{
(
v
)
=>
v
!==
null
&&
setEndpointType
(
v
)
}
>
<
SelectTrigger
id=
'endpoint-type'
>
<
SelectValue
placeholder=
{
t
(
'Auto detect (default)'
)
}
/>
</
SelectTrigger
>
<
SelectContent
>
<
SelectContent
alignItemWithTrigger=
{
false
}
>
<
SelectGroup
>
{
endpointTypeOptions
.
map
((
option
)
=>
{
const
itemValue
=
option
.
value
return
(
...
...
@@ -446,6 +454,7 @@ export function ChannelTestDialog({
</
SelectItem
>
)
})
}
</
SelectGroup
>
</
SelectContent
>
</
Select
>
<
p
className=
'text-muted-foreground text-xs'
>
...
...
web/default/src/features/channels/components/dialogs/edit-tag-dialog.tsx
View file @
d98f0e8a
...
...
@@ -18,6 +18,7 @@ import { ScrollArea } from '@/components/ui/scroll-area'
import
{
Select
,
SelectContent
,
SelectGroup
,
SelectItem
,
SelectTrigger
,
SelectValue
,
...
...
@@ -276,6 +277,12 @@ export function EditTagDialog({ open, onOpenChange }: EditTagDialogProps) {
<
div
className=
'flex gap-2'
>
<
Select
<
string
>
items=
{
[
...
availableModels
.
map
((
model
)
=>
({
value
:
model
,
label
:
model
,
})),
]
}
onValueChange=
{
(
value
)
=>
{
if
(
value
===
null
)
return
if
(
!
selectedModels
.
includes
(
value
))
{
...
...
@@ -288,7 +295,8 @@ export function EditTagDialog({ open, onOpenChange }: EditTagDialogProps) {
placeholder=
{
t
(
'Add from available models...'
)
}
/>
</
SelectTrigger
>
<
SelectContent
>
<
SelectContent
alignItemWithTrigger=
{
false
}
>
<
SelectGroup
>
<
ScrollArea
className=
'h-60'
>
{
availableModels
.
map
((
model
)
=>
(
<
SelectItem
key=
{
model
}
value=
{
model
}
>
...
...
@@ -296,6 +304,7 @@ export function EditTagDialog({ open, onOpenChange }: EditTagDialogProps) {
</
SelectItem
>
))
}
</
ScrollArea
>
</
SelectGroup
>
</
SelectContent
>
</
Select
>
</
div
>
...
...
web/default/src/features/channels/components/dialogs/multi-key-manage-dialog.tsx
View file @
d98f0e8a
...
...
@@ -14,6 +14,7 @@ import {
import
{
Select
,
SelectContent
,
SelectGroup
,
SelectItem
,
SelectTrigger
,
SelectValue
,
...
...
@@ -257,18 +258,26 @@ export function MultiKeyManageDialog({
{
/* Toolbar */
}
<
div
className=
'flex shrink-0 items-center justify-between'
>
<
Select
items=
{
[
...
MULTI_KEY_FILTER_OPTIONS
.
map
((
option
)
=>
({
value
:
option
.
value
,
label
:
t
(
option
.
label
),
})),
]
}
value=
{
statusFilter
===
null
?
'all'
:
statusFilter
.
toString
()
}
onValueChange=
{
(
v
)
=>
v
!==
null
&&
handleStatusFilterChange
(
v
)
}
>
<
SelectTrigger
className=
'w-40'
>
<
SelectValue
placeholder=
{
t
(
'All Status'
)
}
/>
</
SelectTrigger
>
<
SelectContent
>
<
SelectContent
alignItemWithTrigger=
{
false
}
>
<
SelectGroup
>
{
MULTI_KEY_FILTER_OPTIONS
.
map
((
option
)
=>
(
<
SelectItem
key=
{
option
.
value
}
value=
{
option
.
value
}
>
{
t
(
option
.
label
)
}
</
SelectItem
>
))
}
</
SelectGroup
>
</
SelectContent
>
</
Select
>
...
...
web/default/src/features/channels/components/dialogs/param-override-editor-dialog.tsx
View file @
d98f0e8a
...
...
@@ -38,6 +38,7 @@ import { ScrollArea } from '@/components/ui/scroll-area'
import
{
Select
,
SelectContent
,
SelectGroup
,
SelectItem
,
SelectTrigger
,
SelectValue
,
...
...
@@ -1722,6 +1723,12 @@ export function ParamOverrideEditorDialog(
{
t
(
'Template'
)
}
</
span
>
<
Select
items=
{
[
...
templatePresetOptions
.
map
((
o
)
=>
({
value
:
o
.
value
,
label
:
t
(
o
.
label
),
})),
]
}
value=
{
templatePresetKey
}
onValueChange=
{
(
v
)
=>
setTemplatePresetKey
(
v
||
'operations_default'
)
...
...
@@ -1730,12 +1737,14 @@ export function ParamOverrideEditorDialog(
<
SelectTrigger
className=
'h-8 w-[220px]'
>
<
SelectValue
/>
</
SelectTrigger
>
<
SelectContent
>
<
SelectContent
alignItemWithTrigger=
{
false
}
>
<
SelectGroup
>
{
templatePresetOptions
.
map
((
o
)
=>
(
<
SelectItem
key=
{
o
.
value
}
value=
{
o
.
value
}
>
{
t
(
o
.
label
)
}
</
SelectItem
>
))
}
</
SelectGroup
>
</
SelectContent
>
</
Select
>
<
Button
...
...
@@ -2140,6 +2149,12 @@ function RuleEditor(ruleEditorProps: RuleEditorProps) {
<
div
className=
'space-y-1.5'
>
<
label
className=
'text-xs font-medium'
>
{
t
(
'Operation Type'
)
}
</
label
>
<
Select
items=
{
[
...
OPERATION_MODE_OPTIONS
.
map
((
o
)
=>
({
value
:
o
.
value
,
label
:
t
(
o
.
label
),
})),
]
}
value=
{
mode
}
onValueChange=
{
(
nextMode
)
=>
nextMode
!==
null
&&
...
...
@@ -2151,12 +2166,14 @@ function RuleEditor(ruleEditorProps: RuleEditorProps) {
<
SelectTrigger
className=
'h-9'
>
<
SelectValue
/>
</
SelectTrigger
>
<
SelectContent
>
<
SelectContent
alignItemWithTrigger=
{
false
}
>
<
SelectGroup
>
{
OPERATION_MODE_OPTIONS
.
map
((
o
)
=>
(
<
SelectItem
key=
{
o
.
value
}
value=
{
o
.
value
}
>
{
t
(
o
.
label
)
}
</
SelectItem
>
))
}
</
SelectGroup
>
</
SelectContent
>
</
Select
>
</
div
>
...
...
@@ -2339,6 +2356,10 @@ function RuleEditor(ruleEditorProps: RuleEditorProps) {
<
div
className=
'flex items-center gap-2'
>
<
span
className=
'text-sm font-medium'
>
{
t
(
'Conditions'
)
}
</
span
>
<
Select
items=
{
[
{
value
:
'OR'
,
label
:
t
(
'Match Any (OR)'
)
},
{
value
:
'AND'
,
label
:
t
(
'Match All (AND)'
)
},
]
}
value=
{
operation
.
logic
||
'OR'
}
onValueChange=
{
(
v
)
=>
v
!==
null
&&
...
...
@@ -2350,9 +2371,11 @@ function RuleEditor(ruleEditorProps: RuleEditorProps) {
<
SelectTrigger
className=
'h-7 w-[120px] text-xs'
>
<
SelectValue
/>
</
SelectTrigger
>
<
SelectContent
>
<
SelectContent
alignItemWithTrigger=
{
false
}
>
<
SelectGroup
>
<
SelectItem
value=
'OR'
>
{
t
(
'Match Any (OR)'
)
}
</
SelectItem
>
<
SelectItem
value=
'AND'
>
{
t
(
'Match All (AND)'
)
}
</
SelectItem
>
</
SelectGroup
>
</
SelectContent
>
</
Select
>
</
div
>
...
...
@@ -2515,6 +2538,12 @@ function ConditionEditor(conditionEditorProps: ConditionEditorProps) {
{
t
(
'Match Mode'
)
}
</
label
>
<
Select
items=
{
[
...
CONDITION_MODE_OPTIONS
.
map
((
o
)
=>
({
value
:
o
.
value
,
label
:
t
(
o
.
label
),
})),
]
}
value=
{
condition
.
mode
}
onValueChange=
{
(
v
)
=>
v
!==
null
&&
...
...
@@ -2528,12 +2557,14 @@ function ConditionEditor(conditionEditorProps: ConditionEditorProps) {
<
SelectTrigger
className=
'h-8 text-xs'
>
<
SelectValue
/>
</
SelectTrigger
>
<
SelectContent
>
<
SelectContent
alignItemWithTrigger=
{
false
}
>
<
SelectGroup
>
{
CONDITION_MODE_OPTIONS
.
map
((
o
)
=>
(
<
SelectItem
key=
{
o
.
value
}
value=
{
o
.
value
}
>
{
t
(
o
.
label
)
}
</
SelectItem
>
))
}
</
SelectGroup
>
</
SelectContent
>
</
Select
>
</
div
>
...
...
@@ -2889,6 +2920,10 @@ function PruneObjectsEditor(pruneObjectsEditorProps: PruneObjectsEditorProps) {
<
div
className=
'space-y-1'
>
<
label
className=
'text-xs font-medium'
>
{
t
(
'Logic'
)
}
</
label
>
<
Select
items=
{
[
{
value
:
'AND'
,
label
:
t
(
'All Must Match (AND)'
)
},
{
value
:
'OR'
,
label
:
t
(
'Any Match (OR)'
)
},
]
}
value=
{
draft
.
logic
}
onValueChange=
{
(
v
)
=>
pruneObjectsEditorProps
.
updateDraft
(
...
...
@@ -2900,11 +2935,13 @@ function PruneObjectsEditor(pruneObjectsEditorProps: PruneObjectsEditorProps) {
<
SelectTrigger
className=
'h-8 text-xs'
>
<
SelectValue
/>
</
SelectTrigger
>
<
SelectContent
>
<
SelectContent
alignItemWithTrigger=
{
false
}
>
<
SelectGroup
>
<
SelectItem
value=
'AND'
>
{
t
(
'All Must Match (AND)'
)
}
</
SelectItem
>
<
SelectItem
value=
'OR'
>
{
t
(
'Any Match (OR)'
)
}
</
SelectItem
>
</
SelectGroup
>
</
SelectContent
>
</
Select
>
</
div
>
...
...
@@ -3021,6 +3058,12 @@ function PruneObjectsEditor(pruneObjectsEditorProps: PruneObjectsEditorProps) {
{
t
(
'Match Mode'
)
}
</
label
>
<
Select
items=
{
[
...
CONDITION_MODE_OPTIONS
.
map
((
o
)
=>
({
value
:
o
.
value
,
label
:
t
(
o
.
label
),
})),
]
}
value=
{
rule
.
mode
}
onValueChange=
{
(
v
)
=>
v
!==
null
&&
...
...
@@ -3034,12 +3077,14 @@ function PruneObjectsEditor(pruneObjectsEditorProps: PruneObjectsEditorProps) {
<
SelectTrigger
className=
'h-7 text-xs'
>
<
SelectValue
/>
</
SelectTrigger
>
<
SelectContent
>
<
SelectContent
alignItemWithTrigger=
{
false
}
>
<
SelectGroup
>
{
CONDITION_MODE_OPTIONS
.
map
((
o
)
=>
(
<
SelectItem
key=
{
o
.
value
}
value=
{
o
.
value
}
>
{
t
(
o
.
label
)
}
</
SelectItem
>
))
}
</
SelectGroup
>
</
SelectContent
>
</
Select
>
</
div
>
...
...
@@ -3126,6 +3171,12 @@ function SyncFieldsEditor(syncFieldsEditorProps: SyncFieldsEditorProps) {
</
label
>
<
div
className=
'flex gap-2'
>
<
Select
items=
{
[
...
SYNC_TARGET_TYPE_OPTIONS
.
map
((
o
)
=>
({
value
:
o
.
value
,
label
:
t
(
o
.
label
),
})),
]
}
value=
{
syncFieldsEditorProps
.
syncFromTarget
.
type
||
'json'
}
onValueChange=
{
(
v
)
=>
v
!==
null
&&
...
...
@@ -3143,12 +3194,14 @@ function SyncFieldsEditor(syncFieldsEditorProps: SyncFieldsEditorProps) {
<
SelectTrigger
className=
'h-8 w-[110px] text-xs'
>
<
SelectValue
/>
</
SelectTrigger
>
<
SelectContent
>
<
SelectContent
alignItemWithTrigger=
{
false
}
>
<
SelectGroup
>
{
SYNC_TARGET_TYPE_OPTIONS
.
map
((
o
)
=>
(
<
SelectItem
key=
{
o
.
value
}
value=
{
o
.
value
}
>
{
t
(
o
.
label
)
}
</
SelectItem
>
))
}
</
SelectGroup
>
</
SelectContent
>
</
Select
>
<
Input
...
...
@@ -3175,6 +3228,12 @@ function SyncFieldsEditor(syncFieldsEditorProps: SyncFieldsEditorProps) {
</
label
>
<
div
className=
'flex gap-2'
>
<
Select
items=
{
[
...
SYNC_TARGET_TYPE_OPTIONS
.
map
((
o
)
=>
({
value
:
o
.
value
,
label
:
t
(
o
.
label
),
})),
]
}
value=
{
syncFieldsEditorProps
.
syncToTarget
.
type
||
'json'
}
onValueChange=
{
(
v
)
=>
v
!==
null
&&
...
...
@@ -3192,12 +3251,14 @@ function SyncFieldsEditor(syncFieldsEditorProps: SyncFieldsEditorProps) {
<
SelectTrigger
className=
'h-8 w-[110px] text-xs'
>
<
SelectValue
/>
</
SelectTrigger
>
<
SelectContent
>
<
SelectContent
alignItemWithTrigger=
{
false
}
>
<
SelectGroup
>
{
SYNC_TARGET_TYPE_OPTIONS
.
map
((
o
)
=>
(
<
SelectItem
key=
{
o
.
value
}
value=
{
o
.
value
}
>
{
t
(
o
.
label
)
}
</
SelectItem
>
))
}
</
SelectGroup
>
</
SelectContent
>
</
Select
>
<
Input
...
...
web/default/src/features/channels/components/drawers/channel-mutate-drawer.tsx
View file @
d98f0e8a
...
...
@@ -59,6 +59,7 @@ import { Input } from '@/components/ui/input'
import
{
Select
,
SelectContent
,
SelectGroup
,
SelectItem
,
SelectTrigger
,
SelectValue
,
...
...
@@ -1376,6 +1377,13 @@ export function ChannelMutateDrawer({
<
FormItem
>
<
FormLabel
>
{
t
(
'AWS Key Format'
)
}
</
FormLabel
>
<
Select
items=
{
[
{
value
:
'ak_sk'
,
label
:
t
(
'AccessKey / SecretAccessKey'
),
},
{
value
:
'api_key'
,
label
:
t
(
'API Key'
)
},
]
}
onValueChange=
{
field
.
onChange
}
value=
{
field
.
value
}
>
...
...
@@ -1386,13 +1394,15 @@ export function ChannelMutateDrawer({
/>
</
SelectTrigger
>
</
FormControl
>
<
SelectContent
>
<
SelectContent
alignItemWithTrigger=
{
false
}
>
<
SelectGroup
>
<
SelectItem
value=
'ak_sk'
>
{
t
(
'AccessKey / SecretAccessKey'
)
}
</
SelectItem
>
<
SelectItem
value=
'api_key'
>
{
t
(
'API Key'
)
}
</
SelectItem
>
</
SelectGroup
>
</
SelectContent
>
</
Select
>
<
FormDescription
>
...
...
@@ -1534,6 +1544,10 @@ export function ChannelMutateDrawer({
<
FormItem
>
<
FormLabel
>
{
t
(
'Vertex AI Key Format'
)
}
</
FormLabel
>
<
Select
items=
{
[
{
value
:
'json'
,
label
:
t
(
'JSON'
)
},
{
value
:
'api_key'
,
label
:
t
(
'API Key'
)
},
]
}
onValueChange=
{
field
.
onChange
}
value=
{
field
.
value
}
>
...
...
@@ -1542,11 +1556,15 @@ export function ChannelMutateDrawer({
<
SelectValue
/>
</
SelectTrigger
>
</
FormControl
>
<
SelectContent
>
<
SelectItem
value=
'json'
>
{
t
(
'JSON'
)
}
</
SelectItem
>
<
SelectContent
alignItemWithTrigger=
{
false
}
>
<
SelectGroup
>
<
SelectItem
value=
'json'
>
{
t
(
'JSON'
)
}
</
SelectItem
>
<
SelectItem
value=
'api_key'
>
{
t
(
'API Key'
)
}
</
SelectItem
>
</
SelectGroup
>
</
SelectContent
>
</
Select
>
<
FormDescription
>
...
...
@@ -1672,6 +1690,22 @@ export function ChannelMutateDrawer({
{
t
(
'API Base URL *'
)
}
</
FormLabel
>
<
Select
items=
{
[
{
value
:
'https://ark.cn-beijing.volces.com'
,
label
:
t
(
'https://ark.cn-beijing.volces.com'
),
},
{
value
:
'https://ark.ap-southeast.bytepluses.com'
,
label
:
t
(
'https://ark.ap-southeast.bytepluses.com'
),
},
{
value
:
'doubao-coding-plan'
,
label
:
t
(
'Doubao Coding Plan'
),
},
]
}
onValueChange=
{
field
.
onChange
}
value=
{
field
.
value
||
'https://ark.cn-beijing.volces.com'
...
...
@@ -1682,7 +1716,8 @@ export function ChannelMutateDrawer({
<
SelectValue
/>
</
SelectTrigger
>
</
FormControl
>
<
SelectContent
>
<
SelectContent
alignItemWithTrigger=
{
false
}
>
<
SelectGroup
>
<
SelectItem
value=
'https://ark.cn-beijing.volces.com'
>
{
t
(
'https://ark.cn-beijing.volces.com'
)
}
</
SelectItem
>
...
...
@@ -1692,6 +1727,7 @@ export function ChannelMutateDrawer({
<
SelectItem
value=
'doubao-coding-plan'
>
{
t
(
'Doubao Coding Plan'
)
}
</
SelectItem
>
</
SelectGroup
>
</
SelectContent
>
</
Select
>
<
FormDescription
>
...
...
@@ -1790,6 +1826,12 @@ export function ChannelMutateDrawer({
<
FormItem
>
<
FormLabel
>
{
t
(
'Add Mode'
)
}
</
FormLabel
>
<
Select
items=
{
[
...
ADD_MODE_OPTIONS
.
map
((
option
)
=>
({
value
:
option
.
value
,
label
:
t
(
option
.
label
),
})),
]
}
onValueChange=
{
field
.
onChange
}
value=
{
field
.
value
}
>
...
...
@@ -1798,7 +1840,8 @@ export function ChannelMutateDrawer({
<
SelectValue
/>
</
SelectTrigger
>
</
FormControl
>
<
SelectContent
>
<
SelectContent
alignItemWithTrigger=
{
false
}
>
<
SelectGroup
>
{
ADD_MODE_OPTIONS
.
map
((
option
)
=>
(
<
SelectItem
key=
{
option
.
value
}
...
...
@@ -1807,6 +1850,7 @@ export function ChannelMutateDrawer({
{
t
(
option
.
label
)
}
</
SelectItem
>
))
}
</
SelectGroup
>
</
SelectContent
>
</
Select
>
<
FormDescription
>
...
...
@@ -2027,6 +2071,16 @@ export function ChannelMutateDrawer({
<
FormItem
>
<
FormLabel
>
{
t
(
'Key Update Mode'
)
}
</
FormLabel
>
<
Select
items=
{
[
{
value
:
'append'
,
label
:
t
(
'Append to existing keys'
),
},
{
value
:
'replace'
,
label
:
t
(
'Replace all existing keys'
),
},
]
}
onValueChange=
{
field
.
onChange
}
value=
{
field
.
value
}
>
...
...
@@ -2035,13 +2089,15 @@ export function ChannelMutateDrawer({
<
SelectValue
/>
</
SelectTrigger
>
</
FormControl
>
<
SelectContent
>
<
SelectContent
alignItemWithTrigger=
{
false
}
>
<
SelectGroup
>
<
SelectItem
value=
'append'
>
{
t
(
'Append to existing keys'
)
}
</
SelectItem
>
<
SelectItem
value=
'replace'
>
{
t
(
'Replace all existing keys'
)
}
</
SelectItem
>
</
SelectGroup
>
</
SelectContent
>
</
Select
>
<
FormDescription
>
...
...
@@ -2067,6 +2123,10 @@ export function ChannelMutateDrawer({
<
FormItem
>
<
FormLabel
>
{
t
(
'Multi-Key Strategy'
)
}
</
FormLabel
>
<
Select
items=
{
[
{
value
:
'random'
,
label
:
t
(
'Random'
)
},
{
value
:
'polling'
,
label
:
t
(
'Polling'
)
},
]
}
onValueChange=
{
field
.
onChange
}
value=
{
field
.
value
}
>
...
...
@@ -2075,13 +2135,15 @@ export function ChannelMutateDrawer({
<
SelectValue
/>
</
SelectTrigger
>
</
FormControl
>
<
SelectContent
>
<
SelectContent
alignItemWithTrigger=
{
false
}
>
<
SelectGroup
>
<
SelectItem
value=
'random'
>
{
t
(
'Random'
)
}
</
SelectItem
>
<
SelectItem
value=
'polling'
>
{
t
(
'Polling'
)
}
</
SelectItem
>
</
SelectGroup
>
</
SelectContent
>
</
Select
>
<
FormDescription
>
...
...
web/default/src/features/dashboard/components/models/models-chart-preferences.tsx
View file @
d98f0e8a
...
...
@@ -16,6 +16,7 @@ import { Label } from '@/components/ui/label'
import
{
Select
,
SelectContent
,
SelectGroup
,
SelectItem
,
SelectTrigger
,
SelectValue
,
...
...
@@ -73,6 +74,12 @@ export function ModelsChartPreferences(props: ModelsChartPreferencesProps) {
<
div
className=
'grid gap-2'
>
<
Label
htmlFor=
'default-time-range'
>
{
t
(
'Default range'
)
}
</
Label
>
<
Select
items=
{
[
...
TIME_RANGE_PRESETS
.
map
((
option
)
=>
({
value
:
String
(
option
.
days
),
label
:
t
(
option
.
label
),
})),
]
}
value=
{
String
(
draft
.
defaultTimeRangeDays
)
}
onValueChange=
{
(
value
)
=>
setDraft
((
prev
)
=>
({
...
...
@@ -84,12 +91,14 @@ export function ModelsChartPreferences(props: ModelsChartPreferencesProps) {
<
SelectTrigger
id=
'default-time-range'
>
<
SelectValue
placeholder=
{
t
(
'Select default range'
)
}
/>
</
SelectTrigger
>
<
SelectContent
>
<
SelectContent
alignItemWithTrigger=
{
false
}
>
<
SelectGroup
>
{
TIME_RANGE_PRESETS
.
map
((
option
)
=>
(
<
SelectItem
key=
{
option
.
days
}
value=
{
String
(
option
.
days
)
}
>
{
t
(
option
.
label
)
}
</
SelectItem
>
))
}
</
SelectGroup
>
</
SelectContent
>
</
Select
>
</
div
>
...
...
@@ -99,6 +108,12 @@ export function ModelsChartPreferences(props: ModelsChartPreferencesProps) {
{
t
(
'Default time granularity'
)
}
</
Label
>
<
Select
items=
{
[
...
TIME_GRANULARITY_OPTIONS
.
map
((
option
)
=>
({
value
:
option
.
value
,
label
:
t
(
option
.
label
),
})),
]
}
value=
{
draft
.
defaultTimeGranularity
}
onValueChange=
{
(
value
)
=>
setDraft
((
prev
)
=>
({
...
...
@@ -110,12 +125,14 @@ export function ModelsChartPreferences(props: ModelsChartPreferencesProps) {
<
SelectTrigger
id=
'default-time-granularity'
>
<
SelectValue
placeholder=
{
t
(
'Select time granularity'
)
}
/>
</
SelectTrigger
>
<
SelectContent
>
<
SelectContent
alignItemWithTrigger=
{
false
}
>
<
SelectGroup
>
{
TIME_GRANULARITY_OPTIONS
.
map
((
option
)
=>
(
<
SelectItem
key=
{
option
.
value
}
value=
{
option
.
value
}
>
{
t
(
option
.
label
)
}
</
SelectItem
>
))
}
</
SelectGroup
>
</
SelectContent
>
</
Select
>
</
div
>
...
...
@@ -125,6 +142,12 @@ export function ModelsChartPreferences(props: ModelsChartPreferencesProps) {
{
t
(
'Default consumption chart'
)
}
</
Label
>
<
Select
items=
{
[
...
CONSUMPTION_DISTRIBUTION_CHART_OPTIONS
.
map
((
option
)
=>
({
value
:
option
.
value
,
label
:
t
(
option
.
labelKey
),
})),
]
}
value=
{
draft
.
consumptionDistributionChart
}
onValueChange=
{
(
value
)
=>
setDraft
((
prev
)
=>
({
...
...
@@ -137,12 +160,14 @@ export function ModelsChartPreferences(props: ModelsChartPreferencesProps) {
<
SelectTrigger
id=
'consumption-distribution-chart'
>
<
SelectValue
placeholder=
{
t
(
'Select default chart'
)
}
/>
</
SelectTrigger
>
<
SelectContent
>
<
SelectContent
alignItemWithTrigger=
{
false
}
>
<
SelectGroup
>
{
CONSUMPTION_DISTRIBUTION_CHART_OPTIONS
.
map
((
option
)
=>
(
<
SelectItem
key=
{
option
.
value
}
value=
{
option
.
value
}
>
{
t
(
option
.
labelKey
)
}
</
SelectItem
>
))
}
</
SelectGroup
>
</
SelectContent
>
</
Select
>
</
div
>
...
...
@@ -152,6 +177,12 @@ export function ModelsChartPreferences(props: ModelsChartPreferencesProps) {
{
t
(
'Default model call chart'
)
}
</
Label
>
<
Select
items=
{
[
...
MODEL_ANALYTICS_CHART_OPTIONS
.
map
((
option
)
=>
({
value
:
option
.
value
,
label
:
t
(
option
.
labelKey
),
})),
]
}
value=
{
draft
.
modelAnalyticsChart
}
onValueChange=
{
(
value
)
=>
setDraft
((
prev
)
=>
({
...
...
@@ -163,12 +194,14 @@ export function ModelsChartPreferences(props: ModelsChartPreferencesProps) {
<
SelectTrigger
id=
'model-analytics-chart'
>
<
SelectValue
placeholder=
{
t
(
'Select default chart'
)
}
/>
</
SelectTrigger
>
<
SelectContent
>
<
SelectContent
alignItemWithTrigger=
{
false
}
>
<
SelectGroup
>
{
MODEL_ANALYTICS_CHART_OPTIONS
.
map
((
option
)
=>
(
<
SelectItem
key=
{
option
.
value
}
value=
{
option
.
value
}
>
{
t
(
option
.
labelKey
)
}
</
SelectItem
>
))
}
</
SelectGroup
>
</
SelectContent
>
</
Select
>
</
div
>
...
...
web/default/src/features/dashboard/components/models/models-filter-dialog.tsx
View file @
d98f0e8a
...
...
@@ -20,6 +20,7 @@ import { ScrollArea } from '@/components/ui/scroll-area'
import
{
Select
,
SelectContent
,
SelectGroup
,
SelectItem
,
SelectTrigger
,
SelectValue
,
...
...
@@ -197,6 +198,12 @@ export function ModelsFilter(props: ModelsFilterProps) {
<
div
className=
'grid gap-2'
>
<
Label
htmlFor=
'time_granularity'
>
{
t
(
'Time Granularity'
)
}
</
Label
>
<
Select
items=
{
[
...
TIME_GRANULARITY_OPTIONS
.
map
((
option
)
=>
({
value
:
option
.
value
,
label
:
t
(
option
.
label
),
})),
]
}
value=
{
filters
.
time_granularity
}
onValueChange=
{
(
value
)
=>
handleChange
(
'time_granularity'
,
value
as
TimeGranularity
)
...
...
@@ -205,12 +212,14 @@ export function ModelsFilter(props: ModelsFilterProps) {
<
SelectTrigger
>
<
SelectValue
placeholder=
{
t
(
'Select time granularity'
)
}
/>
</
SelectTrigger
>
<
SelectContent
>
<
SelectContent
alignItemWithTrigger=
{
false
}
>
<
SelectGroup
>
{
TIME_GRANULARITY_OPTIONS
.
map
((
option
)
=>
(
<
SelectItem
key=
{
option
.
value
}
value=
{
option
.
value
}
>
{
t
(
option
.
label
)
}
</
SelectItem
>
))
}
</
SelectGroup
>
</
SelectContent
>
</
Select
>
</
div
>
...
...
web/default/src/features/models/components/dialogs/create-deployment-drawer.tsx
View file @
d98f0e8a
...
...
@@ -18,6 +18,7 @@ import { Input } from '@/components/ui/input'
import
{
Select
,
SelectContent
,
SelectGroup
,
SelectItem
,
SelectTrigger
,
SelectValue
,
...
...
@@ -432,6 +433,12 @@ export function CreateDeploymentDrawer({
<
FormItem
>
<
FormLabel
>
{
t
(
'Hardware type'
)
}
</
FormLabel
>
<
Select
items=
{
[
...
hardwareOptions
.
map
((
opt
)
=>
({
value
:
opt
.
value
,
label
:
opt
.
label
,
})),
]
}
value=
{
field
.
value
}
onValueChange=
{
(
v
)
=>
field
.
onChange
(
v
)
}
disabled=
{
isLoadingHardware
}
...
...
@@ -441,12 +448,14 @@ export function CreateDeploymentDrawer({
<
SelectValue
placeholder=
{
t
(
'Select'
)
}
/>
</
SelectTrigger
>
</
FormControl
>
<
SelectContent
>
<
SelectContent
alignItemWithTrigger=
{
false
}
>
<
SelectGroup
>
{
hardwareOptions
.
map
((
opt
)
=>
(
<
SelectItem
key=
{
opt
.
value
}
value=
{
opt
.
value
}
>
{
opt
.
label
}
</
SelectItem
>
))
}
</
SelectGroup
>
</
SelectContent
>
</
Select
>
<
FormMessage
/>
...
...
@@ -593,6 +602,10 @@ export function CreateDeploymentDrawer({
<
FormItem
>
<
FormLabel
>
{
t
(
'Billing currency'
)
}
</
FormLabel
>
<
Select
items=
{
[
{
value
:
'usdc'
,
label
:
'USDC'
},
{
value
:
'iocoin'
,
label
:
'IOCOIN'
},
]
}
value=
{
field
.
value
||
'usdc'
}
onValueChange=
{
(
v
)
=>
field
.
onChange
(
v
)
}
>
...
...
@@ -601,9 +614,11 @@ export function CreateDeploymentDrawer({
<
SelectValue
placeholder=
{
t
(
'Select'
)
}
/>
</
SelectTrigger
>
</
FormControl
>
<
SelectContent
>
<
SelectContent
alignItemWithTrigger=
{
false
}
>
<
SelectGroup
>
<
SelectItem
value=
'usdc'
>
USDC
</
SelectItem
>
<
SelectItem
value=
'iocoin'
>
IOCOIN
</
SelectItem
>
</
SelectGroup
>
</
SelectContent
>
</
Select
>
</
FormItem
>
...
...
web/default/src/features/models/components/dialogs/upstream-conflict-dialog.tsx
View file @
d98f0e8a
...
...
@@ -36,6 +36,7 @@ import {
import
{
Select
,
SelectContent
,
SelectGroup
,
SelectItem
,
SelectTrigger
,
SelectValue
,
...
...
@@ -550,6 +551,12 @@ export function UpstreamConflictDialog({
{
t
(
'Rows per page'
)
}
</
span
>
<
Select
items=
{
[
...[
5
,
10
,
20
,
50
].
map
((
size
)
=>
({
value
:
String
(
size
),
label
:
size
,
})),
]
}
value=
{
String
(
pageSize
)
}
onValueChange=
{
(
value
)
=>
{
setPageSize
(
Number
(
value
))
...
...
@@ -559,12 +566,14 @@ export function UpstreamConflictDialog({
<
SelectTrigger
className=
'h-8 w-[70px] text-xs sm:h-8 sm:w-[72px]'
>
<
SelectValue
/>
</
SelectTrigger
>
<
SelectContent
>
<
SelectContent
alignItemWithTrigger=
{
false
}
>
<
SelectGroup
>
{
[
5
,
10
,
20
,
50
].
map
((
size
)
=>
(
<
SelectItem
key=
{
size
}
value=
{
String
(
size
)
}
>
{
size
}
</
SelectItem
>
))
}
</
SelectGroup
>
</
SelectContent
>
</
Select
>
</
div
>
...
...
web/default/src/features/models/components/dialogs/view-logs-dialog.tsx
View file @
d98f0e8a
...
...
@@ -12,6 +12,7 @@ import {
import
{
Select
,
SelectContent
,
SelectGroup
,
SelectItem
,
SelectTrigger
,
SelectValue
,
...
...
@@ -175,6 +176,27 @@ export function ViewLogsDialog({
{
t
(
'Container'
)
}
</
div
>
<
Select
items=
{
[
...
containers
.
flatMap
((
c
)
=>
{
const
id
=
c
?.
container_id
if
(
typeof
id
!==
'string'
||
!
id
)
return
[]
const
status
=
typeof
c
?.
status
===
'string'
&&
c
.
status
?
` (${c.status})`
:
''
return
[
{
value
:
id
,
label
:
(
<>
{
id
}
{
status
}
</>
),
},
]
}),
]
}
value=
{
containerId
}
onValueChange=
{
(
v
)
=>
v
!==
null
&&
setContainerId
(
v
)
}
disabled=
{
isLoadingContainers
||
containers
.
length
===
0
}
...
...
@@ -190,7 +212,8 @@ export function ViewLogsDialog({
}
/>
</
SelectTrigger
>
<
SelectContent
>
<
SelectContent
alignItemWithTrigger=
{
false
}
>
<
SelectGroup
>
{
containers
.
map
((
c
)
=>
{
const
id
=
c
?.
container_id
if
(
typeof
id
!==
'string'
||
!
id
)
return
null
...
...
@@ -205,12 +228,18 @@ export function ViewLogsDialog({
</
SelectItem
>
)
})
}
</
SelectGroup
>
</
SelectContent
>
</
Select
>
</
div
>
<
div
className=
'space-y-1'
>
<
div
className=
'text-muted-foreground text-xs'
>
{
t
(
'Stream'
)
}
</
div
>
<
Select
items=
{
[
{
value
:
'stdout'
,
label
:
'stdout'
},
{
value
:
'stderr'
,
label
:
'stderr'
},
{
value
:
'all'
,
label
:
'all'
},
]
}
value=
{
stream
}
onValueChange=
{
(
v
)
=>
{
if
(
v
===
'stderr'
||
v
===
'all'
||
v
===
'stdout'
)
{
...
...
@@ -223,10 +252,12 @@ export function ViewLogsDialog({
<
SelectTrigger
>
<
SelectValue
placeholder=
{
t
(
'Select'
)
}
/>
</
SelectTrigger
>
<
SelectContent
>
<
SelectContent
alignItemWithTrigger=
{
false
}
>
<
SelectGroup
>
<
SelectItem
value=
'stdout'
>
stdout
</
SelectItem
>
<
SelectItem
value=
'stderr'
>
stderr
</
SelectItem
>
<
SelectItem
value=
'all'
>
all
</
SelectItem
>
</
SelectGroup
>
</
SelectContent
>
</
Select
>
</
div
>
...
...
web/default/src/features/models/components/drawers/model-mutate-drawer.tsx
View file @
d98f0e8a
...
...
@@ -27,6 +27,7 @@ import { RadioGroup, RadioGroupItem } from '@/components/ui/radio-group'
import
{
Select
,
SelectContent
,
SelectGroup
,
SelectItem
,
SelectTrigger
,
SelectValue
,
...
...
@@ -701,6 +702,12 @@ export function ModelMutateDrawer({
<
FormItem
>
<
FormLabel
>
{
t
(
'Vendor'
)
}
</
FormLabel
>
<
Select
items=
{
[
...
vendors
.
map
((
vendor
)
=>
({
value
:
String
(
vendor
.
id
),
label
:
vendor
.
name
,
})),
]
}
onValueChange=
{
(
value
)
=>
field
.
onChange
(
value
?
parseInt
(
value
)
:
undefined
)
}
...
...
@@ -711,12 +718,17 @@ export function ModelMutateDrawer({
<
SelectValue
placeholder=
{
t
(
'Select vendor'
)
}
/>
</
SelectTrigger
>
</
FormControl
>
<
SelectContent
>
<
SelectContent
alignItemWithTrigger=
{
false
}
>
<
SelectGroup
>
{
vendors
.
map
((
vendor
)
=>
(
<
SelectItem
key=
{
vendor
.
id
}
value=
{
String
(
vendor
.
id
)
}
>
<
SelectItem
key=
{
vendor
.
id
}
value=
{
String
(
vendor
.
id
)
}
>
{
vendor
.
name
}
</
SelectItem
>
))
}
</
SelectGroup
>
</
SelectContent
>
</
Select
>
<
FormMessage
/>
...
...
@@ -801,6 +813,12 @@ export function ModelMutateDrawer({
<
div
className=
'flex items-center justify-between'
>
<
h3
className=
'text-sm font-semibold'
>
{
t
(
'Endpoints'
)
}
</
h3
>
<
Select
<
string
>
items=
{
[
...
Object
.
keys
(
ENDPOINT_TEMPLATES
).
map
((
key
)
=>
({
value
:
key
,
label
:
key
,
})),
]
}
onValueChange=
{
(
v
)
=>
v
!==
null
&&
handleFillEndpointTemplate
(
v
)
}
...
...
@@ -808,12 +826,14 @@ export function ModelMutateDrawer({
<
SelectTrigger
size=
'sm'
className=
'w-[200px]'
>
<
SelectValue
placeholder=
{
t
(
'Load template...'
)
}
/>
</
SelectTrigger
>
<
SelectContent
>
<
SelectContent
alignItemWithTrigger=
{
false
}
>
<
SelectGroup
>
{
Object
.
keys
(
ENDPOINT_TEMPLATES
).
map
((
key
)
=>
(
<
SelectItem
key=
{
key
}
value=
{
key
}
>
{
key
}
</
SelectItem
>
))
}
</
SelectGroup
>
</
SelectContent
>
</
Select
>
</
div
>
...
...
web/default/src/features/models/components/drawers/prefill-group-form-drawer.tsx
View file @
d98f0e8a
...
...
@@ -19,6 +19,7 @@ import { Input } from '@/components/ui/input'
import
{
Select
,
SelectContent
,
SelectGroup
,
SelectItem
,
SelectTrigger
,
SelectValue
,
...
...
@@ -252,6 +253,22 @@ export function PrefillGroupFormDrawer({
<
FormItem
>
<
FormLabel
>
Group Type
</
FormLabel
>
<
Select
items=
{
[
...
PREFILL_GROUP_TYPES
.
map
((
type
)
=>
({
value
:
type
.
value
,
label
:
(
<
div
className=
'flex flex-col text-left'
>
<
span
className=
'font-medium'
>
{
type
.
label
}
</
span
>
<
span
data
-
prefill
-
description
className=
'text-muted-foreground text-xs'
>
{
type
.
description
}
</
span
>
</
div
>
),
})),
]
}
value=
{
field
.
value
}
onValueChange=
{
(
value
)
=>
value
!==
null
&&
...
...
@@ -263,11 +280,14 @@ export function PrefillGroupFormDrawer({
<
SelectValue
placeholder=
{
t
(
'Select a group type'
)
}
/>
</
SelectTrigger
>
</
FormControl
>
<
SelectContent
>
<
SelectContent
alignItemWithTrigger=
{
false
}
>
<
SelectGroup
>
{
PREFILL_GROUP_TYPES
.
map
((
type
)
=>
(
<
SelectItem
key=
{
type
.
value
}
value=
{
type
.
value
}
>
<
div
className=
'flex flex-col text-left'
>
<
span
className=
'font-medium'
>
{
type
.
label
}
</
span
>
<
span
className=
'font-medium'
>
{
type
.
label
}
</
span
>
<
span
data
-
prefill
-
description
className=
'text-muted-foreground text-xs'
...
...
@@ -277,6 +297,7 @@ export function PrefillGroupFormDrawer({
</
div
>
</
SelectItem
>
))
}
</
SelectGroup
>
</
SelectContent
>
</
Select
>
<
FormDescription
>
...
...
web/default/src/features/profile/components/language-preferences-card.tsx
View file @
d98f0e8a
...
...
@@ -6,6 +6,7 @@ import { useAuthStore } from '@/stores/auth-store'
import
{
Select
,
SelectContent
,
SelectGroup
,
SelectItem
,
SelectTrigger
,
SelectValue
,
...
...
@@ -112,6 +113,12 @@ export function LanguagePreferencesCard(props: LanguagePreferencesCardProps) {
</
div
>
<
div
className=
'flex items-center gap-2 sm:min-w-48'
>
<
Select
items=
{
[
...
LANGUAGE_OPTIONS
.
map
((
language
)
=>
({
value
:
language
.
value
,
label
:
language
.
label
,
})),
]
}
value=
{
currentLanguage
}
onValueChange=
{
handleLanguageChange
}
disabled=
{
saving
}
...
...
@@ -119,12 +126,14 @@ export function LanguagePreferencesCard(props: LanguagePreferencesCardProps) {
<
SelectTrigger
className=
'w-full sm:w-48'
>
<
SelectValue
placeholder=
{
t
(
'Select language'
)
}
/>
</
SelectTrigger
>
<
SelectContent
>
<
SelectContent
alignItemWithTrigger=
{
false
}
>
<
SelectGroup
>
{
LANGUAGE_OPTIONS
.
map
((
language
)
=>
(
<
SelectItem
key=
{
language
.
value
}
value=
{
language
.
value
}
>
{
language
.
label
}
</
SelectItem
>
))
}
</
SelectGroup
>
</
SelectContent
>
</
Select
>
{
saving
&&
(
...
...
web/default/src/features/subscriptions/components/dialogs/subscription-purchase-dialog.tsx
View file @
d98f0e8a
...
...
@@ -13,6 +13,7 @@ import {
import
{
Select
,
SelectContent
,
SelectGroup
,
SelectItem
,
SelectTrigger
,
SelectValue
,
...
...
@@ -270,6 +271,12 @@ export function SubscriptionPurchaseDialog(props: Props) {
{
hasEpay
&&
(
<
div
className=
'grid grid-cols-[minmax(0,1fr)_auto] gap-2'
>
<
Select
items=
{
[
...(
props
.
epayMethods
||
[]).
map
((
m
)
=>
({
value
:
m
.
type
,
label
:
m
.
name
||
m
.
type
,
})),
]
}
value=
{
selectedEpayMethod
}
onValueChange=
{
(
v
)
=>
v
!==
null
&&
setSelectedEpayMethod
(
v
)
...
...
@@ -279,12 +286,14 @@ export function SubscriptionPurchaseDialog(props: Props) {
<
SelectTrigger
className=
'flex-1'
>
<
SelectValue
>
{
selectedEpayMethodLabel
}
</
SelectValue
>
</
SelectTrigger
>
<
SelectContent
>
<
SelectContent
alignItemWithTrigger=
{
false
}
>
<
SelectGroup
>
{
(
props
.
epayMethods
||
[]).
map
((
m
)
=>
(
<
SelectItem
key=
{
m
.
type
}
value=
{
m
.
type
}
>
{
m
.
name
||
m
.
type
}
</
SelectItem
>
))
}
</
SelectGroup
>
</
SelectContent
>
</
Select
>
<
Button
...
...
web/default/src/features/subscriptions/components/dialogs/user-subscriptions-dialog.tsx
View file @
d98f0e8a
...
...
@@ -6,6 +6,7 @@ import { Button } from '@/components/ui/button'
import
{
Select
,
SelectContent
,
SelectGroup
,
SelectItem
,
SelectTrigger
,
SelectValue
,
...
...
@@ -183,19 +184,32 @@ export function UserSubscriptionsDialog(props: Props) {
<
div
className=
'mt-4 space-y-4'
>
<
div
className=
'flex gap-2'
>
<
Select
items=
{
[
...
plans
.
map
((
p
)
=>
({
value
:
String
(
p
.
plan
.
id
),
label
:
(
<>
{
p
.
plan
.
title
}
($
{
Number
(
p
.
plan
.
price_amount
||
0
).
toFixed
(
2
)
}
)
</>
),
})),
]
}
value=
{
selectedPlanId
}
onValueChange=
{
(
v
)
=>
v
!==
null
&&
setSelectedPlanId
(
v
)
}
>
<
SelectTrigger
className=
'flex-1'
>
<
SelectValue
placeholder=
{
t
(
'Select subscription plan'
)
}
/>
</
SelectTrigger
>
<
SelectContent
>
<
SelectContent
alignItemWithTrigger=
{
false
}
>
<
SelectGroup
>
{
plans
.
map
((
p
)
=>
(
<
SelectItem
key=
{
p
.
plan
.
id
}
value=
{
String
(
p
.
plan
.
id
)
}
>
{
p
.
plan
.
title
}
($
{
Number
(
p
.
plan
.
price_amount
||
0
).
toFixed
(
2
)
}
)
</
SelectItem
>
))
}
</
SelectGroup
>
</
SelectContent
>
</
Select
>
<
Button
...
...
web/default/src/features/subscriptions/components/subscriptions-mutate-drawer.tsx
View file @
d98f0e8a
...
...
@@ -18,6 +18,7 @@ import { Input } from '@/components/ui/input'
import
{
Select
,
SelectContent
,
SelectGroup
,
SelectItem
,
SelectTrigger
,
SelectValue
,
...
...
@@ -237,6 +238,10 @@ export function SubscriptionsMutateDrawer({
<
FormItem
>
<
FormLabel
>
{
t
(
'Upgrade Group'
)
}
</
FormLabel
>
<
Select
items=
{
[
{
value
:
'__none__'
,
label
:
t
(
'No Upgrade'
)
},
...
groupOptions
.
map
((
g
)
=>
({
value
:
g
,
label
:
g
})),
]
}
onValueChange=
{
(
v
)
=>
field
.
onChange
(
v
===
'__none__'
?
''
:
v
)
}
...
...
@@ -247,7 +252,8 @@ export function SubscriptionsMutateDrawer({
<
SelectValue
placeholder=
{
t
(
'No Upgrade'
)
}
/>
</
SelectTrigger
>
</
FormControl
>
<
SelectContent
>
<
SelectContent
alignItemWithTrigger=
{
false
}
>
<
SelectGroup
>
<
SelectItem
value=
'__none__'
>
{
t
(
'No Upgrade'
)
}
</
SelectItem
>
...
...
@@ -256,6 +262,7 @@ export function SubscriptionsMutateDrawer({
{
g
}
</
SelectItem
>
))
}
</
SelectGroup
>
</
SelectContent
>
</
Select
>
<
FormMessage
/>
...
...
@@ -344,6 +351,12 @@ export function SubscriptionsMutateDrawer({
<
FormItem
>
<
FormLabel
>
{
t
(
'Duration Unit'
)
}
</
FormLabel
>
<
Select
items=
{
[
...
durationUnitOpts
.
map
((
o
)
=>
({
value
:
o
.
value
,
label
:
o
.
label
,
})),
]
}
onValueChange=
{
field
.
onChange
}
value=
{
field
.
value
}
>
...
...
@@ -352,12 +365,14 @@ export function SubscriptionsMutateDrawer({
<
SelectValue
/>
</
SelectTrigger
>
</
FormControl
>
<
SelectContent
>
<
SelectContent
alignItemWithTrigger=
{
false
}
>
<
SelectGroup
>
{
durationUnitOpts
.
map
((
o
)
=>
(
<
SelectItem
key=
{
o
.
value
}
value=
{
o
.
value
}
>
{
o
.
label
}
</
SelectItem
>
))
}
</
SelectGroup
>
</
SelectContent
>
</
Select
>
<
FormMessage
/>
...
...
@@ -426,6 +441,12 @@ export function SubscriptionsMutateDrawer({
<
FormItem
>
<
FormLabel
>
{
t
(
'Reset Cycle'
)
}
</
FormLabel
>
<
Select
items=
{
[
...
resetPeriodOpts
.
map
((
o
)
=>
({
value
:
o
.
value
,
label
:
o
.
label
,
})),
]
}
onValueChange=
{
field
.
onChange
}
value=
{
field
.
value
}
>
...
...
@@ -434,12 +455,14 @@ export function SubscriptionsMutateDrawer({
<
SelectValue
/>
</
SelectTrigger
>
</
FormControl
>
<
SelectContent
>
<
SelectContent
alignItemWithTrigger=
{
false
}
>
<
SelectGroup
>
{
resetPeriodOpts
.
map
((
o
)
=>
(
<
SelectItem
key=
{
o
.
value
}
value=
{
o
.
value
}
>
{
o
.
label
}
</
SelectItem
>
))
}
</
SelectGroup
>
</
SelectContent
>
</
Select
>
<
FormMessage
/>
...
...
web/default/src/features/system-settings/auth/custom-oauth/components/preset-selector.tsx
View file @
d98f0e8a
...
...
@@ -6,6 +6,7 @@ import { Label } from '@/components/ui/label'
import
{
Select
,
SelectContent
,
SelectGroup
,
SelectItem
,
SelectTrigger
,
SelectValue
,
...
...
@@ -89,18 +90,26 @@ export function PresetSelector(props: PresetSelectorProps) {
<
div
className=
'space-y-1.5'
>
<
Label
>
{
t
(
'Preset Template'
)
}
</
Label
>
<
Select
items=
{
[
...
OAUTH_PRESETS
.
map
((
preset
)
=>
({
value
:
preset
.
key
,
label
:
preset
.
name
,
})),
]
}
value=
{
selectedPreset
}
onValueChange=
{
(
v
)
=>
v
!==
null
&&
handlePresetChange
(
v
)
}
>
<
SelectTrigger
className=
'w-full'
>
<
SelectValue
placeholder=
{
t
(
'Select a preset...'
)
}
/>
</
SelectTrigger
>
<
SelectContent
>
<
SelectContent
alignItemWithTrigger=
{
false
}
>
<
SelectGroup
>
{
OAUTH_PRESETS
.
map
((
preset
)
=>
(
<
SelectItem
key=
{
preset
.
key
}
value=
{
preset
.
key
}
>
{
preset
.
name
}
</
SelectItem
>
))
}
</
SelectGroup
>
</
SelectContent
>
</
Select
>
</
div
>
...
...
web/default/src/features/system-settings/auth/custom-oauth/components/provider-form-dialog.tsx
View file @
d98f0e8a
...
...
@@ -24,6 +24,7 @@ import { Input } from '@/components/ui/input'
import
{
Select
,
SelectContent
,
SelectGroup
,
SelectItem
,
SelectTrigger
,
SelectValue
,
...
...
@@ -302,6 +303,12 @@ export function ProviderFormDialog(props: ProviderFormDialogProps) {
<
FormItem
>
<
FormLabel
>
{
t
(
'Auth Style'
)
}
</
FormLabel
>
<
Select
items=
{
[
...
AUTH_STYLE_OPTIONS
.
map
((
option
)
=>
({
value
:
String
(
option
.
value
),
label
:
t
(
option
.
labelKey
),
})),
]
}
value=
{
String
(
field
.
value
)
}
onValueChange=
{
(
val
)
=>
field
.
onChange
(
Number
(
val
))
}
>
...
...
@@ -310,7 +317,8 @@ export function ProviderFormDialog(props: ProviderFormDialogProps) {
<
SelectValue
/>
</
SelectTrigger
>
</
FormControl
>
<
SelectContent
>
<
SelectContent
alignItemWithTrigger=
{
false
}
>
<
SelectGroup
>
{
AUTH_STYLE_OPTIONS
.
map
((
option
)
=>
(
<
SelectItem
key=
{
option
.
value
}
...
...
@@ -319,6 +327,7 @@ export function ProviderFormDialog(props: ProviderFormDialogProps) {
{
t
(
option
.
labelKey
)
}
</
SelectItem
>
))
}
</
SelectGroup
>
</
SelectContent
>
</
Select
>
<
FormDescription
>
...
...
web/default/src/features/system-settings/auth/passkey-section.tsx
View file @
d98f0e8a
...
...
@@ -17,6 +17,7 @@ import { Input } from '@/components/ui/input'
import
{
Select
,
SelectContent
,
SelectGroup
,
SelectItem
,
SelectTrigger
,
SelectValue
,
...
...
@@ -221,18 +222,30 @@ export function PasskeySection({ defaultValues }: PasskeySectionProps) {
<
FormItem
>
<
FormLabel
>
{
t
(
'User Verification'
)
}
</
FormLabel
>
<
FormControl
>
<
Select
value=
{
field
.
value
}
onValueChange=
{
field
.
onChange
}
>
<
Select
items=
{
[
{
value
:
'required'
,
label
:
t
(
'Required'
)
},
{
value
:
'preferred'
,
label
:
t
(
'Recommended'
)
},
{
value
:
'discouraged'
,
label
:
t
(
'Discouraged'
)
},
]
}
value=
{
field
.
value
}
onValueChange=
{
field
.
onChange
}
>
<
SelectTrigger
>
<
SelectValue
placeholder=
{
t
(
'Select requirement'
)
}
/>
</
SelectTrigger
>
<
SelectContent
>
<
SelectItem
value=
'required'
>
{
t
(
'Required'
)
}
</
SelectItem
>
<
SelectContent
alignItemWithTrigger=
{
false
}
>
<
SelectGroup
>
<
SelectItem
value=
'required'
>
{
t
(
'Required'
)
}
</
SelectItem
>
<
SelectItem
value=
'preferred'
>
{
t
(
'Recommended'
)
}
</
SelectItem
>
<
SelectItem
value=
'discouraged'
>
{
t
(
'Discouraged'
)
}
</
SelectItem
>
</
SelectGroup
>
</
SelectContent
>
</
Select
>
</
FormControl
>
...
...
@@ -253,11 +266,20 @@ export function PasskeySection({ defaultValues }: PasskeySectionProps) {
<
FormItem
>
<
FormLabel
>
{
t
(
'Device Type Preference'
)
}
</
FormLabel
>
<
FormControl
>
<
Select
value=
{
field
.
value
}
onValueChange=
{
field
.
onChange
}
>
<
Select
items=
{
[
{
value
:
'none'
,
label
:
t
(
'Unlimited'
)
},
{
value
:
'platform'
,
label
:
t
(
'Built-in Device'
)
},
{
value
:
'cross-platform'
,
label
:
t
(
'External Device'
)
},
]
}
value=
{
field
.
value
}
onValueChange=
{
field
.
onChange
}
>
<
SelectTrigger
>
<
SelectValue
placeholder=
{
t
(
'No preference'
)
}
/>
</
SelectTrigger
>
<
SelectContent
>
<
SelectContent
alignItemWithTrigger=
{
false
}
>
<
SelectGroup
>
<
SelectItem
value=
'none'
>
{
t
(
'Unlimited'
)
}
</
SelectItem
>
<
SelectItem
value=
'platform'
>
{
t
(
'Built-in Device'
)
}
...
...
@@ -265,6 +287,7 @@ export function PasskeySection({ defaultValues }: PasskeySectionProps) {
<
SelectItem
value=
'cross-platform'
>
{
t
(
'External Device'
)
}
</
SelectItem
>
</
SelectGroup
>
</
SelectContent
>
</
Select
>
</
FormControl
>
...
...
web/default/src/features/system-settings/content/announcements-section.tsx
View file @
d98f0e8a
...
...
@@ -39,6 +39,7 @@ import { Input } from '@/components/ui/input'
import
{
Select
,
SelectContent
,
SelectGroup
,
SelectItem
,
SelectTrigger
,
SelectValue
,
...
...
@@ -513,7 +514,23 @@ export function AnnouncementsSection({
render=
{
({
field
})
=>
(
<
FormItem
>
<
FormLabel
>
{
t
(
'Type'
)
}
</
FormLabel
>
<
Select
onValueChange=
{
field
.
onChange
}
value=
{
field
.
value
}
>
<
Select
items=
{
[
...
typeOptions
.
map
((
option
)
=>
({
value
:
option
.
value
,
label
:
(
<
div
className=
'flex items-center gap-2'
>
<
div
className=
{
`h-3 w-3 rounded-full ${option.color}`
}
/>
{
option
.
label
}
</
div
>
),
})),
]
}
onValueChange=
{
field
.
onChange
}
value=
{
field
.
value
}
>
<
FormControl
>
<
SelectTrigger
>
<
SelectValue
...
...
@@ -521,7 +538,8 @@ export function AnnouncementsSection({
/>
</
SelectTrigger
>
</
FormControl
>
<
SelectContent
>
<
SelectContent
alignItemWithTrigger=
{
false
}
>
<
SelectGroup
>
{
typeOptions
.
map
((
option
)
=>
(
<
SelectItem
key=
{
option
.
value
}
value=
{
option
.
value
}
>
<
div
className=
'flex items-center gap-2'
>
...
...
@@ -532,6 +550,7 @@ export function AnnouncementsSection({
</
div
>
</
SelectItem
>
))
}
</
SelectGroup
>
</
SelectContent
>
</
Select
>
<
FormMessage
/>
...
...
web/default/src/features/system-settings/content/api-info-section.tsx
View file @
d98f0e8a
...
...
@@ -38,6 +38,7 @@ import { Input } from '@/components/ui/input'
import
{
Select
,
SelectContent
,
SelectGroup
,
SelectItem
,
SelectTrigger
,
SelectValue
,
...
...
@@ -462,13 +463,30 @@ export function ApiInfoSection({ enabled, data }: ApiInfoSectionProps) {
render=
{
({
field
})
=>
(
<
FormItem
>
<
FormLabel
>
{
t
(
'Badge Color'
)
}
</
FormLabel
>
<
Select
onValueChange=
{
field
.
onChange
}
value=
{
field
.
value
}
>
<
Select
items=
{
[
...
colorOptions
.
map
((
option
)
=>
({
value
:
option
.
value
,
label
:
(
<
div
className=
'flex items-center gap-2'
>
<
div
className=
{
`h-4 w-4 rounded-full ${option.bgClass}`
}
/>
{
option
.
label
}
</
div
>
),
})),
]
}
onValueChange=
{
field
.
onChange
}
value=
{
field
.
value
}
>
<
FormControl
>
<
SelectTrigger
>
<
SelectValue
placeholder=
{
t
(
'Select a color'
)
}
/>
</
SelectTrigger
>
</
FormControl
>
<
SelectContent
>
<
SelectContent
alignItemWithTrigger=
{
false
}
>
<
SelectGroup
>
{
colorOptions
.
map
((
option
)
=>
(
<
SelectItem
key=
{
option
.
value
}
value=
{
option
.
value
}
>
<
div
className=
'flex items-center gap-2'
>
...
...
@@ -479,6 +497,7 @@ export function ApiInfoSection({ enabled, data }: ApiInfoSectionProps) {
</
div
>
</
SelectItem
>
))
}
</
SelectGroup
>
</
SelectContent
>
</
Select
>
<
FormDescription
>
...
...
web/default/src/features/system-settings/content/dashboard-section.tsx
View file @
d98f0e8a
...
...
@@ -17,6 +17,7 @@ import { Input } from '@/components/ui/input'
import
{
Select
,
SelectContent
,
SelectGroup
,
SelectItem
,
SelectTrigger
,
SelectValue
,
...
...
@@ -129,6 +130,12 @@ export function DashboardSection({ defaultValues }: DashboardSectionProps) {
<
FormItem
>
<
FormLabel
>
{
t
(
'Default time granularity'
)
}
</
FormLabel
>
<
Select
items=
{
[
...
granularityOptions
.
map
((
option
)
=>
({
value
:
option
.
value
,
label
:
option
.
label
,
})),
]
}
onValueChange=
{
field
.
onChange
}
value=
{
field
.
value
}
disabled=
{
!
isEnabled
}
...
...
@@ -138,12 +145,14 @@ export function DashboardSection({ defaultValues }: DashboardSectionProps) {
<
SelectValue
placeholder=
{
t
(
'Select granularity'
)
}
/>
</
SelectTrigger
>
</
FormControl
>
<
SelectContent
>
<
SelectContent
alignItemWithTrigger=
{
false
}
>
<
SelectGroup
>
{
granularityOptions
.
map
((
option
)
=>
(
<
SelectItem
key=
{
option
.
value
}
value=
{
option
.
value
}
>
{
option
.
label
}
</
SelectItem
>
))
}
</
SelectGroup
>
</
SelectContent
>
</
Select
>
<
FormDescription
>
...
...
web/default/src/features/system-settings/general/channel-affinity/rule-editor-dialog.tsx
View file @
d98f0e8a
...
...
@@ -21,6 +21,7 @@ import { Label } from '@/components/ui/label'
import
{
Select
,
SelectContent
,
SelectGroup
,
SelectItem
,
SelectTrigger
,
SelectValue
,
...
...
@@ -276,6 +277,9 @@ export function RuleEditorDialog(props: Props) {
{
keySources
.
map
((
src
,
idx
)
=>
(
<
div
key=
{
idx
}
className=
'flex items-center gap-2'
>
<
Select
items=
{
[
...
KEY_SOURCE_TYPES
.
map
((
t
)
=>
({
value
:
t
,
label
:
t
})),
]
}
value=
{
src
.
type
}
onValueChange=
{
(
v
)
=>
{
if
(
v
===
null
)
return
...
...
@@ -290,12 +294,14 @@ export function RuleEditorDialog(props: Props) {
<
SelectTrigger
className=
'w-[160px]'
>
<
SelectValue
/>
</
SelectTrigger
>
<
SelectContent
>
<
SelectContent
alignItemWithTrigger=
{
false
}
>
<
SelectGroup
>
{
KEY_SOURCE_TYPES
.
map
((
t
)
=>
(
<
SelectItem
key=
{
t
}
value=
{
t
}
>
{
t
}
</
SelectItem
>
))
}
</
SelectGroup
>
</
SelectContent
>
</
Select
>
<
Input
...
...
web/default/src/features/system-settings/general/pricing-section.tsx
View file @
d98f0e8a
...
...
@@ -18,6 +18,7 @@ import { Input } from '@/components/ui/input'
import
{
Select
,
SelectContent
,
SelectGroup
,
SelectItem
,
SelectTrigger
,
SelectValue
,
...
...
@@ -162,13 +163,23 @@ export function PricingSection({ defaultValues }: PricingSectionProps) {
render=
{
({
field
})
=>
(
<
FormItem
>
<
FormLabel
>
{
t
(
'Display Mode'
)
}
</
FormLabel
>
<
Select
value=
{
field
.
value
}
onValueChange=
{
field
.
onChange
}
>
<
Select
items=
{
[
{
value
:
'USD'
,
label
:
t
(
'USD'
)
},
{
value
:
'CNY'
,
label
:
t
(
'CNY'
)
},
{
value
:
'CUSTOM'
,
label
:
t
(
'Custom Currency'
)
},
{
value
:
'TOKENS'
,
label
:
t
(
'Tokens Only'
)
},
]
}
value=
{
field
.
value
}
onValueChange=
{
field
.
onChange
}
>
<
FormControl
>
<
SelectTrigger
>
<
SelectValue
placeholder=
{
t
(
'Select display mode'
)
}
/>
</
SelectTrigger
>
</
FormControl
>
<
SelectContent
>
<
SelectContent
alignItemWithTrigger=
{
false
}
>
<
SelectGroup
>
<
SelectItem
value=
'USD'
>
{
t
(
'USD'
)
}
</
SelectItem
>
<
SelectItem
value=
'CNY'
>
{
t
(
'CNY'
)
}
</
SelectItem
>
<
SelectItem
value=
'CUSTOM'
>
...
...
@@ -179,6 +190,7 @@ export function PricingSection({ defaultValues }: PricingSectionProps) {
{
t
(
'Tokens Only'
)
}
</
SelectItem
>
)
}
</
SelectGroup
>
</
SelectContent
>
</
Select
>
<
FormDescription
>
...
...
web/default/src/features/system-settings/general/system-info-section.tsx
View file @
d98f0e8a
...
...
@@ -17,6 +17,7 @@ import { Input } from '@/components/ui/input'
import
{
Select
,
SelectContent
,
SelectGroup
,
SelectItem
,
SelectTrigger
,
SelectValue
,
...
...
@@ -133,19 +134,31 @@ export function SystemInfoSection({ defaultValues }: SystemInfoSectionProps) {
render=
{
({
field
})
=>
(
<
FormItem
>
<
FormLabel
>
{
t
(
'Frontend Theme'
)
}
</
FormLabel
>
<
Select
onValueChange=
{
field
.
onChange
}
value=
{
field
.
value
}
>
<
Select
items=
{
[
{
value
:
'default'
,
label
:
t
(
'Default (New Frontend)'
)
},
{
value
:
'classic'
,
label
:
t
(
'Classic (Legacy Frontend)'
),
},
]
}
onValueChange=
{
field
.
onChange
}
value=
{
field
.
value
}
>
<
FormControl
>
<
SelectTrigger
className=
'w-full'
>
<
SelectValue
/>
</
SelectTrigger
>
</
FormControl
>
<
SelectContent
>
<
SelectContent
alignItemWithTrigger=
{
false
}
>
<
SelectGroup
>
<
SelectItem
value=
'default'
>
{
t
(
'Default (New Frontend)'
)
}
</
SelectItem
>
<
SelectItem
value=
'classic'
>
{
t
(
'Classic (Legacy Frontend)'
)
}
</
SelectItem
>
</
SelectGroup
>
</
SelectContent
>
</
Select
>
<
FormDescription
>
...
...
web/default/src/features/system-settings/integrations/creem-product-dialog.tsx
View file @
d98f0e8a
...
...
@@ -25,6 +25,7 @@ import { Input } from '@/components/ui/input'
import
{
Select
,
SelectContent
,
SelectGroup
,
SelectItem
,
SelectTrigger
,
SelectValue
,
...
...
@@ -160,15 +161,24 @@ export function CreemProductDialog({
render=
{
({
field
})
=>
(
<
FormItem
>
<
FormLabel
>
{
t
(
'Currency'
)
}
</
FormLabel
>
<
Select
onValueChange=
{
field
.
onChange
}
value=
{
field
.
value
}
>
<
Select
items=
{
[
{
value
:
'USD'
,
label
:
'USD ($)'
},
{
value
:
'EUR'
,
label
:
'EUR (€)'
},
]
}
onValueChange=
{
field
.
onChange
}
value=
{
field
.
value
}
>
<
FormControl
>
<
SelectTrigger
>
<
SelectValue
placeholder=
{
t
(
'Select currency'
)
}
/>
</
SelectTrigger
>
</
FormControl
>
<
SelectContent
>
<
SelectContent
alignItemWithTrigger=
{
false
}
>
<
SelectGroup
>
<
SelectItem
value=
'USD'
>
USD ($)
</
SelectItem
>
<
SelectItem
value=
'EUR'
>
EUR (€)
</
SelectItem
>
</
SelectGroup
>
</
SelectContent
>
</
Select
>
<
FormMessage
/>
...
...
web/default/src/features/system-settings/maintenance/performance-section.tsx
View file @
d98f0e8a
...
...
@@ -33,6 +33,7 @@ import { Progress } from '@/components/ui/progress'
import
{
Select
,
SelectContent
,
SelectGroup
,
SelectItem
,
SelectTrigger
,
SelectValue
,
...
...
@@ -508,6 +509,11 @@ export function PerformanceSection(props: Props) {
<
FormItem
>
<
FormLabel
>
{
t
(
'Aggregation bucket'
)
}
</
FormLabel
>
<
Select
items=
{
[
{
value
:
'minute'
,
label
:
t
(
'1 minute'
)
},
{
value
:
'5min'
,
label
:
t
(
'5 minutes'
)
},
{
value
:
'hour'
,
label
:
t
(
'1 hour'
)
},
]
}
value=
{
field
.
value
}
onValueChange=
{
field
.
onChange
}
disabled=
{
!
perfMetricsEnabled
}
...
...
@@ -517,10 +523,12 @@ export function PerformanceSection(props: Props) {
<
SelectValue
/>
</
SelectTrigger
>
</
FormControl
>
<
SelectContent
>
<
SelectContent
alignItemWithTrigger=
{
false
}
>
<
SelectGroup
>
<
SelectItem
value=
'minute'
>
{
t
(
'1 minute'
)
}
</
SelectItem
>
<
SelectItem
value=
'5min'
>
{
t
(
'5 minutes'
)
}
</
SelectItem
>
<
SelectItem
value=
'hour'
>
{
t
(
'1 hour'
)
}
</
SelectItem
>
</
SelectGroup
>
</
SelectContent
>
</
Select
>
</
FormItem
>
...
...
@@ -605,19 +613,25 @@ export function PerformanceSection(props: Props) {
<
div
className=
'grid gap-1.5'
>
<
Label
className=
'text-xs'
>
{
t
(
'Cleanup Mode'
)
}
</
Label
>
<
Select
items=
{
[
{
value
:
'by_count'
,
label
:
t
(
'Retain last N files'
)
},
{
value
:
'by_days'
,
label
:
t
(
'Retain last N days'
)
},
]
}
value=
{
logCleanupMode
}
onValueChange=
{
(
v
)
=>
v
!==
null
&&
setLogCleanupMode
(
v
)
}
>
<
SelectTrigger
className=
'w-[160px]'
>
<
SelectValue
/>
</
SelectTrigger
>
<
SelectContent
>
<
SelectContent
alignItemWithTrigger=
{
false
}
>
<
SelectGroup
>
<
SelectItem
value=
'by_count'
>
{
t
(
'Retain last N files'
)
}
</
SelectItem
>
<
SelectItem
value=
'by_days'
>
{
t
(
'Retain last N days'
)
}
</
SelectItem
>
</
SelectGroup
>
</
SelectContent
>
</
Select
>
</
div
>
...
...
web/default/src/features/system-settings/models/channel-selector-dialog.tsx
View file @
d98f0e8a
...
...
@@ -24,6 +24,7 @@ import { Input } from '@/components/ui/input'
import
{
Select
,
SelectContent
,
SelectGroup
,
SelectItem
,
SelectTrigger
,
SelectValue
,
...
...
@@ -224,18 +225,26 @@ export function ChannelSelectorDialog({
return
(
<
div
className=
'flex items-center gap-2'
>
<
Select
items=
{
[
...
ENDPOINT_OPTIONS
.
map
((
option
)
=>
({
value
:
option
.
value
,
label
:
option
.
label
,
})),
]
}
value=
{
endpointType
}
onValueChange=
{
(
v
)
=>
v
!==
null
&&
handleTypeChange
(
v
)
}
>
<
SelectTrigger
className=
'h-8 w-32'
>
<
SelectValue
/>
</
SelectTrigger
>
<
SelectContent
>
<
SelectContent
alignItemWithTrigger=
{
false
}
>
<
SelectGroup
>
{
ENDPOINT_OPTIONS
.
map
((
option
)
=>
(
<
SelectItem
key=
{
option
.
value
}
value=
{
option
.
value
}
>
{
option
.
label
}
</
SelectItem
>
))
}
</
SelectGroup
>
</
SelectContent
>
</
Select
>
{
endpointType
===
'custom'
&&
(
...
...
web/default/src/features/system-settings/models/group-special-usable-editor.tsx
View file @
d98f0e8a
...
...
@@ -18,6 +18,7 @@ import { Input } from '@/components/ui/input'
import
{
Select
,
SelectContent
,
SelectGroup
,
SelectItem
,
SelectTrigger
,
SelectValue
,
...
...
@@ -176,6 +177,38 @@ function GroupSection(props: GroupSectionProps) {
{
props
.
items
.
map
((
rule
)
=>
(
<
div
key=
{
rule
.
_id
}
className=
'flex items-center gap-2'
>
<
Select
items=
{
[
{
value
:
OP_ADD
,
label
:
(
<
StatusBadge
label=
{
t
(
OP_BADGE_MAP
[
OP_ADD
].
label
)
}
variant=
{
OP_BADGE_MAP
[
OP_ADD
].
variant
}
copyable=
{
false
}
/>
),
},
{
value
:
OP_REMOVE
,
label
:
(
<
StatusBadge
label=
{
t
(
OP_BADGE_MAP
[
OP_REMOVE
].
label
)
}
variant=
{
OP_BADGE_MAP
[
OP_REMOVE
].
variant
}
copyable=
{
false
}
/>
),
},
{
value
:
OP_APPEND
,
label
:
(
<
StatusBadge
label=
{
t
(
OP_BADGE_MAP
[
OP_APPEND
].
label
)
}
variant=
{
OP_BADGE_MAP
[
OP_APPEND
].
variant
}
copyable=
{
false
}
/>
),
},
]
}
value=
{
rule
.
op
}
onValueChange=
{
(
v
)
=>
v
!==
null
&&
props
.
onUpdate
(
rule
.
_id
,
'op'
,
v
)
...
...
@@ -190,7 +223,8 @@ function GroupSection(props: GroupSectionProps) {
/>
</
SelectValue
>
</
SelectTrigger
>
<
SelectContent
>
<
SelectContent
alignItemWithTrigger=
{
false
}
>
<
SelectGroup
>
<
SelectItem
value=
{
OP_ADD
}
>
<
StatusBadge
label=
{
t
(
OP_BADGE_MAP
[
OP_ADD
].
label
)
}
...
...
@@ -212,6 +246,7 @@ function GroupSection(props: GroupSectionProps) {
copyable=
{
false
}
/>
</
SelectItem
>
</
SelectGroup
>
</
SelectContent
>
</
Select
>
<
Input
...
...
web/default/src/features/system-settings/models/tiered-pricing-editor.tsx
View file @
d98f0e8a
...
...
@@ -27,6 +27,7 @@ import { Label } from '@/components/ui/label'
import
{
Select
,
SelectContent
,
SelectGroup
,
SelectItem
,
SelectTrigger
,
SelectValue
,
...
...
@@ -415,6 +416,12 @@ function ConditionRow({ condition, onChange, onRemove }: ConditionRowProps) {
return
(
<
div
className=
'flex items-center gap-2'
>
<
Select
items=
{
[
...
CONDITION_INPUT_OPTIONS
.
map
((
option
)
=>
({
value
:
option
.
value
,
label
:
t
(
option
.
labelKey
),
})),
]
}
value=
{
condition
.
var
}
onValueChange=
{
(
value
)
=>
onChange
({
...
condition
,
var
:
value
as
TierConditionInput
[
'var'
]
})
...
...
@@ -427,15 +434,18 @@ function ConditionRow({ condition, onChange, onRemove }: ConditionRowProps) {
:
condition
.
var
}
</
SelectValue
>
</
SelectTrigger
>
<
SelectContent
>
<
SelectContent
alignItemWithTrigger=
{
false
}
>
<
SelectGroup
>
{
CONDITION_INPUT_OPTIONS
.
map
((
option
)
=>
(
<
SelectItem
key=
{
option
.
value
}
value=
{
option
.
value
}
>
{
t
(
option
.
labelKey
)
}
</
SelectItem
>
))
}
</
SelectGroup
>
</
SelectContent
>
</
Select
>
<
Select
items=
{
[...
OPS
.
map
((
op
)
=>
({
value
:
op
,
label
:
op
}))]
}
value=
{
condition
.
op
}
onValueChange=
{
(
value
)
=>
onChange
({
...
condition
,
op
:
value
as
TierConditionInput
[
'op'
]
})
...
...
@@ -444,12 +454,14 @@ function ConditionRow({ condition, onChange, onRemove }: ConditionRowProps) {
<
SelectTrigger
className=
'w-20'
size=
'sm'
>
<
SelectValue
/>
</
SelectTrigger
>
<
SelectContent
>
<
SelectContent
alignItemWithTrigger=
{
false
}
>
<
SelectGroup
>
{
OPS
.
map
((
op
)
=>
(
<
SelectItem
key=
{
op
}
value=
{
op
}
>
{
op
}
</
SelectItem
>
))
}
</
SelectGroup
>
</
SelectContent
>
</
Select
>
<
DraftNumberInput
...
...
@@ -960,6 +972,12 @@ function RuleConditionRow({
const
renderTimeCondition
=
(
timeCond
:
TimeCondition
)
=>
(
<>
<
Select
items=
{
[
...
TIME_FUNCS
.
map
((
fn
)
=>
({
value
:
fn
,
label
:
getTimeFuncLabel
(
fn
),
})),
]
}
value=
{
timeCond
.
timeFunc
}
onValueChange=
{
(
value
)
=>
onChange
({
...
timeCond
,
timeFunc
:
value
as
TimeFunc
})
...
...
@@ -968,15 +986,23 @@ function RuleConditionRow({
<
SelectTrigger
className=
'w-32'
size=
'sm'
>
<
SelectValue
>
{
getTimeFuncLabel
(
timeCond
.
timeFunc
)
}
</
SelectValue
>
</
SelectTrigger
>
<
SelectContent
>
<
SelectContent
alignItemWithTrigger=
{
false
}
>
<
SelectGroup
>
{
TIME_FUNCS
.
map
((
fn
)
=>
(
<
SelectItem
key=
{
fn
}
value=
{
fn
}
>
{
getTimeFuncLabel
(
fn
)
}
</
SelectItem
>
))
}
</
SelectGroup
>
</
SelectContent
>
</
Select
>
<
Select
items=
{
[
...
COMMON_TIMEZONES
.
map
((
tz
)
=>
({
value
:
tz
.
value
,
label
:
tz
.
label
,
})),
]
}
value=
{
timeCond
.
timezone
}
onValueChange=
{
(
value
)
=>
value
!==
null
&&
onChange
({
...
timeCond
,
timezone
:
value
})
...
...
@@ -988,27 +1014,37 @@ function RuleConditionRow({
?.
label
??
timeCond
.
timezone
}
</
SelectValue
>
</
SelectTrigger
>
<
SelectContent
>
<
SelectContent
alignItemWithTrigger=
{
false
}
>
<
SelectGroup
>
{
COMMON_TIMEZONES
.
map
((
tz
)
=>
(
<
SelectItem
key=
{
tz
.
value
}
value=
{
tz
.
value
}
>
{
tz
.
label
}
</
SelectItem
>
))
}
</
SelectGroup
>
</
SelectContent
>
</
Select
>
<
Select
items=
{
[
...
matchOptions
.
map
((
option
)
=>
({
value
:
option
.
value
,
label
:
getMatchLabel
(
option
.
value
),
})),
]
}
value=
{
timeCond
.
mode
}
onValueChange=
{
(
v
)
=>
v
!==
null
&&
handleModeChange
(
v
)
}
>
<
SelectTrigger
className=
'w-32'
size=
'sm'
>
<
SelectValue
>
{
getMatchLabel
(
timeCond
.
mode
)
}
</
SelectValue
>
</
SelectTrigger
>
<
SelectContent
>
<
SelectContent
alignItemWithTrigger=
{
false
}
>
<
SelectGroup
>
{
matchOptions
.
map
((
option
)
=>
(
<
SelectItem
key=
{
option
.
value
}
value=
{
option
.
value
}
>
{
getMatchLabel
(
option
.
value
)
}
</
SelectItem
>
))
}
</
SelectGroup
>
</
SelectContent
>
</
Select
>
{
timeCond
.
mode
===
MATCH_RANGE
?
(
...
...
@@ -1055,18 +1091,26 @@ function RuleConditionRow({
className=
'w-44'
/>
<
Select
items=
{
[
...
matchOptions
.
map
((
option
)
=>
({
value
:
option
.
value
,
label
:
getMatchLabel
(
option
.
value
),
})),
]
}
value=
{
phCond
.
mode
}
onValueChange=
{
(
v
)
=>
v
!==
null
&&
handleModeChange
(
v
)
}
>
<
SelectTrigger
className=
'w-32'
size=
'sm'
>
<
SelectValue
>
{
getMatchLabel
(
phCond
.
mode
)
}
</
SelectValue
>
</
SelectTrigger
>
<
SelectContent
>
<
SelectContent
alignItemWithTrigger=
{
false
}
>
<
SelectGroup
>
{
matchOptions
.
map
((
option
)
=>
(
<
SelectItem
key=
{
option
.
value
}
value=
{
option
.
value
}
>
{
getMatchLabel
(
option
.
value
)
}
</
SelectItem
>
))
}
</
SelectGroup
>
</
SelectContent
>
</
Select
>
{
phCond
.
mode
!==
MATCH_EXISTS
&&
(
...
...
@@ -1085,16 +1129,23 @@ function RuleConditionRow({
return
(
<
div
className=
'flex flex-wrap items-center gap-2'
>
<
Select
items=
{
[
{
value
:
SOURCE_PARAM
,
label
:
t
(
'Body param'
)
},
{
value
:
SOURCE_HEADER
,
label
:
t
(
'Header'
)
},
{
value
:
SOURCE_TIME
,
label
:
t
(
'Time'
)
},
]
}
value=
{
condition
.
source
}
onValueChange=
{
(
v
)
=>
v
!==
null
&&
handleSourceChange
(
v
)
}
>
<
SelectTrigger
className=
'w-28'
size=
'sm'
>
<
SelectValue
>
{
sourceLabel
}
</
SelectValue
>
</
SelectTrigger
>
<
SelectContent
>
<
SelectContent
alignItemWithTrigger=
{
false
}
>
<
SelectGroup
>
<
SelectItem
value=
{
SOURCE_PARAM
}
>
{
t
(
'Body param'
)
}
</
SelectItem
>
<
SelectItem
value=
{
SOURCE_HEADER
}
>
{
t
(
'Header'
)
}
</
SelectItem
>
<
SelectItem
value=
{
SOURCE_TIME
}
>
{
t
(
'Time'
)
}
</
SelectItem
>
</
SelectGroup
>
</
SelectContent
>
</
Select
>
{
condition
.
source
===
SOURCE_TIME
...
...
@@ -1705,15 +1756,21 @@ export const TieredPricingEditor = memo(function TieredPricingEditor({
<
div
className=
'flex items-center justify-between gap-2'
>
<
Label
className=
'text-xs'
>
{
t
(
'Editor mode'
)
}
</
Label
>
<
Select
items=
{
[
{
value
:
'visual'
,
label
:
t
(
'Visual editor'
)
},
{
value
:
'raw'
,
label
:
t
(
'Expression editor'
)
},
]
}
value=
{
editorMode
}
onValueChange=
{
(
value
)
=>
handleModeChange
(
value
as
EditorMode
)
}
>
<
SelectTrigger
className=
'w-44'
size=
'sm'
>
<
SelectValue
/>
</
SelectTrigger
>
<
SelectContent
>
<
SelectContent
alignItemWithTrigger=
{
false
}
>
<
SelectGroup
>
<
SelectItem
value=
'visual'
>
{
t
(
'Visual editor'
)
}
</
SelectItem
>
<
SelectItem
value=
'raw'
>
{
t
(
'Expression editor'
)
}
</
SelectItem
>
</
SelectGroup
>
</
SelectContent
>
</
Select
>
</
div
>
...
...
web/default/src/features/system-settings/models/upstream-ratio-sync-table.tsx
View file @
d98f0e8a
...
...
@@ -11,6 +11,7 @@ import { Input } from '@/components/ui/input'
import
{
Select
,
SelectContent
,
SelectGroup
,
SelectItem
,
SelectTrigger
,
SelectValue
,
...
...
@@ -212,6 +213,13 @@ export function UpstreamRatioSyncTable({
/>
</
div
>
<
Select
items=
{
[
{
value
:
'__all__'
,
label
:
t
(
'All Types'
)
},
...
RATIO_TYPE_OPTIONS
.
map
((
option
)
=>
({
value
:
option
.
value
,
label
:
t
(
option
.
label
),
})),
]
}
value=
{
ratioTypeFilter
}
onValueChange=
{
(
v
)
=>
v
!==
null
&&
setRatioTypeFilter
(
v
)
}
disabled=
{
isDisabled
}
...
...
@@ -219,13 +227,15 @@ export function UpstreamRatioSyncTable({
<
SelectTrigger
className=
'w-full sm:w-56'
>
<
SelectValue
placeholder=
{
t
(
'Filter by price field'
)
}
/>
</
SelectTrigger
>
<
SelectContent
>
<
SelectContent
alignItemWithTrigger=
{
false
}
>
<
SelectGroup
>
<
SelectItem
value=
'__all__'
>
{
t
(
'All Types'
)
}
</
SelectItem
>
{
RATIO_TYPE_OPTIONS
.
map
((
option
)
=>
(
<
SelectItem
key=
{
option
.
value
}
value=
{
option
.
value
}
>
{
t
(
option
.
label
)
}
</
SelectItem
>
))
}
</
SelectGroup
>
</
SelectContent
>
</
Select
>
</
div
>
...
...
web/default/src/features/system-settings/request-limits/ssrf-section.tsx
View file @
d98f0e8a
...
...
@@ -18,6 +18,7 @@ import { Input } from '@/components/ui/input'
import
{
Select
,
SelectContent
,
SelectGroup
,
SelectItem
,
SelectTrigger
,
SelectValue
,
...
...
@@ -242,6 +243,16 @@ export function SSRFSection({ defaultValues }: SSRFSectionProps) {
<
FormItem
>
<
FormLabel
>
{
t
(
'Domain Filter Mode'
)
}
</
FormLabel
>
<
Select
items=
{
[
{
value
:
'false'
,
label
:
t
(
'Blacklist (Block listed domains)'
),
},
{
value
:
'true'
,
label
:
t
(
'Whitelist (Only allow listed domains)'
),
},
]
}
onValueChange=
{
(
value
)
=>
field
.
onChange
(
value
===
'true'
)
}
value=
{
field
.
value
?
'true'
:
'false'
}
>
...
...
@@ -250,13 +261,15 @@ export function SSRFSection({ defaultValues }: SSRFSectionProps) {
<
SelectValue
/>
</
SelectTrigger
>
</
FormControl
>
<
SelectContent
>
<
SelectContent
alignItemWithTrigger=
{
false
}
>
<
SelectGroup
>
<
SelectItem
value=
'false'
>
{
t
(
'Blacklist (Block listed domains)'
)
}
</
SelectItem
>
<
SelectItem
value=
'true'
>
{
t
(
'Whitelist (Only allow listed domains)'
)
}
</
SelectItem
>
</
SelectGroup
>
</
SelectContent
>
</
Select
>
<
FormDescription
>
...
...
@@ -295,6 +308,16 @@ export function SSRFSection({ defaultValues }: SSRFSectionProps) {
<
FormItem
>
<
FormLabel
>
{
t
(
'IP Filter Mode'
)
}
</
FormLabel
>
<
Select
items=
{
[
{
value
:
'false'
,
label
:
t
(
'Blacklist (Block listed IPs)'
),
},
{
value
:
'true'
,
label
:
t
(
'Whitelist (Only allow listed IPs)'
),
},
]
}
onValueChange=
{
(
value
)
=>
field
.
onChange
(
value
===
'true'
)
}
value=
{
field
.
value
?
'true'
:
'false'
}
>
...
...
@@ -303,13 +326,15 @@ export function SSRFSection({ defaultValues }: SSRFSectionProps) {
<
SelectValue
/>
</
SelectTrigger
>
</
FormControl
>
<
SelectContent
>
<
SelectContent
alignItemWithTrigger=
{
false
}
>
<
SelectGroup
>
<
SelectItem
value=
'false'
>
{
t
(
'Blacklist (Block listed IPs)'
)
}
</
SelectItem
>
<
SelectItem
value=
'true'
>
{
t
(
'Whitelist (Only allow listed IPs)'
)
}
</
SelectItem
>
</
SelectGroup
>
</
SelectContent
>
</
Select
>
<
FormDescription
>
...
...
web/default/src/features/usage-logs/components/common-logs-filter-bar.tsx
View file @
d98f0e8a
...
...
@@ -8,17 +8,18 @@ import { useIsAdmin } from '@/hooks/use-admin'
import
{
Button
}
from
'@/components/ui/button'
import
{
Input
}
from
'@/components/ui/input'
import
{
Tooltip
,
TooltipContent
,
TooltipTrigger
,
}
from
'@/components/ui/tooltip'
import
{
Select
,
SelectContent
,
SelectGroup
,
SelectItem
,
SelectTrigger
,
SelectValue
,
}
from
'@/components/ui/select'
import
{
Tooltip
,
TooltipContent
,
TooltipTrigger
,
}
from
'@/components/ui/tooltip'
import
{
DataTableToolbar
}
from
'@/components/data-table'
import
{
LOG_TYPES
}
from
'../constants'
import
{
buildSearchParams
}
from
'../lib/filter'
...
...
@@ -207,6 +208,13 @@ export function CommonLogsFilterBar<TData>(
className=
{
inputClass
}
/>
<
Select
items=
{
[
{
value
:
'all'
,
label
:
t
(
'All Types'
)
},
...
LOG_TYPES
.
map
((
type
)
=>
({
value
:
String
(
type
.
value
),
label
:
t
(
type
.
label
),
})),
]
}
value=
{
logType
}
onValueChange=
{
(
value
)
=>
{
setLogType
(
value
!==
null
&&
isLogTypeValue
(
value
)
?
value
:
''
)
...
...
@@ -215,13 +223,15 @@ export function CommonLogsFilterBar<TData>(
<
SelectTrigger
className=
{
inputClass
}
>
<
SelectValue
placeholder=
{
t
(
'All Types'
)
}
/>
</
SelectTrigger
>
<
SelectContent
>
<
SelectContent
alignItemWithTrigger=
{
false
}
>
<
SelectGroup
>
<
SelectItem
value=
'all'
>
{
t
(
'All Types'
)
}
</
SelectItem
>
{
LOG_TYPES
.
map
((
type
)
=>
(
<
SelectItem
key=
{
type
.
value
}
value=
{
String
(
type
.
value
)
}
>
{
t
(
type
.
label
)
}
</
SelectItem
>
))
}
</
SelectGroup
>
</
SelectContent
>
</
Select
>
</>
...
...
web/default/src/features/users/components/users-mutate-drawer.tsx
View file @
d98f0e8a
...
...
@@ -22,6 +22,7 @@ import { Label } from '@/components/ui/label'
import
{
Select
,
SelectContent
,
SelectGroup
,
SelectItem
,
SelectTrigger
,
SelectValue
,
...
...
@@ -201,6 +202,10 @@ export function UsersMutateDrawer({
<
FormItem
>
<
FormLabel
>
{
t
(
'Role'
)
}
</
FormLabel
>
<
Select
items=
{
[
{
value
:
'1'
,
label
:
t
(
'Common User'
)
},
{
value
:
'10'
,
label
:
t
(
'Admin'
)
},
]
}
onValueChange=
{
(
value
)
=>
value
!==
null
&&
field
.
onChange
(
parseInt
(
value
))
}
...
...
@@ -211,11 +216,13 @@ export function UsersMutateDrawer({
<
SelectValue
placeholder=
{
t
(
'Select a role'
)
}
/>
</
SelectTrigger
>
</
FormControl
>
<
SelectContent
>
<
SelectContent
alignItemWithTrigger=
{
false
}
>
<
SelectGroup
>
<
SelectItem
value=
'1'
>
{
t
(
'Common User'
)
}
</
SelectItem
>
<
SelectItem
value=
'10'
>
{
t
(
'Admin'
)
}
</
SelectItem
>
</
SelectGroup
>
</
SelectContent
>
</
Select
>
<
FormDescription
>
...
...
@@ -282,6 +289,12 @@ export function UsersMutateDrawer({
<
FormItem
>
<
FormLabel
>
{
t
(
'Group'
)
}
</
FormLabel
>
<
Select
items=
{
[
...
groups
.
map
((
group
)
=>
({
value
:
group
,
label
:
group
,
})),
]
}
onValueChange=
{
field
.
onChange
}
value=
{
field
.
value
}
>
...
...
@@ -290,12 +303,14 @@ export function UsersMutateDrawer({
<
SelectValue
placeholder=
{
t
(
'Select a group'
)
}
/>
</
SelectTrigger
>
</
FormControl
>
<
SelectContent
>
<
SelectContent
alignItemWithTrigger=
{
false
}
>
<
SelectGroup
>
{
groups
.
map
((
group
)
=>
(
<
SelectItem
key=
{
group
}
value=
{
group
}
>
{
group
}
</
SelectItem
>
))
}
</
SelectGroup
>
</
SelectContent
>
</
Select
>
<
FormMessage
/>
...
...
web/default/src/features/wallet/components/dialogs/billing-history-dialog.tsx
View file @
d98f0e8a
...
...
@@ -28,6 +28,7 @@ import { ScrollArea } from '@/components/ui/scroll-area'
import
{
Select
,
SelectContent
,
SelectGroup
,
SelectItem
,
SelectTrigger
,
SelectValue
,
...
...
@@ -104,6 +105,12 @@ export function BillingHistoryDialog({
/>
</
div
>
<
Select
items=
{
[
{
value
:
'10'
,
label
:
t
(
'10 / page'
)
},
{
value
:
'20'
,
label
:
t
(
'20 / page'
)
},
{
value
:
'50'
,
label
:
t
(
'50 / page'
)
},
{
value
:
'100'
,
label
:
t
(
'100 / page'
)
},
]
}
value=
{
pageSize
.
toString
()
}
onValueChange=
{
(
value
)
=>
value
!==
null
&&
handlePageSizeChange
(
parseInt
(
value
))
...
...
@@ -112,11 +119,13 @@ export function BillingHistoryDialog({
<
SelectTrigger
className=
'h-9 w-[92px] sm:w-32'
>
<
SelectValue
/>
</
SelectTrigger
>
<
SelectContent
>
<
SelectContent
alignItemWithTrigger=
{
false
}
>
<
SelectGroup
>
<
SelectItem
value=
'10'
>
{
t
(
'10 / page'
)
}
</
SelectItem
>
<
SelectItem
value=
'20'
>
{
t
(
'20 / page'
)
}
</
SelectItem
>
<
SelectItem
value=
'50'
>
{
t
(
'50 / page'
)
}
</
SelectItem
>
<
SelectItem
value=
'100'
>
{
t
(
'100 / page'
)
}
</
SelectItem
>
</
SelectGroup
>
</
SelectContent
>
</
Select
>
</
div
>
...
...
web/default/src/features/wallet/components/subscription-plans-card.tsx
View file @
d98f0e8a
...
...
@@ -10,6 +10,7 @@ import { Progress } from '@/components/ui/progress'
import
{
Select
,
SelectContent
,
SelectGroup
,
SelectItem
,
SelectTrigger
,
SelectValue
,
...
...
@@ -276,6 +277,34 @@ export function SubscriptionPlansCard({
</
div
>
<
div
className=
'flex w-full items-center gap-2 sm:w-auto'
>
<
Select
items=
{
[
{
value
:
'subscription_first'
,
label
:
(
<>
{
getBillingPreferenceLabel
(
'subscription_first'
,
t
)
}
{
disablePref
?
` (${t('No Active')})`
:
''
}
</>
),
},
{
value
:
'wallet_first'
,
label
:
getBillingPreferenceLabel
(
'wallet_first'
,
t
),
},
{
value
:
'subscription_only'
,
label
:
(
<>
{
getBillingPreferenceLabel
(
'subscription_only'
,
t
)
}
{
disablePref
?
` (${t('No Active')})`
:
''
}
</>
),
},
{
value
:
'wallet_only'
,
label
:
getBillingPreferenceLabel
(
'wallet_only'
,
t
),
},
]
}
value=
{
displayPref
}
onValueChange=
{
(
v
)
=>
v
!==
null
&&
handlePreferenceChange
(
v
)
}
>
...
...
@@ -284,21 +313,29 @@ export function SubscriptionPlansCard({
{
getBillingPreferenceLabel
(
displayPref
,
t
)
}
</
SelectValue
>
</
SelectTrigger
>
<
SelectContent
>
<
SelectItem
value=
'subscription_first'
disabled=
{
disablePref
}
>
<
SelectContent
alignItemWithTrigger=
{
false
}
>
<
SelectGroup
>
<
SelectItem
value=
'subscription_first'
disabled=
{
disablePref
}
>
{
getBillingPreferenceLabel
(
'subscription_first'
,
t
)
}
{
disablePref
?
` (${t('No Active')})`
:
''
}
</
SelectItem
>
<
SelectItem
value=
'wallet_first'
>
{
getBillingPreferenceLabel
(
'wallet_first'
,
t
)
}
</
SelectItem
>
<
SelectItem
value=
'subscription_only'
disabled=
{
disablePref
}
>
<
SelectItem
value=
'subscription_only'
disabled=
{
disablePref
}
>
{
getBillingPreferenceLabel
(
'subscription_only'
,
t
)
}
{
disablePref
?
` (${t('No Active')})`
:
''
}
</
SelectItem
>
<
SelectItem
value=
'wallet_only'
>
{
getBillingPreferenceLabel
(
'wallet_only'
,
t
)
}
</
SelectItem
>
</
SelectGroup
>
</
SelectContent
>
</
Select
>
<
Button
...
...
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