feat(admin-ui): catalog refresh + token migration (Stage 3.2)

This commit is contained in:
Александр Зимин
2026-05-11 09:08:38 +00:00
parent 3e19fd2cf9
commit 6db2a0c345
24 changed files with 289 additions and 273 deletions
@@ -202,7 +202,7 @@ export const DictionaryEditorDialog = ({ open, mode, onClose, onSuccess }: Props
<div className={activeTab === 'metadata' ? 'block' : 'hidden'}>
{!isEdit && (
<div className="mb-3 p-3 rounded-md border border-ultramarain/20 bg-ultramarain/4">
<div className="mb-3 p-3 rounded-md border border-accent/20 bg-accent/4">
<SingleSelect
label={t('schema.template.label')}
hint={t('schema.template.hint')}
@@ -300,7 +300,7 @@ export const DictionaryEditorDialog = ({ open, mode, onClose, onSuccess }: Props
/>
{/* CEO plan E2: per-dict Redis projection opt-in. Default false.
Включается когда dict хочет 10k+ RPS на read-api (вместо PG). */}
<label className="md:col-span-2 flex items-start gap-3 px-3 py-2 rounded-sm border border-regolith bg-regolith/20 cursor-pointer">
<label className="md:col-span-2 flex items-start gap-3 px-3 py-2 rounded-sm border border-line bg-line/20 cursor-pointer">
<input
type="checkbox"
checked={redisProjection}
@@ -308,10 +308,10 @@ export const DictionaryEditorDialog = ({ open, mode, onClose, onSuccess }: Props
className="mt-0.5 size-4 accent-ultramarain"
/>
<span className="flex-1">
<span className="block text-sm font-primary text-carbon">
<span className="block text-sm font-sans text-ink">
{t('schema.redisProjection.label')}
</span>
<span className="block text-2xs text-carbon/60 mt-0.5">
<span className="block text-2xs text-mute mt-0.5">
{t('schema.redisProjection.hint')}
</span>
</span>
@@ -320,7 +320,7 @@ export const DictionaryEditorDialog = ({ open, mode, onClose, onSuccess }: Props
{/* Approval Workflow v2: per-dict opt-in. Default false. Включается
для критичных dicts (ground_station, spacecraft и т.д.) где
один admin не должен иметь power публиковать без review. */}
<label className="md:col-span-2 flex items-start gap-3 px-3 py-2 rounded-sm border border-orbit/40 bg-orbit/8 cursor-pointer">
<label className="md:col-span-2 flex items-start gap-3 px-3 py-2 rounded-sm border border-warn bg-warn-bg cursor-pointer">
<input
type="checkbox"
checked={approvalRequired}
@@ -328,10 +328,10 @@ export const DictionaryEditorDialog = ({ open, mode, onClose, onSuccess }: Props
className="mt-0.5 size-4 accent-orbit"
/>
<span className="flex-1">
<span className="block text-sm font-primary text-carbon">
<span className="block text-sm font-sans text-ink">
{t('schema.approvalRequired.label')}
</span>
<span className="block text-2xs text-carbon/60 mt-0.5">
<span className="block text-2xs text-mute mt-0.5">
{t('schema.approvalRequired.hint')}
</span>
</span>
@@ -341,7 +341,7 @@ export const DictionaryEditorDialog = ({ open, mode, onClose, onSuccess }: Props
<div className="md:col-span-2">
<label
htmlFor="approval-min-role"
className="text-2xs uppercase tracking-label text-carbon/70"
className="text-2xs uppercase tracking-[0.10em] text-ink-2"
>
{t('schema.approvalMinRole.label')}
</label>
@@ -351,7 +351,7 @@ export const DictionaryEditorDialog = ({ open, mode, onClose, onSuccess }: Props
onChange={(e) => setApprovalMinRole(e.target.value)}
placeholder="ordinis:internal"
/>
<p className="text-2xs text-carbon/60 mt-0.5">
<p className="text-2xs text-mute mt-0.5">
{t('schema.approvalMinRole.hint')}
</p>
</div>
@@ -364,7 +364,7 @@ export const DictionaryEditorDialog = ({ open, mode, onClose, onSuccess }: Props
</div>
<div className={activeTab === 'preview' ? 'block' : 'hidden'}>
<pre className="bg-regolith/30 rounded p-3 text-2xs font-mono overflow-x-auto whitespace-pre-wrap">
<pre className="bg-line/30 rounded p-3 text-2xs font-mono overflow-x-auto whitespace-pre-wrap">
{JSON.stringify(schemaJson, null, 2)}
</pre>
</div>
@@ -47,7 +47,7 @@ export const EventsPreviewTab = ({
return (
<div className="space-y-3">
<p className="text-sm text-carbon/70">
<p className="text-sm text-ink-2">
{t('schema.events.intro')}
</p>
@@ -57,18 +57,18 @@ export const EventsPreviewTab = ({
<div className="space-y-2">
<div className="flex items-center gap-2 flex-wrap">
<Badge variant="info">{current.eventType}</Badge>
<span className="text-2xs text-carbon/70">
<span className="text-2xs text-ink-2">
{t('schema.events.topic')}:
</span>
<code className="text-2xs font-mono text-ultramarain">
<code className="text-2xs font-mono text-accent">
{current.topic}
</code>
</div>
<p className="text-2xs text-carbon/60">{current.description}</p>
<pre className="bg-regolith/30 rounded p-3 text-2xs font-mono overflow-x-auto whitespace-pre-wrap">
<p className="text-2xs text-mute">{current.description}</p>
<pre className="bg-line/30 rounded p-3 text-2xs font-mono overflow-x-auto whitespace-pre-wrap">
{JSON.stringify(current.envelope, null, 2)}
</pre>
<p className="text-2xs text-carbon/50">
<p className="text-2xs text-mute">
{t('schema.events.disclaimer')}
</p>
</div>
@@ -49,9 +49,9 @@ export const PropertyEditor = ({
const update = (patch: Partial<PropertyDef>) => onChange({ ...prop, ...patch })
return (
<div className="border border-regolith rounded-lg p-3 space-y-3 bg-white">
<div className="border border-line rounded-lg p-3 space-y-3 bg-white">
<div className="flex items-start justify-between gap-2">
<span className="text-2xs uppercase tracking-label text-carbon/60">
<span className="text-2xs uppercase tracking-[0.10em] text-mute">
{t('schema.property')} #{index + 1}
</span>
<div className="flex items-center gap-1">
@@ -119,13 +119,13 @@ export const PropertyEditor = ({
{prop.kind === 'opaque' && (
<div className="bg-amber-50 border border-amber-200 rounded-md p-3 text-2xs space-y-2">
<div className="font-medium text-carbon">
<div className="font-medium text-ink">
{t('schema.opaque.title')}
</div>
<div className="text-carbon/70">
<div className="text-ink-2">
{t('schema.opaque.hint')}
</div>
<pre className="font-mono text-2xs bg-white border border-regolith rounded p-2 overflow-auto max-h-40">
<pre className="font-mono text-2xs bg-white border border-line rounded p-2 overflow-auto max-h-40">
{JSON.stringify(prop.rawSchema ?? {}, null, 2)}
</pre>
</div>
@@ -260,7 +260,7 @@ const ReferenceTargetPicker = ({ value, onChange }: ReferenceTargetPickerProps)
const isValid = Boolean(refDict && refField)
return (
<div className="border border-ultramarain/20 bg-ultramarain/4 rounded-md p-3 space-y-3">
<div className="border border-accent/20 bg-accent/4 rounded-md p-3 space-y-3">
<div>
<FieldLabel required>{t('schema.reference.title')}</FieldLabel>
<FieldHint>{t('schema.reference.hint')}</FieldHint>