Skip to content

Commit d67f703

Browse files
refactor: clean up unused UUID version handling
1 parent 718b456 commit d67f703

File tree

2 files changed

+58
-126
lines changed

2 files changed

+58
-126
lines changed

dashboard/src/components/dialogs/node-modal.tsx

Lines changed: 52 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,25 @@
1+
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@/components/ui/accordion'
2+
import { Button } from '@/components/ui/button'
13
import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog'
24
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from '@/components/ui/form'
35
import { Input } from '@/components/ui/input'
4-
import { Button } from '@/components/ui/button'
5-
import { Switch } from '@/components/ui/switch'
6-
import { useTranslation } from 'react-i18next'
7-
import { UseFormReturn } from 'react-hook-form'
8-
import { useCreateNode, useModifyNode, NodeConnectionType, useGetAllCores, CoreResponse, getNode, DataLimitResetStrategy, useGetNode, NodeResponse } from '@/service/api'
9-
import { toast } from 'sonner'
10-
import { z } from 'zod'
11-
import { cn } from '@/lib/utils'
126
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'
7+
import { Switch } from '@/components/ui/switch'
138
import { Textarea } from '@/components/ui/textarea'
14-
import { queryClient } from '@/utils/query-client'
159
import useDirDetection from '@/hooks/use-dir-detection'
16-
import React, { useState, useEffect, useRef } from 'react'
17-
import { Loader2, Settings, RefreshCw } from 'lucide-react'
18-
import { v4 as uuidv4, v5 as uuidv5, v6 as uuidv6, v7 as uuidv7 } from 'uuid'
19-
import { LoaderButton } from '../ui/loader-button'
2010
import useDynamicErrorHandler from '@/hooks/use-dynamic-errors.ts'
21-
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@/components/ui/accordion'
11+
import { cn } from '@/lib/utils'
12+
import { CoreResponse, DataLimitResetStrategy, getNode, NodeConnectionType, NodeResponse, useCreateNode, useGetAllCores, useGetNode, useModifyNode } from '@/service/api'
2213
import { formatBytes, gbToBytes } from '@/utils/formatByte'
14+
import { queryClient } from '@/utils/query-client'
15+
import { Loader2, RefreshCw, Settings } from 'lucide-react'
16+
import React, { useEffect, useRef, useState } from 'react'
17+
import { UseFormReturn } from 'react-hook-form'
18+
import { useTranslation } from 'react-i18next'
19+
import { toast } from 'sonner'
20+
import { v4 as uuidv4 } from 'uuid'
21+
import { z } from 'zod'
22+
import { LoaderButton } from '../ui/loader-button'
2323

2424
export const nodeFormSchema = z.object({
2525
name: z.string().min(1, 'Name is required'),
@@ -83,7 +83,7 @@ export default function NodeModal({ isDialogOpen, onOpenChange, form, editingNod
8383

8484
const currentNode = node || initialNodeData
8585
const lastSyncedNodeRef = useRef<NodeResponse | null>(null)
86-
86+
8787
useEffect(() => {
8888
if (isDialogOpen) {
8989
setErrorDetails(null)
@@ -97,32 +97,32 @@ export default function NodeModal({ isDialogOpen, onOpenChange, form, editingNod
9797
// Update form when node data changes (from auto-refresh or external updates)
9898
useEffect(() => {
9999
if (!isDialogOpen || !editingNode || !editingNodeId || !node) return
100-
100+
101101
// Skip if form is dirty (user has made changes)
102102
if (form.formState.isDirty) return
103-
103+
104104
// Skip if this is the same node data we already synced
105105
// Compare key fields that change externally (status, message, versions, usage)
106106
const lastSynced = lastSyncedNodeRef.current
107-
if (lastSynced &&
108-
lastSynced.id === node.id &&
109-
lastSynced.status === node.status &&
110-
lastSynced.message === node.message &&
111-
lastSynced.xray_version === node.xray_version &&
112-
lastSynced.node_version === node.node_version &&
113-
lastSynced.uplink === node.uplink &&
114-
lastSynced.downlink === node.downlink &&
115-
lastSynced.name === node.name &&
116-
lastSynced.address === node.address &&
117-
lastSynced.port === node.port) {
107+
if (
108+
lastSynced &&
109+
lastSynced.id === node.id &&
110+
lastSynced.status === node.status &&
111+
lastSynced.message === node.message &&
112+
lastSynced.xray_version === node.xray_version &&
113+
lastSynced.node_version === node.node_version &&
114+
lastSynced.uplink === node.uplink &&
115+
lastSynced.downlink === node.downlink &&
116+
lastSynced.name === node.name &&
117+
lastSynced.address === node.address &&
118+
lastSynced.port === node.port
119+
) {
118120
return
119121
}
120122

121123
// Update form with new node data
122124
const dataLimitBytes = node.data_limit ?? null
123-
const dataLimitGB = dataLimitBytes !== null && dataLimitBytes !== undefined && dataLimitBytes > 0
124-
? dataLimitBytes / (1024 * 1024 * 1024)
125-
: 0
125+
const dataLimitGB = dataLimitBytes !== null && dataLimitBytes !== undefined && dataLimitBytes > 0 ? dataLimitBytes / (1024 * 1024 * 1024) : 0
126126

127127
if (dataLimitGB > 0) {
128128
const formatted = parseFloat(dataLimitGB.toFixed(9))
@@ -131,22 +131,25 @@ export default function NodeModal({ isDialogOpen, onOpenChange, form, editingNod
131131
dataLimitInputRef.current = ''
132132
}
133133

134-
form.reset({
135-
name: node.name,
136-
address: node.address,
137-
port: node.port,
138-
usage_coefficient: node.usage_coefficient,
139-
connection_type: node.connection_type,
140-
server_ca: node.server_ca,
141-
keep_alive: node.keep_alive,
142-
api_key: (node.api_key as string) || '',
143-
core_config_id: node.core_config_id ?? cores?.cores?.[0]?.id,
144-
data_limit: dataLimitGB,
145-
data_limit_reset_strategy: node.data_limit_reset_strategy ?? DataLimitResetStrategy.no_reset,
146-
reset_time: node.reset_time ?? null,
147-
default_timeout: node.default_timeout ?? 10,
148-
internal_timeout: node.internal_timeout ?? 15,
149-
}, { keepDirty: false, keepValues: false })
134+
form.reset(
135+
{
136+
name: node.name,
137+
address: node.address,
138+
port: node.port,
139+
usage_coefficient: node.usage_coefficient,
140+
connection_type: node.connection_type,
141+
server_ca: node.server_ca,
142+
keep_alive: node.keep_alive,
143+
api_key: (node.api_key as string) || '',
144+
core_config_id: node.core_config_id ?? cores?.cores?.[0]?.id,
145+
data_limit: dataLimitGB,
146+
data_limit_reset_strategy: node.data_limit_reset_strategy ?? DataLimitResetStrategy.no_reset,
147+
reset_time: node.reset_time ?? null,
148+
default_timeout: node.default_timeout ?? 10,
149+
internal_timeout: node.internal_timeout ?? 15,
150+
},
151+
{ keepDirty: false, keepValues: false },
152+
)
150153

151154
lastSyncedNodeRef.current = node
152155
}, [node, isDialogOpen, editingNode, editingNodeId, form, cores])
@@ -534,26 +537,9 @@ export default function NodeModal({ isDialogOpen, onOpenChange, form, editingNod
534537
control={form.control}
535538
name="api_key"
536539
render={({ field }) => {
537-
const [uuidVersion, setUuidVersion] = useState<'v4' | 'v5' | 'v6' | 'v7'>('v4')
538-
539540
const generateUUID = () => {
540-
switch (uuidVersion) {
541-
case 'v4':
542-
field.onChange(uuidv4())
543-
break
544-
case 'v5':
545-
const namespace = '6ba7b810-9dad-11d1-80b4-00c04fd430c8'
546-
field.onChange(uuidv5(field.value || 'default', namespace))
547-
break
548-
case 'v6':
549-
field.onChange(uuidv6())
550-
break
551-
case 'v7':
552-
field.onChange(uuidv7())
553-
break
554-
}
541+
field.onChange(uuidv4())
555542
}
556-
557543
return (
558544
<FormItem className={'min-h-[100px]'}>
559545
<FormLabel>{t('nodeModal.apiKey')}</FormLabel>
@@ -568,17 +554,6 @@ export default function NodeModal({ isDialogOpen, onOpenChange, form, editingNod
568554
onChange={e => field.onChange(e.target.value)}
569555
/>
570556
<div className={cn('flex items-center gap-0', dir === 'rtl' && 'flex-row-reverse')}>
571-
<Select value={uuidVersion} onValueChange={(value: 'v4' | 'v5' | 'v6' | 'v7') => setUuidVersion(value)}>
572-
<SelectTrigger className="h-10 w-[60px] rounded-r-none border-r-0">
573-
<SelectValue />
574-
</SelectTrigger>
575-
<SelectContent>
576-
<SelectItem value="v4">v4</SelectItem>
577-
<SelectItem value="v5">v5</SelectItem>
578-
<SelectItem value="v6">v6</SelectItem>
579-
<SelectItem value="v7">v7</SelectItem>
580-
</SelectContent>
581-
</Select>
582557
<Button type="button" variant="outline" onClick={generateUUID} className="h-10 rounded-l-none px-3">
583558
<RefreshCw className="h-3 w-3" />
584559
</Button>
@@ -590,8 +565,7 @@ export default function NodeModal({ isDialogOpen, onOpenChange, form, editingNod
590565
)
591566
}}
592567
/>
593-
594-
<Accordion type="single" collapsible className="mb-4 !mt-0 w-full pb-4">
568+
<Accordion type="single" collapsible className="!mt-0 mb-4 w-full pb-4">
595569
<AccordionItem className="rounded-sm border px-4 [&_[data-state=closed]]:no-underline [&_[data-state=open]]:no-underline" value="advanced-settings">
596570
<AccordionTrigger>
597571
<div className="flex items-center gap-2">

dashboard/src/components/dialogs/user-modal.tsx

Lines changed: 6 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
1+
import { DatePicker } from '@/components/common/date-picker'
12
import GroupsSelector from '@/components/common/groups-selector'
23
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@/components/ui/accordion'
34
import { Button } from '@/components/ui/button'
45
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from '@/components/ui/dialog'
56
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from '@/components/ui/form'
67
import { Input } from '@/components/ui/input'
78
import { LoaderButton } from '@/components/ui/loader-button'
8-
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'
99
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'
10+
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'
1011
import { Switch } from '@/components/ui/switch'
1112
import { Textarea } from '@/components/ui/textarea'
1213
import useDirDetection from '@/hooks/use-dir-detection'
1314
import useDynamicErrorHandler from '@/hooks/use-dynamic-errors.ts'
1415
import { cn } from '@/lib/utils'
15-
import { DatePicker } from '@/components/common/date-picker'
1616
import { UseEditFormValues, UseFormValues, userCreateSchema, userEditSchema } from '@/pages/_dashboard.users'
1717
import {
1818
getGeneralSettings,
@@ -34,7 +34,7 @@ import React, { useEffect, useState } from 'react'
3434
import { UseFormReturn } from 'react-hook-form'
3535
import { useTranslation } from 'react-i18next'
3636
import { toast } from 'sonner'
37-
import { v4 as uuidv4, v5 as uuidv5, v7 as uuidv7 } from 'uuid'
37+
import { v4 as uuidv4 } from 'uuid'
3838
import { z } from 'zod'
3939

4040
interface UserModalProps {
@@ -1158,28 +1158,6 @@ export default function UserModal({ isDialogOpen, onOpenChange, form, editingUse
11581158
}
11591159
}, [isDialogOpen, form, editingUser, status])
11601160

1161-
// State for UUID version per field
1162-
const [uuidVersions, setUuidVersions] = useState({
1163-
vmess: 'v4',
1164-
vless: 'v4',
1165-
trojan: 'v4',
1166-
shadowsocks: 'v4',
1167-
})
1168-
1169-
// Helper to generate UUID by version
1170-
function generateUUID(version: string, value: string = ''): string {
1171-
switch (version) {
1172-
case 'v4':
1173-
return uuidv4()
1174-
case 'v5':
1175-
return uuidv5(value || 'default', UUID_NAMESPACE)
1176-
case 'v7':
1177-
return uuidv7()
1178-
default:
1179-
return uuidv4()
1180-
}
1181-
}
1182-
11831161
useEffect(() => {
11841162
if (isDialogOpen && editingUser && dataLimitValue !== null && dataLimitValue !== undefined) {
11851163
if (dataLimitValue > 0) {
@@ -1217,7 +1195,7 @@ export default function UserModal({ isDialogOpen, onOpenChange, form, editingUse
12171195

12181196
return (
12191197
<Dialog open={isDialogOpen} onOpenChange={handleModalOpenChange}>
1220-
<DialogContent className={`lg:min-w-[900px] h-auto`}>
1198+
<DialogContent className={`h-auto lg:min-w-[900px]`}>
12211199
<DialogHeader>
12221200
<DialogTitle className={`${dir === 'rtl' ? 'text-right' : 'text-left'}`}>
12231201
{editingUser ? t('userDialog.editUser', { defaultValue: 'Edit User' }) : t('createUser', { defaultValue: 'Create User' })}
@@ -1636,24 +1614,14 @@ export default function UserModal({ isDialogOpen, onOpenChange, form, editingUse
16361614
handleFieldChange('proxy_settings.vmess.id', e.target.value)
16371615
}}
16381616
/>
1639-
<Select value={uuidVersions.vmess} onValueChange={val => setUuidVersions(v => ({ ...v, vmess: val }))}>
1640-
<SelectTrigger className="w-[60px]">
1641-
<SelectValue />
1642-
</SelectTrigger>
1643-
<SelectContent>
1644-
<SelectItem value="v4">v4</SelectItem>
1645-
<SelectItem value="v5">v5</SelectItem>
1646-
<SelectItem value="v7">v7</SelectItem>
1647-
</SelectContent>
1648-
</Select>
16491617
<Button
16501618
size="icon"
16511619
type="button"
16521620
variant="ghost"
16531621
onClick={e => {
16541622
e.preventDefault()
16551623
e.stopPropagation()
1656-
const newVal = generateUUID(uuidVersions.vmess, field.value)
1624+
const newVal = uuidv4()
16571625
field.onChange(newVal)
16581626
form.trigger('proxy_settings.vmess.id')
16591627
handleFieldChange('proxy_settings.vmess.id', newVal)
@@ -1691,24 +1659,14 @@ export default function UserModal({ isDialogOpen, onOpenChange, form, editingUse
16911659
handleFieldChange('proxy_settings.vless.id', e.target.value)
16921660
}}
16931661
/>
1694-
<Select value={uuidVersions.vless} onValueChange={val => setUuidVersions(v => ({ ...v, vless: val }))}>
1695-
<SelectTrigger className="w-[60px]">
1696-
<SelectValue />
1697-
</SelectTrigger>
1698-
<SelectContent>
1699-
<SelectItem value="v4">v4</SelectItem>
1700-
<SelectItem value="v5">v5</SelectItem>
1701-
<SelectItem value="v7">v7</SelectItem>
1702-
</SelectContent>
1703-
</Select>
17041662
<Button
17051663
size="icon"
17061664
type="button"
17071665
variant="ghost"
17081666
onClick={e => {
17091667
e.preventDefault()
17101668
e.stopPropagation()
1711-
const newVal = generateUUID(uuidVersions.vless, field.value)
1669+
const newVal = uuidv4()
17121670
field.onChange(newVal)
17131671
form.trigger('proxy_settings.vless.id')
17141672
handleFieldChange('proxy_settings.vless.id', newVal)

0 commit comments

Comments
 (0)