feat(ui): добавить KPI card-35 на domains, groups и services
ReUI PRO card-35 через KpiStatGrid; клик по KPI синхронизирует tabs. Co-authored-by: Cursor <[email protected]>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { createFileRoute } from '@tanstack/react-router'
|
||||
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
|
||||
import { useMemo, useState } from 'react'
|
||||
import { useCallback, useMemo, useState } from 'react'
|
||||
import { useForm } from 'react-hook-form'
|
||||
import { zodResolver } from '@hookform/resolvers/zod'
|
||||
import { toast } from 'sonner'
|
||||
@@ -15,6 +15,7 @@ import {
|
||||
serviceBindingKeys,
|
||||
} from '@/queries'
|
||||
import { PageShell } from '@/components/page-shell'
|
||||
import { DomainKpiCards } from '@/components/domain-kpi-cards'
|
||||
import { ResourcePage } from '@/components/reui-kit'
|
||||
import {
|
||||
DOMAIN_TABS,
|
||||
@@ -55,7 +56,9 @@ function DomainsPage() {
|
||||
const [importGroupId, setImportGroupId] = useState('')
|
||||
const [deleteTarget, setDeleteTarget] = useState<DomainListItem | null>(null)
|
||||
const [filters, setFilters] = useState<Filter[]>(createDefaultDomainFilters)
|
||||
const [activeTab, setActiveTab] = useState('all')
|
||||
const queryClient = useQueryClient()
|
||||
const handleSelectTab = useCallback((tabId: string) => setActiveTab(tabId), [])
|
||||
|
||||
const {
|
||||
data: domains,
|
||||
@@ -146,10 +149,18 @@ function DomainsPage() {
|
||||
|
||||
return (
|
||||
<PageShell>
|
||||
<DomainKpiCards
|
||||
domains={domains}
|
||||
activeTab={activeTab}
|
||||
isLoading={isLoading && !domains}
|
||||
onSelectTab={handleSelectTab}
|
||||
/>
|
||||
<ResourcePage
|
||||
title="Домены"
|
||||
description="Импортированные зоны Cloudflare"
|
||||
tabs={DOMAIN_TABS.map((tab) => ({ ...tab }))}
|
||||
activeTab={activeTab}
|
||||
onTabChange={setActiveTab}
|
||||
tabFilter={domainTabFilter}
|
||||
filterFields={filterFields}
|
||||
filters={filters}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { createFileRoute, useNavigate } from '@tanstack/react-router'
|
||||
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
|
||||
import { useMemo, useState } from 'react'
|
||||
import { useCallback, useMemo, useState } from 'react'
|
||||
import { FolderTreeIcon } from 'lucide-react'
|
||||
import { toast } from 'sonner'
|
||||
import {
|
||||
@@ -14,6 +14,7 @@ import {
|
||||
import { api } from '@/lib/api-client'
|
||||
import type { CreateGroupInput, Group } from '@/lib/schemas'
|
||||
import { PageShell } from '@/components/page-shell'
|
||||
import { GroupKpiCards } from '@/components/group-kpi-cards'
|
||||
import { EmptyState } from '@/components/empty-state'
|
||||
import { ConfirmDialog } from '@/components/confirm-dialog'
|
||||
import { DomainGroupEditSheet } from '@/components/domain-group-edit-sheet'
|
||||
@@ -66,7 +67,9 @@ function GroupsPage() {
|
||||
const [editingGroup, setEditingGroup] = useState<Group | null>(null)
|
||||
const [deletingGroup, setDeletingGroup] = useState<Group | null>(null)
|
||||
const [filters, setFilters] = useState<Filter[]>(() => createDefaultGroupFilters())
|
||||
const [activeTab, setActiveTab] = useState('all')
|
||||
const queryClient = useQueryClient()
|
||||
const handleSelectTab = useCallback((tabId: string) => setActiveTab(tabId), [])
|
||||
|
||||
const {
|
||||
data: groups,
|
||||
@@ -276,10 +279,19 @@ function GroupsPage() {
|
||||
/>
|
||||
)
|
||||
) : (
|
||||
<>
|
||||
<GroupKpiCards
|
||||
rows={catalogRows}
|
||||
activeTab={activeTab}
|
||||
isLoading={false}
|
||||
onSelectTab={handleSelectTab}
|
||||
/>
|
||||
<ResourcePage
|
||||
title="Группы"
|
||||
description="Каталог групп доменов"
|
||||
tabs={GROUP_TABS.map((tab) => ({ ...tab }))}
|
||||
activeTab={activeTab}
|
||||
onTabChange={setActiveTab}
|
||||
tabFilter={groupTabFilter}
|
||||
filterFields={filterFields}
|
||||
filters={filters}
|
||||
@@ -301,6 +313,7 @@ function GroupsPage() {
|
||||
action: createButton,
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
|
||||
<DomainGroupEditSheet
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { createFileRoute, useNavigate } from '@tanstack/react-router'
|
||||
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
|
||||
import { useMemo, useState } from 'react'
|
||||
import { useCallback, useMemo, useState } from 'react'
|
||||
import { ServerIcon } from 'lucide-react'
|
||||
import { toast } from 'sonner'
|
||||
import {
|
||||
@@ -21,6 +21,7 @@ import type {
|
||||
UpdateServiceConfigInput,
|
||||
} from '@/lib/schemas'
|
||||
import { PageShell } from '@/components/page-shell'
|
||||
import { ServiceKpiCards } from '@/components/service-kpi-cards'
|
||||
import { EmptyState } from '@/components/empty-state'
|
||||
import { ConfirmDialog } from '@/components/confirm-dialog'
|
||||
import { ServiceEditSheet } from '@/components/service-edit-sheet'
|
||||
@@ -146,7 +147,9 @@ function ServicesPage() {
|
||||
const [deletingGroupId, setDeletingGroupId] = useState<number | null>(null)
|
||||
const [togglingServiceId, setTogglingServiceId] = useState<number | null>(null)
|
||||
const [bulkToggling, setBulkToggling] = useState(false)
|
||||
const [activeTab, setActiveTab] = useState('all')
|
||||
const queryClient = useQueryClient()
|
||||
const handleSelectTab = useCallback((tabId: string) => setActiveTab(tabId), [])
|
||||
const selection = useServicesSelection()
|
||||
const {
|
||||
data,
|
||||
@@ -621,11 +624,20 @@ function ServicesPage() {
|
||||
)}
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<ServiceKpiCards
|
||||
rows={catalogRows}
|
||||
activeTab={activeTab}
|
||||
isLoading={false}
|
||||
onSelectTab={handleSelectTab}
|
||||
/>
|
||||
<ServicesGroupedCatalog
|
||||
data={data ?? { groups: [], ungrouped: [] }}
|
||||
domainId={domainId}
|
||||
domainLabel={filteredDomain?.zone_name}
|
||||
togglingId={togglingServiceId}
|
||||
activeTab={activeTab}
|
||||
onTabChange={setActiveTab}
|
||||
onEditService={setEditingService}
|
||||
onDeleteService={setDeletingService}
|
||||
onToggleService={handleServiceToggle}
|
||||
@@ -644,6 +656,7 @@ function ServicesPage() {
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
{sheets}
|
||||
</PageShell>
|
||||
|
||||
Reference in New Issue
Block a user