feat(ui): единый PageHeader h1 на всех разделах
Build, Test, and Push CFDM Docker Image / test (push) Successful in 3m4s
Build, Test, and Push CFDM Docker Image / build-and-push (push) Successful in 1m45s
Build, Test, and Push CFDM Docker Image / create-release (push) Skipped
Build, Test, and Push CFDM Docker Image / update-wiki (push) Successful in 6s
Build, Test, and Push CFDM Docker Image / test (push) Successful in 3m4s
Build, Test, and Push CFDM Docker Image / build-and-push (push) Successful in 1m45s
Build, Test, and Push CFDM Docker Image / create-release (push) Skipped
Build, Test, and Push CFDM Docker Image / update-wiki (push) Successful in 6s
Заголовок раздела над KPI/контентом; FrameTitle text-sm больше не заменяет page-level h1. Co-authored-by: Cursor <[email protected]>
This commit is contained in:
@@ -6,6 +6,7 @@ import type { Filter } from '@/components/reui/filters'
|
||||
import { certificatesQueryOptions, certKeys, certSummaryQueryOptions } from '@/queries'
|
||||
import { api } from '@/lib/api-client'
|
||||
import { PageShell } from '@/components/page-shell'
|
||||
import { PageHeader } from '@/components/page-header'
|
||||
import { ResourcePage } from '@/components/reui-kit'
|
||||
import { CertKpiCards } from '@/components/cert-kpi-cards'
|
||||
import {
|
||||
@@ -71,6 +72,11 @@ function CertificatesPage() {
|
||||
|
||||
return (
|
||||
<PageShell>
|
||||
<PageHeader
|
||||
title="Сертификаты"
|
||||
description="Мониторинг SSL: хосты с активными сервисами или режимом «Обязательно»"
|
||||
actions={primaryAction}
|
||||
/>
|
||||
<CertKpiCards
|
||||
summary={summary}
|
||||
total={certs?.length}
|
||||
@@ -81,6 +87,7 @@ function CertificatesPage() {
|
||||
<ResourcePage
|
||||
title="Сертификаты"
|
||||
description="Мониторинг SSL: хосты с активными сервисами или режимом «Обязательно»"
|
||||
hideHeader
|
||||
tabs={CERT_TABS.map((tab) => ({ ...tab }))}
|
||||
activeTab={activeTab}
|
||||
onTabChange={setActiveTab}
|
||||
@@ -97,7 +104,6 @@ function CertificatesPage() {
|
||||
isError={isError}
|
||||
error={error}
|
||||
onRetry={refetch}
|
||||
primaryAction={primaryAction}
|
||||
emptyState={{
|
||||
title: 'Сертификаты не найдены',
|
||||
description: 'Сертификаты появятся после проверки доменов',
|
||||
|
||||
@@ -15,6 +15,7 @@ import {
|
||||
serviceBindingKeys,
|
||||
} from '@/queries'
|
||||
import { PageShell } from '@/components/page-shell'
|
||||
import { PageHeader } from '@/components/page-header'
|
||||
import { DomainKpiCards } from '@/components/domain-kpi-cards'
|
||||
import { ResourcePage } from '@/components/reui-kit'
|
||||
import {
|
||||
@@ -149,6 +150,11 @@ function DomainsPage() {
|
||||
|
||||
return (
|
||||
<PageShell>
|
||||
<PageHeader
|
||||
title="Домены"
|
||||
description="Импортированные зоны Cloudflare"
|
||||
actions={primaryAction}
|
||||
/>
|
||||
<DomainKpiCards
|
||||
domains={domains}
|
||||
activeTab={activeTab}
|
||||
@@ -158,6 +164,7 @@ function DomainsPage() {
|
||||
<ResourcePage
|
||||
title="Домены"
|
||||
description="Импортированные зоны Cloudflare"
|
||||
hideHeader
|
||||
tabs={DOMAIN_TABS.map((tab) => ({ ...tab }))}
|
||||
activeTab={activeTab}
|
||||
onTabChange={setActiveTab}
|
||||
@@ -174,7 +181,6 @@ function DomainsPage() {
|
||||
isError={isError}
|
||||
error={error}
|
||||
onRetry={refetch}
|
||||
primaryAction={primaryAction}
|
||||
enableRowSelection
|
||||
selectionToolbar={({ selectedIds, clearSelection }) => (
|
||||
<DomainsBulkToolbar
|
||||
|
||||
@@ -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 { PageHeader } from '@/components/page-header'
|
||||
import { GroupKpiCards } from '@/components/group-kpi-cards'
|
||||
import { EmptyState } from '@/components/empty-state'
|
||||
import { ConfirmDialog } from '@/components/confirm-dialog'
|
||||
@@ -202,15 +203,31 @@ function GroupsPage() {
|
||||
</Button>
|
||||
)
|
||||
|
||||
const headerActions = (
|
||||
<>
|
||||
{createButton}
|
||||
<CatalogBoardToggle
|
||||
view={view}
|
||||
onViewChange={setView}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
<PageShell>
|
||||
<PageHeader
|
||||
title="Группы"
|
||||
description="Каталог групп доменов"
|
||||
actions={headerActions}
|
||||
/>
|
||||
{view === 'board' ? (
|
||||
<KanbanBoardSkeleton columns={3} />
|
||||
) : (
|
||||
<ResourcePage
|
||||
title="Группы"
|
||||
description="Каталог групп доменов"
|
||||
hideHeader
|
||||
isLoading
|
||||
filterFields={[]}
|
||||
filters={[]}
|
||||
@@ -228,6 +245,7 @@ function GroupsPage() {
|
||||
if (isError) {
|
||||
return (
|
||||
<PageShell>
|
||||
<PageHeader title="Группы" description="Каталог групп доменов" />
|
||||
<EmptyState
|
||||
title="Не удалось загрузить группы"
|
||||
description={error?.message}
|
||||
@@ -243,6 +261,15 @@ function GroupsPage() {
|
||||
|
||||
return (
|
||||
<PageShell>
|
||||
<PageHeader
|
||||
title="Группы"
|
||||
description={
|
||||
view === 'board'
|
||||
? 'Перетащите домен в группу или создайте новую группу'
|
||||
: 'Каталог групп доменов'
|
||||
}
|
||||
actions={headerActions}
|
||||
/>
|
||||
{view === 'board' ? (
|
||||
(groups?.length ?? 0) === 0 && (domains?.length ?? 0) === 0 ? (
|
||||
<EmptyState
|
||||
@@ -263,12 +290,6 @@ function GroupsPage() {
|
||||
columns={columnConfigs}
|
||||
value={kanbanValue}
|
||||
onValueChange={handleKanbanValueChange}
|
||||
toolbarActions={
|
||||
<>
|
||||
{createButton}
|
||||
<CatalogBoardToggle view="board" onViewChange={setView} />
|
||||
</>
|
||||
}
|
||||
renderCard={(domain, ctx) => (
|
||||
<DomainKanbanCard
|
||||
domain={domain}
|
||||
@@ -289,6 +310,7 @@ function GroupsPage() {
|
||||
<ResourcePage
|
||||
title="Группы"
|
||||
description="Каталог групп доменов"
|
||||
hideHeader
|
||||
tabs={GROUP_TABS.map((tab) => ({ ...tab }))}
|
||||
activeTab={activeTab}
|
||||
onTabChange={setActiveTab}
|
||||
@@ -301,12 +323,6 @@ function GroupsPage() {
|
||||
columns={columns}
|
||||
data={catalogRows}
|
||||
getRowId={(row) => String(row.id)}
|
||||
primaryAction={
|
||||
<>
|
||||
{createButton}
|
||||
<CatalogBoardToggle view="catalog" onViewChange={setView} />
|
||||
</>
|
||||
}
|
||||
emptyState={{
|
||||
title: 'Группы не найдены',
|
||||
description: 'Создайте группу для организации доменов.',
|
||||
|
||||
@@ -21,6 +21,7 @@ import type {
|
||||
UpdateServiceConfigInput,
|
||||
} from '@/lib/schemas'
|
||||
import { PageShell } from '@/components/page-shell'
|
||||
import { PageHeader } from '@/components/page-header'
|
||||
import { ServiceKpiCards } from '@/components/service-kpi-cards'
|
||||
import { EmptyState } from '@/components/empty-state'
|
||||
import { ConfirmDialog } from '@/components/confirm-dialog'
|
||||
@@ -437,6 +438,17 @@ function ServicesPage() {
|
||||
/>
|
||||
)
|
||||
|
||||
const headerActions = (
|
||||
<>
|
||||
{addMenu}
|
||||
<CatalogBoardToggle view={view} onViewChange={setView} />
|
||||
</>
|
||||
)
|
||||
|
||||
const pageDescription = filteredDomain
|
||||
? `Сервисы с привязками к домену ${filteredDomain.zone_name}`
|
||||
: 'Группы, FQDN и доступность сервисов'
|
||||
|
||||
const sheets = (
|
||||
<>
|
||||
<ServiceEditSheet
|
||||
@@ -528,12 +540,18 @@ function ServicesPage() {
|
||||
if (isLoading) {
|
||||
return (
|
||||
<PageShell>
|
||||
<PageHeader
|
||||
title="Сервисы"
|
||||
description={pageDescription}
|
||||
actions={headerActions}
|
||||
/>
|
||||
{view === 'board' ? (
|
||||
<KanbanBoardSkeleton columns={3} />
|
||||
) : (
|
||||
<ServicesGroupedCatalog
|
||||
data={{ groups: [], ungrouped: [] }}
|
||||
isLoading
|
||||
hideHeader
|
||||
togglingId={null}
|
||||
onEditService={() => {}}
|
||||
onDeleteService={() => {}}
|
||||
@@ -551,6 +569,7 @@ function ServicesPage() {
|
||||
if (isError) {
|
||||
return (
|
||||
<PageShell>
|
||||
<PageHeader title="Сервисы" description={pageDescription} />
|
||||
<EmptyState
|
||||
title="Не удалось загрузить сервисы"
|
||||
description={error?.message}
|
||||
@@ -567,6 +586,11 @@ function ServicesPage() {
|
||||
|
||||
return (
|
||||
<PageShell>
|
||||
<PageHeader
|
||||
title="Сервисы"
|
||||
description={pageDescription}
|
||||
actions={headerActions}
|
||||
/>
|
||||
{view === 'board' ? (
|
||||
<>
|
||||
<ServicesBulkToolbar
|
||||
@@ -588,7 +612,6 @@ function ServicesPage() {
|
||||
action={
|
||||
<div className="flex flex-wrap justify-center gap-2">
|
||||
{addMenu}
|
||||
<CatalogBoardToggle view="board" onViewChange={setView} />
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
@@ -603,12 +626,6 @@ function ServicesPage() {
|
||||
columns={columnConfigs}
|
||||
value={kanbanValue}
|
||||
onValueChange={dragDisabled ? () => {} : handleKanbanValueChange}
|
||||
toolbarActions={
|
||||
<>
|
||||
{addMenu}
|
||||
<CatalogBoardToggle view="board" onViewChange={setView} />
|
||||
</>
|
||||
}
|
||||
renderCard={(service, ctx) => (
|
||||
<ServiceKanbanCard
|
||||
service={service}
|
||||
@@ -638,18 +655,13 @@ function ServicesPage() {
|
||||
togglingId={togglingServiceId}
|
||||
activeTab={activeTab}
|
||||
onTabChange={setActiveTab}
|
||||
hideHeader
|
||||
onEditService={setEditingService}
|
||||
onDeleteService={setDeletingService}
|
||||
onToggleService={handleServiceToggle}
|
||||
onEditGroup={setEditingGroup}
|
||||
onDeleteGroup={setDeletingGroup}
|
||||
onAddServiceToGroup={handleOpenCreateService}
|
||||
primaryAction={
|
||||
<>
|
||||
{addMenu}
|
||||
<CatalogBoardToggle view="catalog" onViewChange={setView} />
|
||||
</>
|
||||
}
|
||||
emptyAction={
|
||||
<div className="flex flex-wrap justify-center gap-2">
|
||||
{addMenu}
|
||||
|
||||
Reference in New Issue
Block a user