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