diff --git a/src/features/control-center/pages/ModulesPage.tsx b/src/features/control-center/pages/ModulesPage.tsx
index 4ca8ef6..df22b00 100644
--- a/src/features/control-center/pages/ModulesPage.tsx
+++ b/src/features/control-center/pages/ModulesPage.tsx
@@ -5,10 +5,12 @@ import {
Pause,
RotateCcw,
Sliders,
+ Sparkles,
} from 'lucide-react';
import { useKccStore, useOperatorRole } from '../store/kccStore';
import { StatusBadge } from '../components/StatusBadge';
import { RolloutStage } from '../contracts';
+import { RU_ROLLOUT_STAGE, RU_MODULE_CATEGORY } from '../locales/ru';
export const ModulesPage: React.FC = () => {
const modules = useKccStore((state) => state.modules);
@@ -31,10 +33,11 @@ export const ModulesPage: React.FC = () => {
const handleStageChange = (stage: RolloutStage, percentage: number) => {
if (!activeRollout) return;
+ const stageLabel = RU_ROLLOUT_STAGE[stage] || stage;
openConfirmModal({
title: `Смена фазы раскатки: ${activeRollout.moduleName}`,
actionName: `rollout.stage_${stage}`,
- impactSummary: `Конвейер раскатки будет переведен в состояние «${stage}» (${percentage}% трафика).`,
+ impactSummary: `Конвейер раскатки будет переведен в состояние «${stageLabel}» (${percentage}% трафика).`,
targetType: 'rollout',
targetId: activeRollout.rolloutId,
targetName: activeRollout.moduleName,
@@ -68,34 +71,39 @@ export const ModulesPage: React.FC = () => {
};
return (
-
+
{/* Header */}
-
+
-
-
+
+
Каталог модулей и Rollout конвейер
-
- Управление манифестами, compatibility core/schema, пилотными организациями и фазовыми релизами
+
+ Управление версиями модулей, совместимостью с ядром, пилотными группами и канареечным развертыванием
-
- Всего модулей:
{modules.length} • Активных раскаток:{' '}
-
{rollouts.length}
+
+
+ Всего модулей: {modules.length}
+
+
+ Активных раскаток: {rollouts.length}
+
{/* Grid: Module Selector + Module Detail & Rollout Manager */}
-
+
{/* Left Column: Modules Catalog List */}
-
-
+
+
Каталог системных модулей
-
+ {/* Module list with min 44px items */}
+
{modules.map((m) => {
const isSelected = m.moduleId === selectedModuleId;
const hasRollout = rollouts.some((r) => r.moduleId === m.moduleId);
@@ -104,24 +112,24 @@ export const ModulesPage: React.FC = () => {
setSelectedModuleId(m.moduleId)}
- className={`p-3 rounded-lg border text-xs cursor-pointer transition-colors space-y-1.5 ${
+ className={`min-h-[44px] p-3 rounded-lg border text-xs cursor-pointer transition-colors space-y-1.5 ${
isSelected
- ? 'bg-amber-500/15 border-amber-500/40 text-zinc-100'
- : 'bg-zinc-950/60 border-zinc-800 text-zinc-400 hover:bg-zinc-800/50 hover:text-zinc-200'
+ ? 'bg-amber-500/15 border-amber-500/40 text-krona-primary shadow-xs'
+ : 'bg-krona-workspace border-krona-border text-krona-secondary hover:bg-krona-surface hover:text-krona-primary'
}`}
>
- {m.name}
-
+ {m.name}
+
v{m.latestVersion}
-
{m.description}
-
-
Тенантов: {m.activeTenantsCount} • Инстансов: {m.instancesCount}
+
{m.description}
+
+ Организаций: {m.activeTenantsCount} • Установок: {m.instancesCount}
{hasRollout && (
-
- Rollout
+
+ Раскатка
)}
@@ -132,97 +140,115 @@ export const ModulesPage: React.FC = () => {
{/* Right 2 Columns: Module Details & Rollout Controller */}
-
+
{selectedModule && (
<>
{/* Module Header Card */}
-
-
+
+
-
-
{selectedModule.code}
-
•
-
Категория: {selectedModule.category}
+
+ {selectedModule.code}
+ •
+
+ Категория: {RU_MODULE_CATEGORY[selectedModule.category] || selectedModule.category}
+
-
{selectedModule.name}
-
{selectedModule.description}
+
{selectedModule.name}
+
{selectedModule.description}
-
-
Текущая стабильная версия:
-
v{selectedModule.latestVersion}
+
+
Текущая версия:
+
+ v{selectedModule.latestVersion}
+
-
-
-
Канал релиза:
-
{selectedModule.rolloutChannel}
+
+
+
Канал релиза:
+
{selectedModule.rolloutChannel}
-
-
Манифест:
-
v{selectedModule.manifestVersion}
+
+
Манифест:
+
v{selectedModule.manifestVersion}
-
-
Зависимости:
-
- {selectedModule.dependencies.length > 0 ? selectedModule.dependencies.join(', ') : 'Нет (Базовый)'}
+
+
Зависимости:
+
+ {selectedModule.dependencies.length > 0 ? selectedModule.dependencies.join(', ') : 'Базовый'}
- {/* Rollout Control Panel (Сценарий 8) */}
-
-
+ {/* Rollout Control Panel */}
+
+
-
-
Управление раскаткой (Rollout Pipeline)
+
+
+ Управление конвейером раскатки (Rollout)
+
- {activeRollout &&
}
+ {activeRollout && (
+
+ )}
{activeRollout ? (
{/* Progress visualizer */}
-
+
-
- Целевая версия: v{activeRollout.targetVersion}
+
+ Целевая версия:{' '}
+ v{activeRollout.targetVersion}
- {activeRollout.percentage}%
+ {activeRollout.percentage}%
-
+
-
-
Стадия: {activeRollout.stage}
+
+
+ Стадия:{' '}
+
+ {RU_ROLLOUT_STAGE[activeRollout.stage] || activeRollout.stage}
+
+
Пилотных организаций: {activeRollout.pilotTenantIds.length}
Старт: {new Date(activeRollout.startedAt).toLocaleDateString('ru-RU')}
- {/* Rollout Action Buttons */}
+ {/* Rollout Action Buttons with min 44px touch targets */}
@@ -231,7 +257,7 @@ export const ModulesPage: React.FC = () => {
type="button"
disabled={!permissions.canTriggerRollouts || activeRollout.stage === 'general_availability'}
onClick={() => handleStageChange('general_availability', 100)}
- className="px-3 py-1.5 rounded-lg bg-emerald-950 text-emerald-300 border border-emerald-700 hover:bg-emerald-900 text-xs font-bold disabled:opacity-40 transition-colors"
+ className="min-h-[44px] px-4 py-2 rounded-lg bg-emerald-500/15 text-emerald-600 dark:text-emerald-300 border border-emerald-500/40 hover:bg-emerald-500/25 text-xs font-bold disabled:opacity-40 transition-colors shadow-xs"
>
Фаза 3: Полный релиз (100% GA)
@@ -241,19 +267,19 @@ export const ModulesPage: React.FC = () => {
type="button"
disabled={!permissions.canPauseRollbackRollouts}
onClick={() => handleStageChange('paused', activeRollout.percentage)}
- className="px-3 py-1.5 rounded-lg bg-amber-950/70 text-amber-300 border border-amber-700 hover:bg-amber-900/60 text-xs font-bold disabled:opacity-40 transition-colors flex items-center gap-1.5"
+ className="min-h-[44px] px-3.5 py-2 rounded-lg bg-amber-500/15 text-amber-600 dark:text-amber-300 border border-amber-500/40 hover:bg-amber-500/25 text-xs font-bold disabled:opacity-40 transition-colors flex items-center gap-1.5 shadow-xs"
>
-
-
Поставить на паузу
+
+
На паузу
) : (
)}
@@ -262,47 +288,50 @@ export const ModulesPage: React.FC = () => {
type="button"
disabled={!permissions.canPauseRollbackRollouts || activeRollout.stage === 'rolled_back'}
onClick={() => handleStageChange('rolled_back', 0)}
- className="px-3 py-1.5 rounded-lg bg-rose-950 text-rose-300 border border-rose-700 hover:bg-rose-900 text-xs font-bold disabled:opacity-40 transition-colors flex items-center gap-1.5"
+ className="min-h-[44px] px-3.5 py-2 rounded-lg bg-rose-500/15 text-rose-600 dark:text-rose-300 border border-rose-500/40 hover:bg-rose-500/25 text-xs font-bold disabled:opacity-40 transition-colors flex items-center gap-1.5 shadow-xs"
>
-
-
Rollback (Откат)
+
+
Откат (Rollback)
) : (
-
-
- Для модуля {selectedModule.name} нет активных раскаток.
- Вы можете запустить пилотный релиз новой версии.
+
+
+ Для модуля {selectedModule.name} нет активных раскаток.
+ Вы можете запустить пилотный релиз новой версии для проверки совместимости.
)}
{/* Release History & Deployments */}
-
-
История релизов и совместимость (Compatibility)
+
+
+
+ История релизов и совместимость
+
{selectedModule.releaseHistory.map((rel) => (
-
+
- v{rel.version}
-
+ v{rel.version}
+
{new Date(rel.releasedAt).toLocaleDateString('ru-RU')}
-
{rel.changelog}
-
- Совместимость с Core: {rel.compatibleCore}
+
{rel.changelog}
+
+ Совместимость с ядром: {rel.compatibleCore}
))}
@@ -315,3 +344,4 @@ export const ModulesPage: React.FC = () => {
);
};
+