feat(changelog): wire up History tab to /changelog endpoint + diff modal

This commit is contained in:
Александр Зимин
2026-05-12 10:49:53 +00:00
parent ba04c2199e
commit 57be0d88d3
6 changed files with 614 additions and 38 deletions
@@ -0,0 +1,96 @@
import {
PencilSimpleIcon,
PlusCircleIcon,
CheckCircleIcon,
XCircleIcon,
ArrowsCounterClockwiseIcon,
RocketIcon,
TrashIcon,
ChatCircleTextIcon,
EyeIcon,
type Icon,
} from '@phosphor-icons/react'
import type { ChangelogKind } from '@/api/client'
import type { BadgeProps } from '@/ui'
/**
* Metadata mapping для ChangelogKind: icon, badge variant, локализуемый
* label. Один источник для History tab card + Diff modal header.
*
* Versioning events (definition_*, draft_publish) и draft promotional
* events различаются tone'ом — promotional рендерятся neutral/info чтобы
* не конкурировать с major version bump'ом визуально.
*/
type TFn = (key: string, opts?: { defaultValue?: string }) => string
export function kindIcon(kind: ChangelogKind): Icon {
switch (kind) {
case 'definition_create':
return PlusCircleIcon
case 'definition_update':
return PencilSimpleIcon
case 'draft_create':
return ChatCircleTextIcon
case 'draft_review':
return EyeIcon
case 'draft_approve':
return CheckCircleIcon
case 'draft_reject':
return XCircleIcon
case 'draft_changes_requested':
return ArrowsCounterClockwiseIcon
case 'draft_publish':
return RocketIcon
case 'draft_withdraw':
return TrashIcon
}
}
export function kindBadgeVariant(kind: ChangelogKind): BadgeProps['variant'] {
switch (kind) {
case 'definition_create':
case 'draft_publish':
return 'primary'
case 'definition_update':
return 'info'
case 'draft_approve':
return 'success'
case 'draft_reject':
return 'danger'
case 'draft_changes_requested':
return 'warning'
case 'draft_create':
case 'draft_review':
case 'draft_withdraw':
return 'neutral'
}
}
export function kindLabel(kind: ChangelogKind, t: TFn): string {
const fallbackByKind: Record<ChangelogKind, string> = {
definition_create: 'Создан словарь',
definition_update: 'Изменена схема',
draft_create: 'Черновик создан',
draft_review: 'Отправлен на ревью',
draft_approve: 'Одобрен',
draft_reject: 'Отклонён',
draft_changes_requested: 'Запрошены правки',
draft_publish: 'Опубликован',
draft_withdraw: 'Отозван',
}
return t(`changelog.kind.${kind}`, { defaultValue: fallbackByKind[kind] })
}
/**
* Versioning events меняют semver/HEAD словаря. Promotional draft events
* (review/approve/reject/changes_requested/withdraw) меняют только
* workflow state — без bump'а версии.
*/
export function isVersioningKind(kind: ChangelogKind): boolean {
return (
kind === 'definition_create' ||
kind === 'definition_update' ||
kind === 'draft_publish'
)
}