feat(web): dashboard modules grid and activity feed as on mockup boards
quality / changes (push) Successful in 8s
quality / go (push) Skipped
quality / bird2 (push) Skipped
quality / commitlint (push) Skipped
quality / docker-check (push) Skipped
quality / openapi (push) Successful in 23s
quality / web (push) Successful in 1m32s
CD / quality (push) Successful in 2m11s
CD / publish (push) Successful in 3m7s
quality / changes (push) Successful in 8s
quality / go (push) Skipped
quality / bird2 (push) Skipped
quality / commitlint (push) Skipped
quality / docker-check (push) Skipped
quality / openapi (push) Successful in 23s
quality / web (push) Successful in 1m32s
CD / quality (push) Successful in 2m11s
CD / publish (push) Successful in 3m7s
Заголовки страниц приведены к доскам (20px). На панели добавлены таблица первых 5 модулей и лента активности по последним задачам. Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
This commit is contained in:
1 parent
55ddce43f7
commit
53420b49a1
2 files changed
+34
-11
No files matched your search
@@ -2,22 +2,19 @@ import type { ReactNode } from 'react'
|
||||
|
||||
interface PageHeaderProps {
|
||||
title: string
|
||||
description?: string
|
||||
description?: ReactNode
|
||||
actions?: ReactNode
|
||||
}
|
||||
|
||||
/** Заголовок страницы как на досках макета: название 20px, описание 14px muted, действия справа. */
|
||||
export function PageHeader({ title, description, actions }: PageHeaderProps) {
|
||||
return (
|
||||
<div className="flex min-w-0 flex-col gap-2 md:flex-row md:items-start md:justify-between">
|
||||
<div className="flex min-w-0 flex-col gap-1">
|
||||
<h1 className="text-2xl font-semibold tracking-tight">{title}</h1>
|
||||
{description ? (
|
||||
<p className="text-muted-foreground max-w-prose text-sm break-words">{description}</p>
|
||||
) : null}
|
||||
</div>
|
||||
{actions ? (
|
||||
<div className="flex shrink-0 flex-wrap items-center justify-end gap-2">{actions}</div>
|
||||
) : null}
|
||||
<header className="flex min-w-0 flex-wrap items-end justify-between gap-3">
|
||||
<div className="flex min-w-0 flex-col gap-0.5">
|
||||
<h1 className="text-xl font-semibold tracking-[-0.01em]">{title}</h1>
|
||||
{description ? <p className="text-muted-foreground text-sm text-pretty">{description}</p> : null}
|
||||
</div>
|
||||
{actions ? <div className="flex shrink-0 flex-wrap items-center justify-end gap-2">{actions}</div> : null}
|
||||
</header>
|
||||
)
|
||||
}
|
||||
@@ -9,6 +9,10 @@ import { buildDashboardKpiCards } from '@/components/dashboard/dashboard-kpi-gri
|
||||
import { DashboardNetworkHealth } from '@/components/dashboard/dashboard-network-health'
|
||||
import { DashboardOperationsBreakdown } from '@/components/dashboard/dashboard-operations-breakdown'
|
||||
import { DashboardQuickLinks } from '@/components/dashboard/dashboard-quick-links'
|
||||
import { ModulesListGrid } from '@/components/modules/modules-list-grid'
|
||||
import { ActivityFeed } from '@/components/portal/canvas-blocks'
|
||||
import { fmtWhen } from '@/components/portal/format'
|
||||
import type { Tone } from '@/components/portal/tone'
|
||||
import { OpsDashboard } from '@/components/reui-kit'
|
||||
import { chartPanelGridClassName } from '@/lib/ui-surface'
|
||||
import {
|
||||
@@ -69,6 +73,18 @@ function DashboardComponent() {
|
||||
const speakers = speakersQ.data?.items ?? []
|
||||
const jobs = jobsQ.data?.items ?? []
|
||||
const kpiCards = buildDashboardKpiCards({ modules, peers, speakers, jobs })
|
||||
const activity = jobs.slice(0, 4).map((j) => {
|
||||
const failed = ['failed', 'error', 'cancelled'].includes(j.status.toLowerCase())
|
||||
const running = j.status === 'running' || j.status === 'queued'
|
||||
const tone: Tone = failed ? 'er' : running ? 'in' : 'ok'
|
||||
return {
|
||||
t: fmtWhen(j.finished_at ?? j.started_at ?? j.created_at),
|
||||
title: j.kind,
|
||||
text: j.error ?? `Статус: ${j.status}`,
|
||||
label: failed ? 'Error' : running ? 'Running' : 'Info',
|
||||
tone,
|
||||
}
|
||||
})
|
||||
|
||||
return (
|
||||
<OpsDashboard
|
||||
@@ -87,6 +103,16 @@ function DashboardComponent() {
|
||||
kpiCards={kpiCards}
|
||||
isLoading={initialLoading}
|
||||
afterKpi={showQuickActions ? <DashboardQuickLinks /> : null}
|
||||
queue={
|
||||
<div className="flex min-w-0 flex-col gap-5">
|
||||
<ModulesListGrid items={modules.slice(0, 5)} isLoading={modulesQ.isLoading} title="Модули" />
|
||||
{activity.length > 0 ? (
|
||||
<ActivityFeed title="Активность" description="Последние события плоскости управления" items={activity} />
|
||||
) : null}
|
||||
</div>
|
||||
}
|
||||
queueTitle=""
|
||||
queueDescription=""
|
||||
charts={
|
||||
<div className={chartPanelGridClassName}>
|
||||
<DashboardNetworkHealth
|
||||
|
||||
Reference in new issue
Block a user