import SwiftUI import SwiftData struct EntityListView: View { @Environment(\.modelContext) private var modelContext @Query var items: [T] @State private var showingAddSheet = false @State private var itemToEdit: T? = nil @State private var itemToDelete: T? = nil private var sortDescriptors: [SortDescriptor] init(sort: [SortDescriptor] = [], searchString: String = "") { self.sortDescriptors = sort _items = Query(filter: #Predicate { item in if searchString.isEmpty { return true } else { return item.name.localizedStandardContains(searchString) } }, sort: sort) } @State private var isInsideNavigationStack: Bool = false var body: some View { let content = Form { List { ForEach(items) { item in ListItem(title: item.name, count: item.count) .swipeActions(edge: .trailing, allowsFullSwipe: false) { Button(role: .destructive) { itemToDelete = item } label: { Label("Delete", systemImage: "trash") } Button { itemToEdit = item } label: { Label("Edit", systemImage: "pencil") } .tint(.indigo) } } } } .navigationTitle(T.navigationTitle) .toolbar { ToolbarItem(placement: .navigationBarTrailing) { Button(action: { showingAddSheet.toggle() }) { Image(systemName: "plus") } } } .sheet(isPresented: $showingAddSheet) { T.formView(for: T.createNew()) } .sheet(item: $itemToEdit) { item in T.formView(for: item) } .confirmationDialog( "Delete?", isPresented: Binding( get: { itemToDelete != nil }, set: { if !$0 { itemToDelete = nil } } ), titleVisibility: .visible ) { Button("Delete", role: .destructive) { if let item = itemToDelete { modelContext.delete(item) try? modelContext.save() itemToDelete = nil } } Button("Cancel", role: .cancel) { itemToDelete = nil } } message: { Text("Are you sure you want to delete \(itemToDelete?.name ?? "this item")?") } .background( NavigationStackChecker(isInside: $isInsideNavigationStack) ) if isInsideNavigationStack { content } else { NavigationStack { content } } } }