Group tasks feature (#3)
This PR contains the work done to implement the **Group Task** feature, and to integrate it into the main content view of the app. Furthermore, an issue related to triggering a view update after inserting the todo tasks into the model container has been fixed. Reviewed-on: rock-n-code/todos-app#3 Co-authored-by: Javier Cicchelli <javier@rock-n-code.com> Co-committed-by: Javier Cicchelli <javier@rock-n-code.com>
This commit was merged in pull request #3.
This commit is contained in:
@@ -0,0 +1,131 @@
|
||||
import SwiftData
|
||||
import SwiftUI
|
||||
|
||||
/// A preview modifier that provides sample task data for SwiftUI previews.
|
||||
///
|
||||
/// This modifier creates an in-memory SwiftData model container populated with representative sample todos across all task groups
|
||||
/// (today, upcoming, overdue, completed).
|
||||
/// It's designed to be used with SwiftUI previews to display realistic data without
|
||||
/// requiring a persistent database.
|
||||
///
|
||||
/// ## Usage
|
||||
/// Use the `.sampleTasks` trait on your preview:
|
||||
///
|
||||
/// ```swift
|
||||
/// #Preview(traits: .sampleTasks) {
|
||||
/// TaskGroupListView()
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// This automatically provides a model container with sample data to the preview.
|
||||
struct SampleTaskDataModifier: PreviewModifier {
|
||||
|
||||
// MARK: Functions
|
||||
|
||||
/// Creates and configures a shared in-memory model container with sample task data.
|
||||
///
|
||||
/// This method is called once when the preview is loaded and creates an in-memory
|
||||
/// SwiftData container populated with 8 representative todo tasks spanning all
|
||||
/// task groups and various configurations.
|
||||
///
|
||||
/// - Returns: A `ModelContainer` configured for in-memory storage with sample data.
|
||||
/// - Throws: An error if the model container cannot be created.
|
||||
static func makeSharedContext() async throws -> ModelContainer {
|
||||
let modelContainer = try ModelContainer(
|
||||
for: Todo.self,
|
||||
configurations: .init(isStoredInMemoryOnly: true)
|
||||
)
|
||||
|
||||
let calendar: Calendar = .current
|
||||
let today: Date = .now
|
||||
let tomorrow: Date = calendar.date(byAdding: .day, value: 1, to: today) ?? today
|
||||
let yesterday = calendar.date(byAdding: .day, value: -1, to: today) ?? today
|
||||
|
||||
let tasks: [Todo] = [
|
||||
.init(
|
||||
title: "Today task 1",
|
||||
due: today
|
||||
),
|
||||
.init(
|
||||
title: "Today task 2",
|
||||
note: "This is some random note attached to the task.",
|
||||
due: today
|
||||
),
|
||||
.init(
|
||||
title: "Tomorrow task",
|
||||
due: tomorrow
|
||||
),
|
||||
.init(
|
||||
title: "Next week task",
|
||||
note: "This is some random note attached to the task.",
|
||||
due: calendar.date(byAdding: .day, value: 7, to: today) ?? today
|
||||
),
|
||||
.init(
|
||||
title: "Yesterday task",
|
||||
due: yesterday
|
||||
),
|
||||
.init(
|
||||
title: "Last week task",
|
||||
note: "This is some random note attached to the task.",
|
||||
due: calendar.date(byAdding: .day, value: -7, to: today) ?? today
|
||||
),
|
||||
.init(
|
||||
title: "Completed task 1",
|
||||
due: today,
|
||||
completed: today
|
||||
),
|
||||
.init(
|
||||
title: "Completed task 2",
|
||||
note: "This is some random note attached to the task.",
|
||||
due: yesterday,
|
||||
completed: today
|
||||
),
|
||||
]
|
||||
|
||||
for task in tasks {
|
||||
modelContainer.mainContext.insert(task)
|
||||
}
|
||||
|
||||
return modelContainer
|
||||
}
|
||||
|
||||
/// Applies the model container to the preview content.
|
||||
///
|
||||
/// This method is called by SwiftUI to apply the modifier to the preview.
|
||||
/// It injects the model container into the SwiftUI environment, making it
|
||||
/// available to any views that use `@Query` or `@Environment(\.modelContext)`.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - content: The preview content to modify.
|
||||
/// - context: The model container with sample data.
|
||||
/// - Returns: The content with the model container applied.
|
||||
func body(
|
||||
content: Content,
|
||||
context: ModelContainer
|
||||
) -> some View {
|
||||
content.modelContainer(context)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - PreviewTrait
|
||||
|
||||
extension PreviewTrait where T == Preview.ViewTraits {
|
||||
|
||||
/// A preview trait that provides sample task data.
|
||||
///
|
||||
/// Use this trait to automatically populate previews with realistic sample todos
|
||||
/// without manually creating a model container and inserting data.
|
||||
///
|
||||
/// ## Example
|
||||
/// ```swift
|
||||
/// #Preview(traits: .sampleTasks) {
|
||||
/// TaskGroupListView()
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// This is equivalent to manually creating a container with sample data but
|
||||
/// much more concise and reusable across multiple previews.
|
||||
static var sampleTasks: Self = .modifier(SampleTaskDataModifier())
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user