Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
25c95356a1 |
@@ -0,0 +1,13 @@
|
|||||||
|
/** ISO country codes from fleet locations seed → RU labels for selects. */
|
||||||
|
const COUNTRY_LABELS: Record<string, string> = {
|
||||||
|
RU: 'Россия',
|
||||||
|
DE: 'Германия',
|
||||||
|
NL: 'Нидерланды',
|
||||||
|
FI: 'Финляндия',
|
||||||
|
FR: 'Франция',
|
||||||
|
}
|
||||||
|
|
||||||
|
export function countrySelectLabel(code: string): string {
|
||||||
|
const name = COUNTRY_LABELS[code]
|
||||||
|
return name ? `${code} — ${name}` : code
|
||||||
|
}
|
||||||
@@ -25,6 +25,7 @@ import { Button } from '@cdnmanager/ui/components/button'
|
|||||||
import { Input } from '@cdnmanager/ui/components/input'
|
import { Input } from '@cdnmanager/ui/components/input'
|
||||||
import { Label } from '@cdnmanager/ui/components/label'
|
import { Label } from '@cdnmanager/ui/components/label'
|
||||||
import { SelectField } from '@/components/select-field'
|
import { SelectField } from '@/components/select-field'
|
||||||
|
import { countrySelectLabel } from '@/lib/country-labels'
|
||||||
import { queryClient } from '@/lib/query-client'
|
import { queryClient } from '@/lib/query-client'
|
||||||
import {
|
import {
|
||||||
createNode,
|
createNode,
|
||||||
@@ -80,6 +81,7 @@ function NodesPage() {
|
|||||||
const [editing, setEditing] = useState<Node | null>(null)
|
const [editing, setEditing] = useState<Node | null>(null)
|
||||||
const [deleteId, setDeleteId] = useState<string | null>(null)
|
const [deleteId, setDeleteId] = useState<string | null>(null)
|
||||||
const [preview, setPreview] = useState('')
|
const [preview, setPreview] = useState('')
|
||||||
|
const [countryCode, setCountryCode] = useState('')
|
||||||
|
|
||||||
const form = useForm<FormValues>({
|
const form = useForm<FormValues>({
|
||||||
resolver: zodResolver(formSchema),
|
resolver: zodResolver(formSchema),
|
||||||
@@ -102,6 +104,30 @@ function NodesPage() {
|
|||||||
const watchIndex = form.watch('indexNum')
|
const watchIndex = form.watch('indexNum')
|
||||||
const watchProvider = form.watch('providerTag')
|
const watchProvider = form.watch('providerTag')
|
||||||
|
|
||||||
|
const countryOptions = useMemo(() => {
|
||||||
|
const codes = new Set<string>()
|
||||||
|
for (const loc of locations) {
|
||||||
|
if (loc.country) codes.add(loc.country)
|
||||||
|
}
|
||||||
|
return [...codes]
|
||||||
|
.sort((a, b) => a.localeCompare(b))
|
||||||
|
.map((code) => ({ value: code, label: countrySelectLabel(code) }))
|
||||||
|
}, [locations])
|
||||||
|
|
||||||
|
const locationOptions = useMemo(() => {
|
||||||
|
if (!countryCode) return []
|
||||||
|
return locations
|
||||||
|
.filter((l) => l.country === countryCode)
|
||||||
|
.map((l) => ({
|
||||||
|
value: l.id,
|
||||||
|
label: `${l.code} — ${l.name}`,
|
||||||
|
}))
|
||||||
|
}, [locations, countryCode])
|
||||||
|
|
||||||
|
function countryForLocationId(locationId: string): string {
|
||||||
|
return locations.find((l) => l.id === locationId)?.country ?? ''
|
||||||
|
}
|
||||||
|
|
||||||
async function refreshPreview() {
|
async function refreshPreview() {
|
||||||
if (!watchZone || !watchLoc || !watchRole) return
|
if (!watchZone || !watchLoc || !watchRole) return
|
||||||
try {
|
try {
|
||||||
@@ -148,6 +174,7 @@ function NodesPage() {
|
|||||||
toast.success(editing ? 'Нода обновлена' : 'Нода создана')
|
toast.success(editing ? 'Нода обновлена' : 'Нода создана')
|
||||||
setSheetOpen(false)
|
setSheetOpen(false)
|
||||||
setEditing(null)
|
setEditing(null)
|
||||||
|
setCountryCode('')
|
||||||
form.reset()
|
form.reset()
|
||||||
void qc.invalidateQueries({ queryKey: ['fleet'] })
|
void qc.invalidateQueries({ queryKey: ['fleet'] })
|
||||||
},
|
},
|
||||||
@@ -267,6 +294,7 @@ function NodesPage() {
|
|||||||
onClick={() => {
|
onClick={() => {
|
||||||
const n = row.original
|
const n = row.original
|
||||||
setEditing(n)
|
setEditing(n)
|
||||||
|
setCountryCode(countryForLocationId(n.locationId))
|
||||||
form.reset({
|
form.reset({
|
||||||
zoneId: n.zoneId,
|
zoneId: n.zoneId,
|
||||||
locationId: n.locationId,
|
locationId: n.locationId,
|
||||||
@@ -306,9 +334,11 @@ function NodesPage() {
|
|||||||
size="sm"
|
size="sm"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setEditing(null)
|
setEditing(null)
|
||||||
|
const firstLoc = locations[0]
|
||||||
|
setCountryCode(firstLoc?.country ?? '')
|
||||||
form.reset({
|
form.reset({
|
||||||
zoneId: zones[0]?.id ?? '',
|
zoneId: zones[0]?.id ?? '',
|
||||||
locationId: locations[0]?.id ?? '',
|
locationId: firstLoc?.id ?? '',
|
||||||
role: 'gw',
|
role: 'gw',
|
||||||
indexNum: 1,
|
indexNum: 1,
|
||||||
ipv4: '',
|
ipv4: '',
|
||||||
@@ -396,20 +426,41 @@ function NodesPage() {
|
|||||||
</div>
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
<div className="flex flex-col gap-2">
|
<div className="grid grid-cols-2 gap-3">
|
||||||
<Label>Локация</Label>
|
<div className="flex flex-col gap-2">
|
||||||
<SelectField
|
<Label>Страна</Label>
|
||||||
value={form.watch('locationId')}
|
<SelectField
|
||||||
onValueChange={(v) => {
|
value={countryCode || null}
|
||||||
form.setValue('locationId', v ?? '')
|
onValueChange={(v) => {
|
||||||
void refreshPreview()
|
const next = v ?? ''
|
||||||
}}
|
setCountryCode(next)
|
||||||
placeholder="Локация"
|
const currentLoc = locations.find((l) => l.id === form.getValues('locationId'))
|
||||||
options={locations.map((l) => ({
|
if (!next || !currentLoc || currentLoc.country !== next) {
|
||||||
value: l.id,
|
form.setValue('locationId', '')
|
||||||
label: `${l.code} — ${l.name}`,
|
setPreview('')
|
||||||
}))}
|
}
|
||||||
/>
|
void refreshPreview()
|
||||||
|
}}
|
||||||
|
placeholder="Страна"
|
||||||
|
options={countryOptions}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-col gap-2">
|
||||||
|
<Label>Локация</Label>
|
||||||
|
<SelectField
|
||||||
|
value={form.watch('locationId') || null}
|
||||||
|
disabled={!countryCode}
|
||||||
|
onValueChange={(v) => {
|
||||||
|
const id = v ?? ''
|
||||||
|
form.setValue('locationId', id)
|
||||||
|
const loc = locations.find((l) => l.id === id)
|
||||||
|
if (loc?.country) setCountryCode(loc.country)
|
||||||
|
void refreshPreview()
|
||||||
|
}}
|
||||||
|
placeholder={countryCode ? 'Локация' : 'Сначала страна'}
|
||||||
|
options={locationOptions}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="grid grid-cols-2 gap-3">
|
<div className="grid grid-cols-2 gap-3">
|
||||||
|
|||||||
Reference in New Issue
Block a user