Fix widget gap: forward-fill months and use reference month date for batch update
BatchUpdateView now accepts a saveDate parameter. When saving from a past-month check-in, the call site passes referenceDate.endOfMonth so snapshots are dated within the correct month instead of today. For the current month, Date() is used. Widget forward-fills missing month buckets (trend and category series) using the most recent earlier month's value, preventing gaps when a check-in is done in the following month. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -154,7 +154,8 @@ struct MonthlyCheckInView: View {
|
|||||||
.sheet(isPresented: $showBatchUpdate) {
|
.sheet(isPresented: $showBatchUpdate) {
|
||||||
viewModel.refresh()
|
viewModel.refresh()
|
||||||
} content: {
|
} content: {
|
||||||
BatchUpdateView(sources: viewModel.sources)
|
let batchSaveDate = referenceDate.isSameMonth(as: Date()) ? Date() : referenceDate.endOfMonth
|
||||||
|
BatchUpdateView(sources: viewModel.sources, saveDate: batchSaveDate)
|
||||||
}
|
}
|
||||||
.onChange(of: starRating) { _, newValue in
|
.onChange(of: starRating) { _, newValue in
|
||||||
MonthlyCheckInStore.setRating(newValue == 0 ? nil : newValue, for: referenceDate)
|
MonthlyCheckInStore.setRating(newValue == 0 ? nil : newValue, for: referenceDate)
|
||||||
@@ -945,10 +946,16 @@ struct AchievementMilestoneBar: View {
|
|||||||
struct BatchUpdateView: View {
|
struct BatchUpdateView: View {
|
||||||
@Environment(\.dismiss) private var dismiss
|
@Environment(\.dismiss) private var dismiss
|
||||||
let sources: [InvestmentSource]
|
let sources: [InvestmentSource]
|
||||||
|
let saveDate: Date
|
||||||
@State private var values: [UUID: String] = [:]
|
@State private var values: [UUID: String] = [:]
|
||||||
@State private var contributions: [UUID: String] = [:]
|
@State private var contributions: [UUID: String] = [:]
|
||||||
@State private var savedCount = 0
|
@State private var savedCount = 0
|
||||||
|
|
||||||
|
init(sources: [InvestmentSource], saveDate: Date = Date()) {
|
||||||
|
self.sources = sources
|
||||||
|
self.saveDate = saveDate
|
||||||
|
}
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
NavigationStack {
|
NavigationStack {
|
||||||
List {
|
List {
|
||||||
@@ -1080,7 +1087,7 @@ struct BatchUpdateView: View {
|
|||||||
|
|
||||||
repository.createSnapshot(
|
repository.createSnapshot(
|
||||||
for: source,
|
for: source,
|
||||||
date: Date(),
|
date: saveDate,
|
||||||
value: parsed,
|
value: parsed,
|
||||||
contribution: parsedContribution
|
contribution: parsedContribution
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -264,7 +264,12 @@ struct InvestmentWidgetProvider: TimelineProvider {
|
|||||||
}
|
}
|
||||||
let monthFormatter = DateFormatter()
|
let monthFormatter = DateFormatter()
|
||||||
monthFormatter.dateFormat = "MMM"
|
monthFormatter.dateFormat = "MMM"
|
||||||
trendPoints = months.map { monthlyTotals[$0] ?? .zero }
|
trendPoints = months.map { month in
|
||||||
|
if let value = monthlyTotals[month] { return value }
|
||||||
|
// Forward-fill: use the most recent earlier month's value
|
||||||
|
let previous = sortedMonths.last { $0.0 < month }
|
||||||
|
return previous?.1 ?? .zero
|
||||||
|
}
|
||||||
trendLabels = months.map { monthFormatter.string(from: $0) }
|
trendLabels = months.map { monthFormatter.string(from: $0) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -307,7 +312,13 @@ struct InvestmentWidgetProvider: TimelineProvider {
|
|||||||
|
|
||||||
let categoryEvolution: [CategorySeries] = categoryTotalsData.prefix(4).map { category in
|
let categoryEvolution: [CategorySeries] = categoryTotalsData.prefix(4).map { category in
|
||||||
let monthMap = categoryMonthlyTotals[category.id] ?? [:]
|
let monthMap = categoryMonthlyTotals[category.id] ?? [:]
|
||||||
let points = months.map { monthMap[$0] ?? .zero }
|
let sortedCategoryMonths = monthMap.map { ($0.key, $0.value) }.sorted { $0.0 < $1.0 }
|
||||||
|
let points = months.map { month -> Decimal in
|
||||||
|
if let value = monthMap[month] { return value }
|
||||||
|
// Forward-fill: use the most recent earlier month's value
|
||||||
|
let previous = sortedCategoryMonths.last { $0.0 < month }
|
||||||
|
return previous?.1 ?? .zero
|
||||||
|
}
|
||||||
return CategorySeries(
|
return CategorySeries(
|
||||||
id: category.id,
|
id: category.id,
|
||||||
name: category.name,
|
name: category.name,
|
||||||
|
|||||||
Reference in New Issue
Block a user