fix: migrate select to Base UI items API (#4655)
This commit is contained in:
+15
-6
@@ -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>
|
||||
{OAUTH_PRESETS.map((preset) => (
|
||||
<SelectItem key={preset.key} value={preset.key}>
|
||||
{preset.name}
|
||||
</SelectItem>
|
||||
))}
|
||||
<SelectContent alignItemWithTrigger={false}>
|
||||
<SelectGroup>
|
||||
{OAUTH_PRESETS.map((preset) => (
|
||||
<SelectItem key={preset.key} value={preset.key}>
|
||||
{preset.name}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectGroup>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
|
||||
Vendored
+18
-9
@@ -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,15 +317,17 @@ export function ProviderFormDialog(props: ProviderFormDialogProps) {
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
</FormControl>
|
||||
<SelectContent>
|
||||
{AUTH_STYLE_OPTIONS.map((option) => (
|
||||
<SelectItem
|
||||
key={option.value}
|
||||
value={String(option.value)}
|
||||
>
|
||||
{t(option.labelKey)}
|
||||
</SelectItem>
|
||||
))}
|
||||
<SelectContent alignItemWithTrigger={false}>
|
||||
<SelectGroup>
|
||||
{AUTH_STYLE_OPTIONS.map((option) => (
|
||||
<SelectItem
|
||||
key={option.value}
|
||||
value={String(option.value)}
|
||||
>
|
||||
{t(option.labelKey)}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectGroup>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<FormDescription>
|
||||
|
||||
@@ -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>
|
||||
<SelectItem value='preferred'>
|
||||
{t('Recommended')}
|
||||
</SelectItem>
|
||||
<SelectItem value='discouraged'>
|
||||
{t('Discouraged')}
|
||||
</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,18 +266,28 @@ 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>
|
||||
<SelectItem value='none'>{t('Unlimited')}</SelectItem>
|
||||
<SelectItem value='platform'>
|
||||
{t('Built-in Device')}
|
||||
</SelectItem>
|
||||
<SelectItem value='cross-platform'>
|
||||
{t('External Device')}
|
||||
</SelectItem>
|
||||
<SelectContent alignItemWithTrigger={false}>
|
||||
<SelectGroup>
|
||||
<SelectItem value='none'>{t('Unlimited')}</SelectItem>
|
||||
<SelectItem value='platform'>
|
||||
{t('Built-in Device')}
|
||||
</SelectItem>
|
||||
<SelectItem value='cross-platform'>
|
||||
{t('External Device')}
|
||||
</SelectItem>
|
||||
</SelectGroup>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</FormControl>
|
||||
|
||||
+31
-12
@@ -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,17 +538,19 @@ export function AnnouncementsSection({
|
||||
/>
|
||||
</SelectTrigger>
|
||||
</FormControl>
|
||||
<SelectContent>
|
||||
{typeOptions.map((option) => (
|
||||
<SelectItem key={option.value} value={option.value}>
|
||||
<div className='flex items-center gap-2'>
|
||||
<div
|
||||
className={`h-3 w-3 rounded-full ${option.color}`}
|
||||
/>
|
||||
{option.label}
|
||||
</div>
|
||||
</SelectItem>
|
||||
))}
|
||||
<SelectContent alignItemWithTrigger={false}>
|
||||
<SelectGroup>
|
||||
{typeOptions.map((option) => (
|
||||
<SelectItem key={option.value} value={option.value}>
|
||||
<div className='flex items-center gap-2'>
|
||||
<div
|
||||
className={`h-3 w-3 rounded-full ${option.color}`}
|
||||
/>
|
||||
{option.label}
|
||||
</div>
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectGroup>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<FormMessage />
|
||||
|
||||
@@ -38,6 +38,7 @@ import { Input } from '@/components/ui/input'
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
SelectGroup,
|
||||
SelectItem,
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
@@ -462,23 +463,41 @@ export function ApiInfoSection({ enabled, data }: ApiInfoSectionProps) {
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>{t('Badge Color')}</FormLabel>
|
||||
<Select onValueChange={field.onChange} value={field.value}>
|
||||
<FormControl>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder={t('Select a color')} />
|
||||
</SelectTrigger>
|
||||
</FormControl>
|
||||
<SelectContent>
|
||||
{colorOptions.map((option) => (
|
||||
<SelectItem key={option.value} value={option.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>
|
||||
</SelectItem>
|
||||
))}
|
||||
),
|
||||
})),
|
||||
]}
|
||||
onValueChange={field.onChange}
|
||||
value={field.value}
|
||||
>
|
||||
<FormControl>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder={t('Select a color')} />
|
||||
</SelectTrigger>
|
||||
</FormControl>
|
||||
<SelectContent alignItemWithTrigger={false}>
|
||||
<SelectGroup>
|
||||
{colorOptions.map((option) => (
|
||||
<SelectItem key={option.value} value={option.value}>
|
||||
<div className='flex items-center gap-2'>
|
||||
<div
|
||||
className={`h-4 w-4 rounded-full ${option.bgClass}`}
|
||||
/>
|
||||
{option.label}
|
||||
</div>
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectGroup>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<FormDescription>
|
||||
|
||||
@@ -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>
|
||||
{granularityOptions.map((option) => (
|
||||
<SelectItem key={option.value} value={option.value}>
|
||||
{option.label}
|
||||
</SelectItem>
|
||||
))}
|
||||
<SelectContent alignItemWithTrigger={false}>
|
||||
<SelectGroup>
|
||||
{granularityOptions.map((option) => (
|
||||
<SelectItem key={option.value} value={option.value}>
|
||||
{option.label}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectGroup>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<FormDescription>
|
||||
|
||||
+12
-6
@@ -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>
|
||||
{KEY_SOURCE_TYPES.map((t) => (
|
||||
<SelectItem key={t} value={t}>
|
||||
{t}
|
||||
</SelectItem>
|
||||
))}
|
||||
<SelectContent alignItemWithTrigger={false}>
|
||||
<SelectGroup>
|
||||
{KEY_SOURCE_TYPES.map((t) => (
|
||||
<SelectItem key={t} value={t}>
|
||||
{t}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectGroup>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<Input
|
||||
|
||||
@@ -18,6 +18,7 @@ import { Input } from '@/components/ui/input'
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
SelectGroup,
|
||||
SelectItem,
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
@@ -162,23 +163,34 @@ 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>
|
||||
<SelectItem value='USD'>{t('USD')}</SelectItem>
|
||||
<SelectItem value='CNY'>{t('CNY')}</SelectItem>
|
||||
<SelectItem value='CUSTOM'>
|
||||
{t('Custom Currency')}
|
||||
</SelectItem>
|
||||
{showTokensOnlyOption && (
|
||||
<SelectItem value='TOKENS'>
|
||||
{t('Tokens Only')}
|
||||
<SelectContent alignItemWithTrigger={false}>
|
||||
<SelectGroup>
|
||||
<SelectItem value='USD'>{t('USD')}</SelectItem>
|
||||
<SelectItem value='CNY'>{t('CNY')}</SelectItem>
|
||||
<SelectItem value='CUSTOM'>
|
||||
{t('Custom Currency')}
|
||||
</SelectItem>
|
||||
)}
|
||||
{showTokensOnlyOption && (
|
||||
<SelectItem value='TOKENS'>
|
||||
{t('Tokens Only')}
|
||||
</SelectItem>
|
||||
)}
|
||||
</SelectGroup>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<FormDescription>
|
||||
|
||||
@@ -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>
|
||||
<SelectItem value='default'>
|
||||
{t('Default (New Frontend)')}
|
||||
</SelectItem>
|
||||
<SelectItem value='classic'>
|
||||
{t('Classic (Legacy Frontend)')}
|
||||
</SelectItem>
|
||||
<SelectContent alignItemWithTrigger={false}>
|
||||
<SelectGroup>
|
||||
<SelectItem value='default'>
|
||||
{t('Default (New Frontend)')}
|
||||
</SelectItem>
|
||||
<SelectItem value='classic'>
|
||||
{t('Classic (Legacy Frontend)')}
|
||||
</SelectItem>
|
||||
</SelectGroup>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<FormDescription>
|
||||
|
||||
+14
-4
@@ -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>
|
||||
<SelectItem value='USD'>USD ($)</SelectItem>
|
||||
<SelectItem value='EUR'>EUR (€)</SelectItem>
|
||||
<SelectContent alignItemWithTrigger={false}>
|
||||
<SelectGroup>
|
||||
<SelectItem value='USD'>USD ($)</SelectItem>
|
||||
<SelectItem value='EUR'>EUR (€)</SelectItem>
|
||||
</SelectGroup>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<FormMessage />
|
||||
|
||||
+25
-11
@@ -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>
|
||||
<SelectItem value='minute'>{t('1 minute')}</SelectItem>
|
||||
<SelectItem value='5min'>{t('5 minutes')}</SelectItem>
|
||||
<SelectItem value='hour'>{t('1 hour')}</SelectItem>
|
||||
<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>
|
||||
<SelectItem value='by_count'>
|
||||
{t('Retain last N files')}
|
||||
</SelectItem>
|
||||
<SelectItem value='by_days'>
|
||||
{t('Retain last N days')}
|
||||
</SelectItem>
|
||||
<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>
|
||||
|
||||
+15
-6
@@ -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>
|
||||
{ENDPOINT_OPTIONS.map((option) => (
|
||||
<SelectItem key={option.value} value={option.value}>
|
||||
{option.label}
|
||||
</SelectItem>
|
||||
))}
|
||||
<SelectContent alignItemWithTrigger={false}>
|
||||
<SelectGroup>
|
||||
{ENDPOINT_OPTIONS.map((option) => (
|
||||
<SelectItem key={option.value} value={option.value}>
|
||||
{option.label}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectGroup>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
{endpointType === 'custom' && (
|
||||
|
||||
+57
-22
@@ -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,28 +223,30 @@ function GroupSection(props: GroupSectionProps) {
|
||||
/>
|
||||
</SelectValue>
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value={OP_ADD}>
|
||||
<StatusBadge
|
||||
label={t(OP_BADGE_MAP[OP_ADD].label)}
|
||||
variant={OP_BADGE_MAP[OP_ADD].variant}
|
||||
copyable={false}
|
||||
/>
|
||||
</SelectItem>
|
||||
<SelectItem value={OP_REMOVE}>
|
||||
<StatusBadge
|
||||
label={t(OP_BADGE_MAP[OP_REMOVE].label)}
|
||||
variant={OP_BADGE_MAP[OP_REMOVE].variant}
|
||||
copyable={false}
|
||||
/>
|
||||
</SelectItem>
|
||||
<SelectItem value={OP_APPEND}>
|
||||
<StatusBadge
|
||||
label={t(OP_BADGE_MAP[OP_APPEND].label)}
|
||||
variant={OP_BADGE_MAP[OP_APPEND].variant}
|
||||
copyable={false}
|
||||
/>
|
||||
</SelectItem>
|
||||
<SelectContent alignItemWithTrigger={false}>
|
||||
<SelectGroup>
|
||||
<SelectItem value={OP_ADD}>
|
||||
<StatusBadge
|
||||
label={t(OP_BADGE_MAP[OP_ADD].label)}
|
||||
variant={OP_BADGE_MAP[OP_ADD].variant}
|
||||
copyable={false}
|
||||
/>
|
||||
</SelectItem>
|
||||
<SelectItem value={OP_REMOVE}>
|
||||
<StatusBadge
|
||||
label={t(OP_BADGE_MAP[OP_REMOVE].label)}
|
||||
variant={OP_BADGE_MAP[OP_REMOVE].variant}
|
||||
copyable={false}
|
||||
/>
|
||||
</SelectItem>
|
||||
<SelectItem value={OP_APPEND}>
|
||||
<StatusBadge
|
||||
label={t(OP_BADGE_MAP[OP_APPEND].label)}
|
||||
variant={OP_BADGE_MAP[OP_APPEND].variant}
|
||||
copyable={false}
|
||||
/>
|
||||
</SelectItem>
|
||||
</SelectGroup>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<Input
|
||||
|
||||
+100
-43
@@ -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>
|
||||
{CONDITION_INPUT_OPTIONS.map((option) => (
|
||||
<SelectItem key={option.value} value={option.value}>
|
||||
{t(option.labelKey)}
|
||||
</SelectItem>
|
||||
))}
|
||||
<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>
|
||||
{OPS.map((op) => (
|
||||
<SelectItem key={op} value={op}>
|
||||
{op}
|
||||
</SelectItem>
|
||||
))}
|
||||
<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>
|
||||
{TIME_FUNCS.map((fn) => (
|
||||
<SelectItem key={fn} value={fn}>
|
||||
{getTimeFuncLabel(fn)}
|
||||
</SelectItem>
|
||||
))}
|
||||
<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>
|
||||
{COMMON_TIMEZONES.map((tz) => (
|
||||
<SelectItem key={tz.value} value={tz.value}>
|
||||
{tz.label}
|
||||
</SelectItem>
|
||||
))}
|
||||
<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>
|
||||
{matchOptions.map((option) => (
|
||||
<SelectItem key={option.value} value={option.value}>
|
||||
{getMatchLabel(option.value)}
|
||||
</SelectItem>
|
||||
))}
|
||||
<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>
|
||||
{matchOptions.map((option) => (
|
||||
<SelectItem key={option.value} value={option.value}>
|
||||
{getMatchLabel(option.value)}
|
||||
</SelectItem>
|
||||
))}
|
||||
<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>
|
||||
<SelectItem value={SOURCE_PARAM}>{t('Body param')}</SelectItem>
|
||||
<SelectItem value={SOURCE_HEADER}>{t('Header')}</SelectItem>
|
||||
<SelectItem value={SOURCE_TIME}>{t('Time')}</SelectItem>
|
||||
<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>
|
||||
<SelectItem value='visual'>{t('Visual editor')}</SelectItem>
|
||||
<SelectItem value='raw'>{t('Expression editor')}</SelectItem>
|
||||
<SelectContent alignItemWithTrigger={false}>
|
||||
<SelectGroup>
|
||||
<SelectItem value='visual'>{t('Visual editor')}</SelectItem>
|
||||
<SelectItem value='raw'>{t('Expression editor')}</SelectItem>
|
||||
</SelectGroup>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
|
||||
+17
-7
@@ -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>
|
||||
<SelectItem value='__all__'>{t('All Types')}</SelectItem>
|
||||
{RATIO_TYPE_OPTIONS.map((option) => (
|
||||
<SelectItem key={option.value} value={option.value}>
|
||||
{t(option.label)}
|
||||
</SelectItem>
|
||||
))}
|
||||
<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>
|
||||
|
||||
@@ -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>
|
||||
<SelectItem value='false'>
|
||||
{t('Blacklist (Block listed domains)')}
|
||||
</SelectItem>
|
||||
<SelectItem value='true'>
|
||||
{t('Whitelist (Only allow listed domains)')}
|
||||
</SelectItem>
|
||||
<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>
|
||||
<SelectItem value='false'>
|
||||
{t('Blacklist (Block listed IPs)')}
|
||||
</SelectItem>
|
||||
<SelectItem value='true'>
|
||||
{t('Whitelist (Only allow listed IPs)')}
|
||||
</SelectItem>
|
||||
<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>
|
||||
|
||||
Reference in New Issue
Block a user