Update pnpm-lock.yaml to include new dependencies for @dnd-kit packages; enhance frontend documentation with MCP patterns and shadcn guidelines; refactor route handling for groups and services; implement new DataTableCard and KanbanBoard components for better domain and service management; add service binding functionality and improve DNS record management with new schemas and queries.
Build, Test, and Push CFDM Docker Image / test (push) Failing after 16h45m4s
Build, Test, and Push CFDM Docker Image / create-release (push) Has been cancelled
Build, Test, and Push CFDM Docker Image / build-and-push (push) Has been cancelled
Build, Test, and Push CFDM Docker Image / update-wiki (push) Has been cancelled
Build, Test, and Push CFDM Docker Image / test (push) Failing after 16h45m4s
Build, Test, and Push CFDM Docker Image / create-release (push) Has been cancelled
Build, Test, and Push CFDM Docker Image / build-and-push (push) Has been cancelled
Build, Test, and Push CFDM Docker Image / update-wiki (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
import type { DnsRecord } from '@/lib/schemas'
|
||||
|
||||
export interface DnsRecordGroup {
|
||||
key: string
|
||||
recordType: string
|
||||
name: string
|
||||
records: DnsRecord[]
|
||||
isMultiValue: boolean
|
||||
}
|
||||
|
||||
const MULTI_VALUE_TYPES = new Set(['A', 'AAAA'])
|
||||
|
||||
function groupKey(record: DnsRecord): string {
|
||||
return `${record.record_type}:${record.name}`
|
||||
}
|
||||
|
||||
export function groupDnsRecords(records: DnsRecord[]): DnsRecordGroup[] {
|
||||
const map = new Map<string, DnsRecord[]>()
|
||||
|
||||
for (const record of records) {
|
||||
const key = groupKey(record)
|
||||
const list = map.get(key) ?? []
|
||||
list.push(record)
|
||||
map.set(key, list)
|
||||
}
|
||||
|
||||
return [...map.entries()].map(([key, groupRecords]) => {
|
||||
const [recordType, ...nameParts] = key.split(':')
|
||||
const name = nameParts.join(':')
|
||||
const isMultiValue =
|
||||
MULTI_VALUE_TYPES.has(recordType) && groupRecords.length > 1
|
||||
|
||||
return {
|
||||
key,
|
||||
recordType,
|
||||
name,
|
||||
records: groupRecords,
|
||||
isMultiValue,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export function allSameValue<T>(values: T[]): boolean {
|
||||
if (values.length <= 1) return true
|
||||
return values.every((v) => v === values[0])
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
import type { ServiceBinding } from '@/lib/schemas'
|
||||
|
||||
export function getDomainIps(bindings: ServiceBinding[], domainId: number): string[] {
|
||||
const ips = bindings
|
||||
.filter((b) => b.domain_id === domainId && b.target_ip)
|
||||
.map((b) => b.target_ip as string)
|
||||
return [...new Set(ips)]
|
||||
}
|
||||
|
||||
export function groupBindingsByHostname(
|
||||
bindings: ServiceBinding[],
|
||||
): Map<string, ServiceBinding[]> {
|
||||
const map = new Map<string, ServiceBinding[]>()
|
||||
for (const binding of bindings) {
|
||||
const list = map.get(binding.hostname) ?? []
|
||||
list.push(binding)
|
||||
map.set(binding.hostname, list)
|
||||
}
|
||||
return map
|
||||
}
|
||||
|
||||
export function buildIpsByDomainId(bindings: ServiceBinding[]): Map<number, string[]> {
|
||||
const map = new Map<number, string[]>()
|
||||
for (const binding of bindings) {
|
||||
if (!binding.target_ip) continue
|
||||
const existing = map.get(binding.domain_id) ?? []
|
||||
if (!existing.includes(binding.target_ip)) {
|
||||
map.set(binding.domain_id, [...existing, binding.target_ip])
|
||||
}
|
||||
}
|
||||
return map
|
||||
}
|
||||
@@ -8,6 +8,10 @@ export const groupSchema = z.object({
|
||||
updated_at: z.string(),
|
||||
})
|
||||
|
||||
export const groupWithStatsSchema = groupSchema.extend({
|
||||
domain_count: z.number(),
|
||||
})
|
||||
|
||||
export const serviceSchema = z.object({
|
||||
id: z.number(),
|
||||
name: z.string(),
|
||||
@@ -27,6 +31,28 @@ export const domainSchema = z.object({
|
||||
updated_at: z.string(),
|
||||
})
|
||||
|
||||
export const domainListItemSchema = domainSchema.extend({
|
||||
group_name: z.string().nullable(),
|
||||
service_count: z.number(),
|
||||
})
|
||||
|
||||
export const serviceBindingSchema = z.object({
|
||||
id: z.number(),
|
||||
domain_id: z.number(),
|
||||
service_id: z.number(),
|
||||
hostname: z.string(),
|
||||
dns_record_id: z.number().nullable(),
|
||||
zone_name: z.string(),
|
||||
group_id: z.number().nullable(),
|
||||
group_name: z.string().nullable(),
|
||||
service_name: z.string(),
|
||||
service_slug: z.string(),
|
||||
target_ip: z.string().nullable(),
|
||||
sync_status: z.string().nullable(),
|
||||
created_at: z.string(),
|
||||
updated_at: z.string(),
|
||||
})
|
||||
|
||||
export const dnsRecordSchema = z.object({
|
||||
id: z.number(),
|
||||
domain_id: z.number(),
|
||||
@@ -58,8 +84,11 @@ export const certificateSchema = z.object({
|
||||
})
|
||||
|
||||
export type Group = z.infer<typeof groupSchema>
|
||||
export type GroupWithStats = z.infer<typeof groupWithStatsSchema>
|
||||
export type Service = z.infer<typeof serviceSchema>
|
||||
export type Domain = z.infer<typeof domainSchema>
|
||||
export type DomainListItem = z.infer<typeof domainListItemSchema>
|
||||
export type ServiceBinding = z.infer<typeof serviceBindingSchema>
|
||||
export type DnsRecord = z.infer<typeof dnsRecordSchema>
|
||||
export type Certificate = z.infer<typeof certificateSchema>
|
||||
|
||||
@@ -73,6 +102,18 @@ export const createServiceSchema = z.object({
|
||||
slug: z.string().min(1, 'Укажите slug'),
|
||||
})
|
||||
|
||||
export const createServiceBindingSchema = z.object({
|
||||
domain_id: z.string().min(1, 'Выберите домен'),
|
||||
service_id: z.string().min(1, 'Выберите сервис'),
|
||||
hostname: z.string().optional(),
|
||||
target_ip: z.string().optional(),
|
||||
})
|
||||
|
||||
export const updateDomainGroupSchema = z.object({
|
||||
group_id: z.number().nullable(),
|
||||
status: z.string().optional(),
|
||||
})
|
||||
|
||||
export const createDomainSchema = z.object({
|
||||
zone_name: z.string().min(1, 'Укажите имя зоны'),
|
||||
group_id: z.string(),
|
||||
@@ -93,6 +134,7 @@ export const createDnsRecordSchema = z.object({
|
||||
|
||||
export type CreateGroupInput = z.infer<typeof createGroupSchema>
|
||||
export type CreateServiceInput = z.infer<typeof createServiceSchema>
|
||||
export type CreateServiceBindingInput = z.infer<typeof createServiceBindingSchema>
|
||||
export type CreateDomainInput = z.infer<typeof createDomainSchema>
|
||||
export type LoginInput = z.infer<typeof loginSchema>
|
||||
export type CreateDnsRecordInput = z.infer<typeof createDnsRecordSchema>
|
||||
|
||||
Reference in New Issue
Block a user