From 13c4bb33b553b9243d227847c936c065e73c2e9d Mon Sep 17 00:00:00 2001 From: Michael Housh Date: Fri, 16 Jan 2026 11:40:21 -0500 Subject: [PATCH] feat: Reorganizes / creates duct sizes container, uses it in views and projectClient. --- .../{DuctSizing.swift => DuctSizes.swift} | 26 ++++++++---- Sources/ProjectClient/Interface.swift | 19 ++------- .../DatabaseClient+calculateDuctSizes.swift | 6 +-- .../ManualDClient+calculateDuctSizes.swift | 20 +++++----- Sources/ViewController/Live.swift | 18 +++++---- .../Views/DuctSizing/DuctSizingView.swift | 15 ++++--- .../DuctSizing/RectangularSizeForm.swift | 6 +-- .../Views/DuctSizing/RoomsTable.swift | 6 +-- .../Views/DuctSizing/TrunkSizeForm.swift | 12 +++--- .../Views/DuctSizing/TrunksTable.swift | 13 +++--- Sources/ViewController/Views/TestPage.swift | 40 +++++++++---------- 11 files changed, 90 insertions(+), 91 deletions(-) rename Sources/ManualDCore/{DuctSizing.swift => DuctSizes.swift} (83%) diff --git a/Sources/ManualDCore/DuctSizing.swift b/Sources/ManualDCore/DuctSizes.swift similarity index 83% rename from Sources/ManualDCore/DuctSizing.swift rename to Sources/ManualDCore/DuctSizes.swift index 36f31d0..94c932c 100644 --- a/Sources/ManualDCore/DuctSizing.swift +++ b/Sources/ManualDCore/DuctSizes.swift @@ -1,7 +1,21 @@ import Dependencies import Foundation -public enum DuctSizing { +public struct DuctSizes: Codable, Equatable, Sendable { + + public let rooms: [RoomContainer] + public let trunks: [TrunkContainer] + + public init( + rooms: [DuctSizes.RoomContainer], + trunks: [DuctSizes.TrunkContainer] + ) { + self.rooms = rooms + self.trunks = trunks + } +} + +extension DuctSizes { public struct SizeContainer: Codable, Equatable, Sendable { @@ -16,7 +30,7 @@ public enum DuctSizing { public init( rectangularID: Room.RectangularSize.ID? = nil, - designCFM: DuctSizing.DesignCFM, + designCFM: DuctSizes.DesignCFM, roundSize: Double, finalSize: Int, velocity: Int, @@ -35,8 +49,6 @@ public enum DuctSizing { } } - // TODO: Uses SizeContainer - @dynamicMemberLookup public struct RoomContainer: Codable, Equatable, Sendable { @@ -69,7 +81,7 @@ public enum DuctSizing { self.ductSize = ductSize } - public subscript(dynamicMember keyPath: KeyPath) -> T { + public subscript(dynamicMember keyPath: KeyPath) -> T { ductSize[keyPath: keyPath] } } @@ -95,7 +107,7 @@ public enum DuctSizing { } } -extension DuctSizing { +extension DuctSizes { // Represents the database model that the duct sizes have been calculated // for. @@ -118,7 +130,7 @@ extension DuctSizing { trunk[keyPath: keyPath] } - public subscript(dynamicMember keyPath: KeyPath) -> T { + public subscript(dynamicMember keyPath: KeyPath) -> T { ductSize[keyPath: keyPath] } } diff --git a/Sources/ProjectClient/Interface.swift b/Sources/ProjectClient/Interface.swift index 9d85847..e9f2d13 100644 --- a/Sources/ProjectClient/Interface.swift +++ b/Sources/ProjectClient/Interface.swift @@ -16,11 +16,11 @@ extension DependencyValues { /// for the view controller client to render views. @DependencyClient public struct ProjectClient: Sendable { - public var calculateDuctSizes: @Sendable (Project.ID) async throws -> DuctSizeResponse + public var calculateDuctSizes: @Sendable (Project.ID) async throws -> DuctSizes public var calculateRoomDuctSizes: - @Sendable (Project.ID) async throws -> [DuctSizing.RoomContainer] + @Sendable (Project.ID) async throws -> [DuctSizes.RoomContainer] public var calculateTrunkDuctSizes: - @Sendable (Project.ID) async throws -> [DuctSizing.TrunkContainer] + @Sendable (Project.ID) async throws -> [DuctSizes.TrunkContainer] public var createProject: @Sendable (User.ID, Project.Create) async throws -> CreateProjectResponse @@ -54,19 +54,6 @@ extension ProjectClient { } } - public struct DuctSizeResponse: Codable, Equatable, Sendable { - public let rooms: [DuctSizing.RoomContainer] - public let trunks: [DuctSizing.TrunkContainer] - - public init( - rooms: [DuctSizing.RoomContainer], - trunks: [DuctSizing.TrunkContainer] - ) { - self.rooms = rooms - self.trunks = trunks - } - } - public struct FrictionRateResponse: Codable, Equatable, Sendable { public let componentLosses: [ComponentPressureLoss] diff --git a/Sources/ProjectClient/Internal/DatabaseClient+calculateDuctSizes.swift b/Sources/ProjectClient/Internal/DatabaseClient+calculateDuctSizes.swift index 50c965a..1380283 100644 --- a/Sources/ProjectClient/Internal/DatabaseClient+calculateDuctSizes.swift +++ b/Sources/ProjectClient/Internal/DatabaseClient+calculateDuctSizes.swift @@ -7,7 +7,7 @@ extension DatabaseClient { func calculateDuctSizes( projectID: Project.ID - ) async throws -> ProjectClient.DuctSizeResponse { + ) async throws -> DuctSizes { @Dependency(\.manualD) var manualD return try await manualD.calculateDuctSizes( @@ -19,7 +19,7 @@ extension DatabaseClient { func calculateRoomDuctSizes( projectID: Project.ID - ) async throws -> [DuctSizing.RoomContainer] { + ) async throws -> [DuctSizes.RoomContainer] { @Dependency(\.manualD) var manualD return try await manualD.calculateRoomSizes( @@ -30,7 +30,7 @@ extension DatabaseClient { func calculateTrunkDuctSizes( projectID: Project.ID - ) async throws -> [DuctSizing.TrunkContainer] { + ) async throws -> [DuctSizes.TrunkContainer] { @Dependency(\.manualD) var manualD return try await manualD.calculateTrunkSizes( diff --git a/Sources/ProjectClient/Internal/ManualDClient+calculateDuctSizes.swift b/Sources/ProjectClient/Internal/ManualDClient+calculateDuctSizes.swift index c09f78b..effc1e0 100644 --- a/Sources/ProjectClient/Internal/ManualDClient+calculateDuctSizes.swift +++ b/Sources/ProjectClient/Internal/ManualDClient+calculateDuctSizes.swift @@ -19,7 +19,7 @@ extension ManualDClient { trunks: [TrunkSize], sharedRequest: DuctSizeSharedRequest, logger: Logger? = nil - ) async throws -> ProjectClient.DuctSizeResponse { + ) async throws -> DuctSizes { try await .init( rooms: calculateRoomSizes( rooms: rooms, @@ -37,9 +37,9 @@ extension ManualDClient { rooms: [Room], sharedRequest: DuctSizeSharedRequest, logger: Logger? = nil - ) async throws -> [DuctSizing.RoomContainer] { + ) async throws -> [DuctSizes.RoomContainer] { - var retval: [DuctSizing.RoomContainer] = [] + var retval: [DuctSizes.RoomContainer] = [] let totalHeatingLoad = rooms.totalHeatingLoad let totalCoolingSensible = rooms.totalCoolingSensible(shr: sharedRequest.projectSHR) @@ -50,7 +50,7 @@ extension ManualDClient { let coolingPercent = coolingLoad / totalCoolingSensible let heatingCFM = heatingPercent * Double(sharedRequest.equipmentInfo.heatingCFM) let coolingCFM = coolingPercent * Double(sharedRequest.equipmentInfo.coolingCFM) - let designCFM = DuctSizing.DesignCFM(heating: heatingCFM, cooling: coolingCFM) + let designCFM = DuctSizes.DesignCFM(heating: heatingCFM, cooling: coolingCFM) let sizes = try await self.ductSize( .init(designCFM: Int(designCFM.value), frictionRate: sharedRequest.designFrictionRate) ) @@ -96,9 +96,9 @@ extension ManualDClient { trunks: [TrunkSize], sharedRequest: DuctSizeSharedRequest, logger: Logger? = nil - ) async throws -> [DuctSizing.TrunkContainer] { + ) async throws -> [DuctSizes.TrunkContainer] { - var retval = [DuctSizing.TrunkContainer]() + var retval = [DuctSizes.TrunkContainer]() let totalHeatingLoad = rooms.totalHeatingLoad let totalCoolingSensible = rooms.totalCoolingSensible(shr: sharedRequest.projectSHR) @@ -109,7 +109,7 @@ extension ManualDClient { let coolingPercent = coolingLoad / totalCoolingSensible let heatingCFM = heatingPercent * Double(sharedRequest.equipmentInfo.heatingCFM) let coolingCFM = coolingPercent * Double(sharedRequest.equipmentInfo.coolingCFM) - let designCFM = DuctSizing.DesignCFM(heating: heatingCFM, cooling: coolingCFM) + let designCFM = DuctSizes.DesignCFM(heating: heatingCFM, cooling: coolingCFM) let sizes = try await self.ductSize( .init(designCFM: Int(designCFM.value), frictionRate: sharedRequest.designFrictionRate) ) @@ -139,9 +139,9 @@ extension ManualDClient { } -extension DuctSizing.SizeContainer { +extension DuctSizes.SizeContainer { init( - designCFM: DuctSizing.DesignCFM, + designCFM: DuctSizes.DesignCFM, sizes: ManualDClient.DuctSizeResponse, height: Int?, width: Int? @@ -159,7 +159,7 @@ extension DuctSizing.SizeContainer { } init( - designCFM: DuctSizing.DesignCFM, + designCFM: DuctSizes.DesignCFM, sizes: ManualDClient.DuctSizeResponse, rectangularSize: Room.RectangularSize?, width: Int? diff --git a/Sources/ViewController/Live.swift b/Sources/ViewController/Live.swift index dd46031..6af672a 100644 --- a/Sources/ViewController/Live.swift +++ b/Sources/ViewController/Live.swift @@ -15,15 +15,17 @@ extension ViewController.Request { switch route { case .test: - let projectID = UUID(uuidString: "A9C20153-E2E5-4C65-B33F-4D8A29C63A7A")! + // let projectID = UUID(uuidString: "A9C20153-E2E5-4C65-B33F-4D8A29C63A7A")! return await view { await ResultView { - return ( - try await database.projects.getCompletedSteps(projectID), - try await projectClient.calculateDuctSizes(projectID) - ) - } onSuccess: { (_, result) in - TestPage(trunks: result.trunks, rooms: result.rooms) + + // return ( + // try await database.projects.getCompletedSteps(projectID), + // try await projectClient.calculateDuctSizes(projectID) + // ) + } onSuccess: { + TestPage() + // TestPage(trunks: result.trunks, rooms: result.rooms) } } case .login(let route): @@ -609,7 +611,7 @@ extension SiteRoute.View.ProjectRoute.DuctSizingRoute { ) } onSuccess: { (steps, ducts) in ProjectView(projectID: projectID, activeTab: .ductSizing, completedSteps: steps) { - DuctSizingView(rooms: ducts.rooms, trunks: ducts.trunks) + DuctSizingView(ductSizes: ducts) } } } diff --git a/Sources/ViewController/Views/DuctSizing/DuctSizingView.swift b/Sources/ViewController/Views/DuctSizing/DuctSizingView.swift index 1790490..9963508 100644 --- a/Sources/ViewController/Views/DuctSizing/DuctSizingView.swift +++ b/Sources/ViewController/Views/DuctSizing/DuctSizingView.swift @@ -7,8 +7,7 @@ struct DuctSizingView: HTML, Sendable { @Environment(ProjectViewValue.$projectID) var projectID - let rooms: [DuctSizing.RoomContainer] - let trunks: [DuctSizing.TrunkContainer] + let ductSizes: DuctSizes var body: some HTML { div(.class("space-y-4")) { @@ -21,13 +20,13 @@ struct DuctSizingView: HTML, Sendable { Must complete all the previous sections to display duct sizing calculations. """ ) - .hidden(when: rooms.count > 0) + .hidden(when: ductSizes.rooms.count > 0) .attributes(.class("text-error font-bold italic mt-4")) } } - if rooms.count != 0 { - RoomsTable(rooms: rooms) + if ductSizes.rooms.count != 0 { + RoomsTable(rooms: ductSizes.rooms) PageTitleRow { PageTitle { @@ -42,13 +41,13 @@ struct DuctSizingView: HTML, Sendable { .tooltip("Add trunk / runout") } - if trunks.count > 0 { - TrunkTable(trunks: trunks, rooms: rooms) + if ductSizes.trunks.count > 0 { + TrunkTable(ductSizes: ductSizes) } } - TrunkSizeForm(rooms: rooms, dismiss: true) + TrunkSizeForm(rooms: ductSizes.rooms, dismiss: true) } } diff --git a/Sources/ViewController/Views/DuctSizing/RectangularSizeForm.swift b/Sources/ViewController/Views/DuctSizing/RectangularSizeForm.swift index 8cae9dc..9142285 100644 --- a/Sources/ViewController/Views/DuctSizing/RectangularSizeForm.swift +++ b/Sources/ViewController/Views/DuctSizing/RectangularSizeForm.swift @@ -5,7 +5,7 @@ import Styleguide struct RectangularSizeForm: HTML, Sendable { - static func id(_ room: DuctSizing.RoomContainer) -> String { + static func id(_ room: DuctSizes.RoomContainer) -> String { let base = "rectangularSize" return "\(base)_\(room.roomName.idString)" } @@ -13,12 +13,12 @@ struct RectangularSizeForm: HTML, Sendable { @Environment(ProjectViewValue.$projectID) var projectID let id: String - let room: DuctSizing.RoomContainer + let room: DuctSizes.RoomContainer let dismiss: Bool init( id: String? = nil, - room: DuctSizing.RoomContainer, + room: DuctSizes.RoomContainer, dismiss: Bool = true ) { self.id = Self.id(room) diff --git a/Sources/ViewController/Views/DuctSizing/RoomsTable.swift b/Sources/ViewController/Views/DuctSizing/RoomsTable.swift index ea08885..be3e090 100644 --- a/Sources/ViewController/Views/DuctSizing/RoomsTable.swift +++ b/Sources/ViewController/Views/DuctSizing/RoomsTable.swift @@ -9,7 +9,7 @@ extension DuctSizingView { struct RoomsTable: HTML, Sendable { @Environment(ProjectViewValue.$projectID) var projectID - let rooms: [DuctSizing.RoomContainer] + let rooms: [DuctSizes.RoomContainer] var body: some HTML { @@ -34,13 +34,13 @@ extension DuctSizingView { struct RoomRow: HTML, Sendable { - static func id(_ room: DuctSizing.RoomContainer) -> String { + static func id(_ room: DuctSizes.RoomContainer) -> String { "roomRow_\(room.roomName.idString)" } @Environment(ProjectViewValue.$projectID) var projectID - let room: DuctSizing.RoomContainer + let room: DuctSizes.RoomContainer let formID = UUID().idString var deleteRoute: String { diff --git a/Sources/ViewController/Views/DuctSizing/TrunkSizeForm.swift b/Sources/ViewController/Views/DuctSizing/TrunkSizeForm.swift index b4a5b78..8f281ef 100644 --- a/Sources/ViewController/Views/DuctSizing/TrunkSizeForm.swift +++ b/Sources/ViewController/Views/DuctSizing/TrunkSizeForm.swift @@ -5,7 +5,7 @@ import Styleguide struct TrunkSizeForm: HTML, Sendable { - static func id(_ trunk: DuctSizing.TrunkContainer? = nil) -> String { + static func id(_ trunk: DuctSizes.TrunkContainer? = nil) -> String { let base = "trunkSizeForm" guard let trunk else { return base } return "\(base)_\(trunk.id.idString)" @@ -13,8 +13,8 @@ struct TrunkSizeForm: HTML, Sendable { @Environment(ProjectViewValue.$projectID) var projectID - let container: DuctSizing.TrunkContainer? - let rooms: [DuctSizing.RoomContainer] + let container: DuctSizes.TrunkContainer? + let rooms: [DuctSizes.RoomContainer] let dismiss: Bool var trunk: TrunkSize? { @@ -22,8 +22,8 @@ struct TrunkSizeForm: HTML, Sendable { } init( - trunk: DuctSizing.TrunkContainer? = nil, - rooms: [DuctSizing.RoomContainer], + trunk: DuctSizes.TrunkContainer? = nil, + rooms: [DuctSizes.RoomContainer], dismiss: Bool = true ) { self.container = trunk @@ -122,7 +122,7 @@ struct TrunkSizeForm: HTML, Sendable { } extension Array where Element == TrunkSize.RoomProxy { - func hasRoom(_ room: DuctSizing.RoomContainer) -> Bool { + func hasRoom(_ room: DuctSizes.RoomContainer) -> Bool { first { $0.id == room.roomID && $0.registers.contains(room.roomRegister) diff --git a/Sources/ViewController/Views/DuctSizing/TrunksTable.swift b/Sources/ViewController/Views/DuctSizing/TrunksTable.swift index de131b6..ced8f52 100644 --- a/Sources/ViewController/Views/DuctSizing/TrunksTable.swift +++ b/Sources/ViewController/Views/DuctSizing/TrunksTable.swift @@ -7,11 +7,10 @@ extension DuctSizingView { struct TrunkTable: HTML, Sendable { - let trunks: [DuctSizing.TrunkContainer] - let rooms: [DuctSizing.RoomContainer] + let ductSizes: DuctSizes - private var sortedTrunks: [DuctSizing.TrunkContainer] { - trunks + private var sortedTrunks: [DuctSizes.TrunkContainer] { + ductSizes.trunks .sorted(by: { $0.designCFM.value > $1.designCFM.value }) .sorted(by: { $0.type.rawValue > $1.type.rawValue }) } @@ -29,7 +28,7 @@ extension DuctSizingView { } tbody { for trunk in sortedTrunks { - TrunkRow(trunk: trunk, rooms: rooms) + TrunkRow(trunk: trunk, rooms: ductSizes.rooms) } } } @@ -41,8 +40,8 @@ extension DuctSizingView { @Environment(ProjectViewValue.$projectID) var projectID - let trunk: DuctSizing.TrunkContainer - let rooms: [DuctSizing.RoomContainer] + let trunk: DuctSizes.TrunkContainer + let rooms: [DuctSizes.RoomContainer] var body: some HTML { tr { diff --git a/Sources/ViewController/Views/TestPage.swift b/Sources/ViewController/Views/TestPage.swift index 9227c38..f286e7b 100644 --- a/Sources/ViewController/Views/TestPage.swift +++ b/Sources/ViewController/Views/TestPage.swift @@ -5,27 +5,27 @@ import ManualDCore import Styleguide struct TestPage: HTML, Sendable { - let trunks: [DuctSizing.TrunkContainer] - let rooms: [DuctSizing.RoomContainer] + // let ductSizes: DuctSizes var body: some HTML { - div(.class("overflow-auto")) { - DuctSizingView.TrunkTable(trunks: trunks, rooms: rooms) - - Row { - h2(.class("text-2xl font-bold")) { "Trunk Sizes" } - - PlusButton() - .attributes( - .class("me-6"), - .showModal(id: TrunkSizeForm.id()) - ) - } - .attributes(.class("mt-6")) - - div(.class("divider -mt-2")) {} - - DuctSizingView.TrunkTable(trunks: trunks, rooms: rooms) - } + div {} + // div(.class("overflow-auto")) { + // DuctSizingView.TrunkTable(ductSizes: ductSizes) + // + // Row { + // h2(.class("text-2xl font-bold")) { "Trunk Sizes" } + // + // PlusButton() + // .attributes( + // .class("me-6"), + // .showModal(id: TrunkSizeForm.id()) + // ) + // } + // .attributes(.class("mt-6")) + // + // div(.class("divider -mt-2")) {} + // + // DuctSizingView.TrunkTable(ductSizes: ductSizes) + // } } }