Goals por categoría: ámbito de categoría en objetivos (build 88) #46
Un Goal ya podía acotarse por cuenta; ahora también por categoría de fuente, de modo que se puede fijar "100.000 € en Cash" y que el progreso cuente solo las fuentes de esa categoría. - CoreData: relación Goal.category ↔ Category.goals (opcional, Nullify) - Goal.includes(_:)/relevantSources(from:)/scopeKey centralizan el filtro de ámbito (cuenta Y categoría) que antes estaba duplicado en GoalsViewModel, AddSourceView y NotificationService - GoalEditorView: sección "Ámbito" con selector de categoría - Chip de categoría en la lista de Goals y en la tarjeta del Dashboard - ETA del Dashboard para goals con ámbito: usa la proyección del propio goal en vez de la evolución global de la cartera (que daría "objetivo alcanzado" en cuanto la cartera total superara el importe) - GoalRepository e ImportService deduplican por (nombre, cuenta, categoría) - Export/Import de goals incluye "category" - Nuevas claves localizadas en los 7 idiomas Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YcDn5ccuRFV83q7xWWokBT
This commit is contained in:
@@ -403,7 +403,14 @@ struct DashboardView: View {
|
||||
paceStatusProvider: goalsViewModel.paceStatus(for:),
|
||||
etaProvider: { goal in
|
||||
let currentValue = goalsViewModel.totalValue(for: goal)
|
||||
return viewModel.goalEtaText(for: goal, currentValue: currentValue)
|
||||
guard goal.account != nil || goal.category != nil else {
|
||||
return viewModel.goalEtaText(for: goal, currentValue: currentValue)
|
||||
}
|
||||
return viewModel.goalEtaText(
|
||||
for: goal,
|
||||
currentValue: currentValue,
|
||||
projection: goalsViewModel.projection(for: goal)
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -1576,8 +1583,19 @@ struct GoalsSummaryCard: View {
|
||||
lineWidth: 5
|
||||
)
|
||||
VStack(alignment: .leading, spacing: 3) {
|
||||
Text(goal.name)
|
||||
.font(.subheadline.weight(.semibold))
|
||||
HStack(spacing: 6) {
|
||||
Text(goal.name)
|
||||
.font(.subheadline.weight(.semibold))
|
||||
if let category = goal.category {
|
||||
HStack(spacing: 3) {
|
||||
Image(systemName: category.icon)
|
||||
.font(.system(size: 9))
|
||||
Text(category.name)
|
||||
.font(.caption2.weight(.semibold))
|
||||
}
|
||||
.foregroundColor(category.color)
|
||||
}
|
||||
}
|
||||
HStack(spacing: 4) {
|
||||
Text(currentValue.compactCurrencyString)
|
||||
.font(.caption.weight(.semibold))
|
||||
|
||||
Reference in New Issue
Block a user