79ff60ffd9
ErrorView 320→178 (+ ErrorBrand 54 + ErrorIllustration 31 + ErrorActions 55 + ErrorMeta 102).
DashboardView 302→84 (+ DashboardPageHead 65 + DashboardKpiRow 97 + DashboardBalance 124).
State (config, errorCode в ErrorView; range/kpis/balance в DashboardView) остаётся
в parent ради единого route.meta-driven flow + future API-fetch'а (Phase B/1 паттерн).
DashboardPageHead использует Vue 3.5 defineModel<T>() для двусторонней привязки range.
Sub-components читают только props — без Pinia stores (mock-data flow).
Все sub-components <250 строк (acceptance threshold). Shell line counts: 178/84.
ЗАМЕЧАНИЕ по acceptance «0 components >300»: НЕ закрыто полностью. 2 файла остались
выше порога — DealsView 560 + DealDetailDrawer 386. Зафиксировано в Sprint 3 Phase C
commit 6c2f0ce: bulk-action функции (applyBulkStatus/applyBulkDelete/applyBulkExport/
undoBulkDelete/applyBulkRestoreFromTrash) и comment/reminders fetch экспонируются
через defineExpose в Vitest-тестах напрямую — дальнейшая декомпозиция требует
изменения тест-контракта (отдельным flow, не вошло в Sprint 4 Phase B).
Phase B/3 закрывает 8/12 audit-кандидатов O-refactor-04: 3 в Sprint 3 Phase C
(Top-3) + 5 в Sprint 4 Phase B/1+B/2 (admin/layout/billing/security/reminders) +
2 в B/3 (errors/dashboard). Оставшиеся: 2 крупных deals-view (defineExpose-blocked)
+ ImpersonationDialog уже <300 органически.
Регрессия: ESLint 0 + vue-tsc 0 + Vitest 416/416 + build OK 989 ms.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
56 lines
1.4 KiB
Vue
56 lines
1.4 KiB
Vue
<script setup lang="ts">
|
|
/**
|
|
* ErrorActions — две кнопки (primary + опциональная secondary) для ErrorView.
|
|
* Принимает action-объекты как props; click на handler делегирует через
|
|
* вызов action.onClick() (router-link / href обрабатывается Vuetify-биндингами).
|
|
*
|
|
* Sprint 4 Phase B/3 — split ErrorView (audit O-refactor-04 закрытие).
|
|
*/
|
|
interface ErrorAction {
|
|
label: string;
|
|
icon: string;
|
|
to?: string;
|
|
href?: string;
|
|
onClick?: () => void;
|
|
}
|
|
|
|
defineProps<{
|
|
primary: ErrorAction;
|
|
secondary?: ErrorAction;
|
|
}>();
|
|
</script>
|
|
|
|
<template>
|
|
<div class="err-actions">
|
|
<v-btn
|
|
color="primary"
|
|
variant="flat"
|
|
:prepend-icon="primary.icon"
|
|
:to="primary.to"
|
|
@click="primary.onClick?.()"
|
|
>
|
|
{{ primary.label }}
|
|
</v-btn>
|
|
<v-btn
|
|
v-if="secondary"
|
|
variant="outlined"
|
|
:prepend-icon="secondary.icon"
|
|
:to="secondary.to"
|
|
:href="secondary.href"
|
|
@click="secondary.onClick?.()"
|
|
>
|
|
{{ secondary.label }}
|
|
</v-btn>
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.err-actions {
|
|
display: flex;
|
|
gap: 12px;
|
|
margin-bottom: 24px;
|
|
flex-wrap: wrap;
|
|
justify-content: center;
|
|
}
|
|
</style>
|