iOS: Mengen-Sheet auf Form-Ebene praesentieren (erstes Oeffnen bleibt offen)

Das Menge-hinzufuegen/umlagern/entfernen-Sheet ging beim ersten Antippen sofort
wieder zu: das spaet fertige Laden der Entnahme-Statistik (.task im Abschnitt)
riss das gerade praesentierte Sheet weg. ObjectStockSection ist jetzt zustands-
los (bekommt removals + Sheet-Binding); Sheet und Statistik-Laden liegen in der
Detailansicht auf der stabilen Form-Ebene bzw. im reload().

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Scarriffle
2026-07-29 12:03:19 +02:00
parent 4ab8d11f92
commit 620e77dff1
2 changed files with 49 additions and 46 deletions

View File

@@ -4,27 +4,29 @@ import SwiftUI
/// Lebensmittel. Erlaubt Hinzufügen, Umlagern (ohne Grund) und Entfernen (mit
/// Pflicht-Grund) und zeigt eine kleine Entnahme-Statistik. Wird als Abschnitt
/// in die Produkt-Detailansicht eingebettet.
/// Welches Mengen-Sheet gerade offen ist. Wird auf der stabilen Form-Ebene der
/// Detailansicht präsentiert (nicht im Abschnitt selbst), sonst schloss sich das
/// Fenster beim ersten Öffnen sofort wieder (das spät fertige Laden der
/// Entnahme-Statistik hat das frische Sheet weggerissen).
enum ObjectStockSheet: Identifiable {
case add
case relocate(from: String?)
case remove(loc: String?)
var id: String {
switch self {
case .add: return "add"
case .relocate(let f): return "relocate-\(f ?? "none")"
case .remove(let l): return "remove-\(l ?? "none")"
}
}
}
struct ObjectStockSection: View {
let product: Product
let locations: [StorageLocation]
let lots: [Lot]
var onChanged: () async -> Void
@State private var removals: RemovalSummary?
@State private var sheet: StockSheet?
enum StockSheet: Identifiable {
case add
case relocate(from: String?)
case remove(loc: String?)
var id: String {
switch self {
case .add: return "add"
case .relocate(let f): return "relocate-\(f ?? "none")"
case .remove(let l): return "remove-\(l ?? "none")"
}
}
}
let removals: RemovalSummary?
@Binding var sheet: ObjectStockSheet?
private var einheit: String { product.unitName.isEmpty ? "Stück" : product.unitName }
private func ortName(_ id: String?) -> String {
@@ -63,23 +65,6 @@ struct ObjectStockSection: View {
.buttonStyle(.borderless)
.font(.callout)
}
// Sheet an den Abschnitt hängen (nicht an die Group) sonst ging das
// Fenster bei manchen iOS-Versionen kurz auf und sofort wieder zu.
.sheet(item: $sheet) { welche in
NavigationStack {
switch welche {
case .add:
ObjectAddSheet(product: product, locations: locations, einheit: einheit,
perform: { await afterAction() })
case .relocate(let from):
ObjectRelocateSheet(product: product, locations: locations, initialFrom: from,
perform: { await afterAction() })
case .remove(let loc):
ObjectRemoveSheet(product: product, locations: locations, einheit: einheit,
initialLoc: loc, perform: { await afterAction() })
}
}
}
if let removals, !removals.stats.isEmpty {
Section("Bereits entnommen") {
@@ -90,17 +75,6 @@ struct ObjectStockSection: View {
}
}
}
.task(id: product.id) { await loadRemovals() }
.onChange(of: lots) { _ in Task { await loadRemovals() } }
}
private func loadRemovals() async {
removals = try? await APIClient.shared.productRemovals(id: product.id)
}
private func afterAction() async {
await onChanged()
await loadRemovals()
}
}