fix(web): align grid columns with reui reference and clean labels
Гриды операций и расписания выровнены по эталону data-grid-filtering-2: явные размеры колонок (size в columnDef) вместо равномерного деления при table-layout: fixed — колонка названия доминирует, второстепенные сжаты по содержимому, пропали обрезанные имена («partner-dom…», «Обновлен...»). Убраны фейковые многоточия из JS-срезов: ID ревизии и варианты выбора в сравнении теперь показываются целиком, а усечение делает CSS-truncate. Подписи «Ревизия A/B» переведены на Field/FieldLabel вместо самодельных span, шапка блока diff дополнена заголовком «ревизия A → ревизия B» (CodeBlockTitle) слева от кнопок.
This commit is contained in:
@@ -93,6 +93,7 @@ export function OperationsJobsGrid({
|
||||
)
|
||||
},
|
||||
meta: { headerTitle: 'Вид' },
|
||||
size: 320,
|
||||
},
|
||||
{
|
||||
accessorKey: 'status',
|
||||
@@ -105,6 +106,7 @@ export function OperationsJobsGrid({
|
||||
return <StatusBadge status={row.original.status} hint={hint} />
|
||||
},
|
||||
meta: { headerTitle: 'Статус' },
|
||||
size: 150,
|
||||
},
|
||||
{
|
||||
id: 'created_at',
|
||||
@@ -118,6 +120,7 @@ export function OperationsJobsGrid({
|
||||
</DataGridMutedCell>
|
||||
),
|
||||
meta: { headerTitle: 'Создана' },
|
||||
size: 190,
|
||||
},
|
||||
{
|
||||
id: 'finished_at',
|
||||
@@ -131,6 +134,7 @@ export function OperationsJobsGrid({
|
||||
</DataGridMutedCell>
|
||||
),
|
||||
meta: { headerTitle: 'Завершена' },
|
||||
size: 190,
|
||||
},
|
||||
{
|
||||
id: 'actions',
|
||||
|
||||
@@ -56,9 +56,10 @@ export function OperationsRevisionsGrid({
|
||||
accessorFn: (row) => row.id,
|
||||
header: ({ column }) => <DataGridColumnHeader column={column} title="ID" />,
|
||||
cell: ({ row }) => (
|
||||
<DataGridNameCell icon={GitCommitHorizontal} title={`${row.original.id.slice(0, 12)}…`} />
|
||||
<DataGridNameCell icon={GitCommitHorizontal} title={row.original.id} />
|
||||
),
|
||||
meta: { headerTitle: 'ID' },
|
||||
size: 340,
|
||||
},
|
||||
{
|
||||
accessorKey: 'created_at',
|
||||
@@ -69,6 +70,7 @@ export function OperationsRevisionsGrid({
|
||||
</DataGridMutedCell>
|
||||
),
|
||||
meta: { headerTitle: 'Создана' },
|
||||
size: 210,
|
||||
},
|
||||
{
|
||||
accessorKey: 'materialized_prefix_count',
|
||||
@@ -79,6 +81,7 @@ export function OperationsRevisionsGrid({
|
||||
</span>
|
||||
),
|
||||
meta: { headerTitle: 'Префиксов' },
|
||||
size: 150,
|
||||
},
|
||||
{
|
||||
id: 'actions',
|
||||
@@ -91,7 +94,7 @@ export function OperationsRevisionsGrid({
|
||||
<RefreshCw className="size-3.5" />
|
||||
</Button>
|
||||
}
|
||||
title={`Откатиться к ревизии ${row.original.id.slice(0, 8)}…?`}
|
||||
title={`Откатиться к ревизии ${row.original.id}?`}
|
||||
description="Будет создана новая ревизия на основе выбранной. Требуется роль оператора."
|
||||
confirmLabel="Откатить"
|
||||
destructive
|
||||
|
||||
@@ -52,12 +52,14 @@ export function ScheduleModulesGrid({
|
||||
header: ({ column }) => <DataGridColumnHeader column={column} title="Модуль" />,
|
||||
cell: ({ row }) => <DataGridNameCell icon={Boxes} title={row.original.name} />,
|
||||
meta: { headerTitle: 'Модуль' },
|
||||
size: 280,
|
||||
},
|
||||
{
|
||||
accessorKey: 'type',
|
||||
header: ({ column }) => <DataGridColumnHeader column={column} title="Тип" />,
|
||||
cell: ({ row }) => <CategoryBadge>{moduleTypeRu(row.original.type)}</CategoryBadge>,
|
||||
meta: { headerTitle: 'Тип' },
|
||||
size: 150,
|
||||
},
|
||||
{
|
||||
id: 'schedule',
|
||||
@@ -70,6 +72,7 @@ export function ScheduleModulesGrid({
|
||||
</DataGridMonoCell>
|
||||
),
|
||||
meta: { headerTitle: 'Расписание' },
|
||||
size: 130,
|
||||
},
|
||||
{
|
||||
id: 'last_refreshed_at',
|
||||
@@ -83,6 +86,7 @@ export function ScheduleModulesGrid({
|
||||
</DataGridMutedCell>
|
||||
),
|
||||
meta: { headerTitle: 'Обновлено' },
|
||||
size: 190,
|
||||
},
|
||||
{
|
||||
id: 'enabled',
|
||||
@@ -92,6 +96,7 @@ export function ScheduleModulesGrid({
|
||||
<ModeBadge enabled={row.original.enabled} onLabel="Вкл" offLabel="Выкл" />
|
||||
),
|
||||
meta: { headerTitle: 'Статус' },
|
||||
size: 110,
|
||||
},
|
||||
{
|
||||
id: 'actions',
|
||||
|
||||
@@ -5,6 +5,7 @@ import { toast } from 'sonner'
|
||||
import { useMemo, useState } from 'react'
|
||||
|
||||
import { Button } from '@evobgp/ui/components/button'
|
||||
import { Field, FieldLabel } from '@evobgp/ui/components/field'
|
||||
import { SegmentedTabs, TabsContent } from '@/components/segmented-tabs'
|
||||
import {
|
||||
FrameSection,
|
||||
@@ -19,6 +20,7 @@ import {
|
||||
CodeBlockCopyButton,
|
||||
CodeBlockExpandButton,
|
||||
CodeBlockHeader,
|
||||
CodeBlockTitle,
|
||||
} from '@/components/reui/code-block/code-block'
|
||||
import type { CodeBlockDiffSpec } from '@/components/reui/code-block/code-block-highlight'
|
||||
import { SelectMenu } from '@/components/select-field'
|
||||
@@ -275,35 +277,31 @@ function DiffTab({ revisions }: { revisions: RevisionRow[] }) {
|
||||
const [b, setB] = useState('')
|
||||
const diffQ = useQuery(operationsDiffQueryOptions(a, b))
|
||||
const revisionItems = useMemo(
|
||||
() =>
|
||||
revisions.map((r) => ({
|
||||
value: r.id,
|
||||
label: `${r.id.slice(0, 12)}…`,
|
||||
})),
|
||||
() => revisions.map((r) => ({ value: r.id, label: r.id })),
|
||||
[revisions],
|
||||
)
|
||||
|
||||
return (
|
||||
<FrameSection title="Сравнение ревизий" contentClassName="flex flex-col gap-4 py-4">
|
||||
<div className="flex flex-wrap items-end gap-3">
|
||||
<div className="flex w-full max-w-xs flex-col gap-1">
|
||||
<span className="text-xs text-muted-foreground">Ревизия A</span>
|
||||
<Field className="w-full max-w-xs">
|
||||
<FieldLabel>Ревизия A</FieldLabel>
|
||||
<SelectMenu
|
||||
items={revisionItems}
|
||||
value={a}
|
||||
placeholder="Выберите"
|
||||
onValueChange={(v) => v && setA(v)}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex w-full max-w-xs flex-col gap-1">
|
||||
<span className="text-xs text-muted-foreground">Ревизия B</span>
|
||||
</Field>
|
||||
<Field className="w-full max-w-xs">
|
||||
<FieldLabel>Ревизия B</FieldLabel>
|
||||
<SelectMenu
|
||||
items={revisionItems}
|
||||
value={b}
|
||||
placeholder="Выберите"
|
||||
onValueChange={(v) => v && setB(v)}
|
||||
/>
|
||||
</div>
|
||||
</Field>
|
||||
<Button onClick={() => diffQ.refetch()} disabled={!a || !b || diffQ.isFetching}>
|
||||
Сравнить
|
||||
</Button>
|
||||
@@ -363,6 +361,9 @@ function DiffView({ diff }: { diff: import('@/types/api').RevisionDiff }) {
|
||||
label="Различия ревизий"
|
||||
>
|
||||
<CodeBlockHeader>
|
||||
<CodeBlockTitle className="flex-1">
|
||||
{`${diff.revision_a ?? '—'} → ${diff.revision_b ?? '—'}`}
|
||||
</CodeBlockTitle>
|
||||
<CodeBlockCopyButton />
|
||||
<CodeBlockExpandButton>Показать всё</CodeBlockExpandButton>
|
||||
</CodeBlockHeader>
|
||||
|
||||
Reference in New Issue
Block a user