fix(ui): выровнять chrome Frame и убрать Card-оболочки
Docker images / prepare-release (push) Successful in 4s
Docker images / backend-image (push) Failing after 2m36s
Docker images / frontend-image (push) Successful in 2m22s
Docker images / notify-webhook (push) Skipped
Docker images / updater-image (push) Successful in 55s
Docker images / publish-release (push) Skipped

Подключить App Switcher, NavUser, OpsPanel и AlertDialog вместо Card-shell.

Co-authored-by: Cursor <[email protected]>
This commit is contained in:
Denozordec
2026-08-17 15:36:56 +07:00
co-authored by Cursor
parent d2de8d3188
commit 5f29cfaf0f
47 changed files with 1972 additions and 860 deletions
+33 -39
View File
@@ -6,7 +6,9 @@ import { PageHeader } from "@/components/page-header"
import { FormToggle } from "@/components/form-kit"
import { Badge } from "@/components/ui/badge"
import { Button, buttonVariants } from "@/components/ui/button"
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
import { Frame, FramePanel } from "@/components/reui/frame"
import { IconTile } from "@/components/reui/icon-tile"
import { OpsPanel } from "@/components/ops-panel"
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"
import {
Collapsible,
@@ -1032,30 +1034,24 @@ export default function DataCollectionPage() {
<div className="flex-1 overflow-y-auto p-6">
<div className="flex flex-col gap-5 max-w-[1100px] mx-auto w-full">
{!prefsHydrated && (
<Card>
<CardHeader>
<CardTitle className="text-base">Загрузка настроек подключения</CardTitle>
<CardDescription className="text-xs">
Читаем режим данных и адрес API из локальных настроек.
</CardDescription>
</CardHeader>
</Card>
<OpsPanel
title="Загрузка настроек подключения"
description="Читаем режим данных и адрес API из локальных настроек."
>
<div />
</OpsPanel>
)}
{prefsHydrated && !isLive && (
<Card>
<CardHeader>
<CardTitle className="text-base">Нужен live-режим</CardTitle>
<CardDescription className="text-xs">
Планировщик и журнал читаются только с бекенда. Включите «Живые» данные и проверьте URL бекенда в настройках.
</CardDescription>
</CardHeader>
<CardContent className="px-5 pb-5">
<OpsPanel
title="Нужен live-режим"
description="Планировщик и журнал читаются только с бекенда. Включите «Живые» данные и проверьте URL бекенда в настройках."
contentClassName="px-5 pb-5"
>
<Link href="/settings" className={cn(buttonVariants({ variant: "default", size: "sm" }), "h-8")}>
Открыть настройки
</Link>
</CardContent>
</Card>
</OpsPanel>
)}
{isLive && collectorError && (
@@ -1070,16 +1066,18 @@ export default function DataCollectionPage() {
<>
<div className="grid grid-cols-2 lg:grid-cols-4 gap-4">
{stats.map((s) => (
<Card key={s.label}>
<CardContent className="px-5 py-4 flex items-start justify-between gap-3">
<div className="min-w-0">
<p className="text-sm text-muted-foreground">{s.label}</p>
<p className="text-xl font-semibold tabular-nums mt-0.5 truncate">{s.value}</p>
<Frame key={s.label} className="h-full">
<FramePanel className="relative isolate flex h-full items-start gap-3">
<IconTile variant="elevated" aria-hidden="true" className="size-10.5 text-muted-foreground">
{s.icon}
</IconTile>
<div className="min-w-0 flex-1 flex flex-col gap-0.5">
<p className="text-muted-foreground text-sm font-medium">{s.label}</p>
<p className="text-xl leading-none font-bold tabular-nums truncate">{s.value}</p>
<p className="text-[11px] text-muted-foreground mt-1 leading-snug line-clamp-2">{s.sub}</p>
</div>
<div className="shrink-0 mt-0.5">{s.icon}</div>
</CardContent>
</Card>
</FramePanel>
</Frame>
))}
</div>
@@ -1203,14 +1201,10 @@ export default function DataCollectionPage() {
</div>
</DataPageCard>
<Card>
<CardHeader className="border-b border-border flex flex-col gap-3 sm:flex-row sm:items-end sm:justify-between">
<div>
<CardTitle className="text-base">Журнал прогонов</CardTitle>
<CardDescription className="text-xs">
SQLite `scheduler_runs` до 80 записей; раскройте строку для полей и текста ошибки.
</CardDescription>
</div>
<OpsPanel
title="Журнал прогонов"
description="SQLite `scheduler_runs` — до 80 записей; раскройте строку для полей и текста ошибки."
headerRight={
<div className="flex items-center gap-2 shrink-0">
<label className="text-xs text-muted-foreground whitespace-nowrap" htmlFor="run-filter">
Задача
@@ -1229,8 +1223,9 @@ export default function DataCollectionPage() {
))}
</select>
</div>
</CardHeader>
<CardContent className="px-0 pb-0">
}
contentClassName="px-0 pb-0"
>
{schedulerRuns.length === 0 ? (
<p className="text-sm text-muted-foreground text-center py-10 px-4">Пока нет прогонов</p>
) : (
@@ -1287,8 +1282,7 @@ export default function DataCollectionPage() {
))}
</div>
)}
</CardContent>
</Card>
</OpsPanel>
</>
)}
</div>