| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071 |
- //
- // Project.swift
- // Todos
- //
- // Created by Sam Jaffe on 2/28/26.
- //
- import Foundation
- import SwiftData
- import SwiftUI
- @Model
- final class Project: Codable, Ordered, Aggregate {
- typealias Element = Task
- var sortOrder: Int = 0
- var timestamp: Date
- var name: String = "New Project"
- var category: String = ""
- @Relationship(deleteRule: .cascade, inverse: \Task.project)
- var tasks: [Task] = []
- init(timestamp: Date) {
- self.timestamp = timestamp
- }
- func move(fromOffsets: IndexSet, toOffset: Int) {
- tasks.move(fromOffsets: fromOffsets, toOffset: toOffset)
- reindex()
- }
- func remove(_ item: Element) {
- tasks.removeAll(where: { $0.id == item.id })
- reindex()
- }
- func reindex() {
- for (index, item) in tasks.enumerated() {
- item.sortOrder = index
- }
- }
- func yaml(_ indent: Int = 0) -> String {
- let hdr = String(repeating: " ", count: indent)
- var rval = hdr + "\(name):\n"
- if !category.isEmpty {
- rval += hdr + " # In Category: \(category)\n"
- }
- rval += tasks.map({ $0.yaml(indent + 1) }).joined()
- return rval
- }
- enum CodingKeys: CodingKey { case timestamp, category, name, tasks }
- required init(from decoder: any Decoder) throws {
- let container = try decoder.container(keyedBy: CodingKeys.self)
- timestamp = try container.decode(Date.self, forKey: .timestamp)
- category = try container.decode(String.self, forKey: .category)
- name = try container.decode(String.self, forKey: .name)
- tasks = try container.decode([Task].self, forKey: .tasks)
- tasks.forEach({ $0.project = self })
- }
- func encode(to encoder: any Encoder) throws {
- var container = encoder.container(keyedBy: CodingKeys.self)
- try container.encode(timestamp, forKey: .timestamp)
- try container.encode(category, forKey: .category)
- try container.encode(tasks, forKey: .tasks)
- try container.encode(name, forKey: .name)
- }
- }
|