feat: Uses shared duct size container for both room and trunk duct sizing containers.

This commit is contained in:
2026-01-16 10:16:31 -05:00
parent 65fc8565b6
commit 59c1c9ec4a
4 changed files with 102 additions and 43 deletions

View File

@@ -23,6 +23,7 @@ public enum DuctSizing {
public struct SizeContainer: Codable, Equatable, Sendable {
public let rectangularID: RectangularDuct.ID?
public let designCFM: DesignCFM
public let roundSize: Double
public let finalSize: Int
@@ -32,6 +33,7 @@ public enum DuctSizing {
public let width: Int?
public init(
rectangularID: RectangularDuct.ID? = nil,
designCFM: DuctSizing.DesignCFM,
roundSize: Double,
finalSize: Int,
@@ -40,6 +42,7 @@ public enum DuctSizing {
height: Int? = nil,
width: Int? = nil
) {
self.rectangularID = rectangularID
self.designCFM = designCFM
self.roundSize = roundSize
self.finalSize = finalSize
@@ -52,6 +55,7 @@ public enum DuctSizing {
// TODO: Uses SizeContainer
@dynamicMemberLookup
public struct RoomContainer: Codable, Equatable, Sendable {
public let roomID: Room.ID
@@ -61,13 +65,7 @@ public enum DuctSizing {
public let coolingLoad: Double
public let heatingCFM: Double
public let coolingCFM: Double
public let designCFM: DesignCFM
public let roundSize: Double
public let finalSize: Int
public let velocity: Int
public let flexSize: Int
public let rectangularSize: RectangularDuct?
public let rectangularWidth: Int?
public let ductSize: SizeContainer
public init(
roomID: Room.ID,
@@ -77,13 +75,7 @@ public enum DuctSizing {
coolingLoad: Double,
heatingCFM: Double,
coolingCFM: Double,
designCFM: DesignCFM,
roundSize: Double,
finalSize: Int,
velocity: Int,
flexSize: Int,
rectangularSize: RectangularDuct? = nil,
rectangularWidth: Int? = nil
ductSize: SizeContainer
) {
self.roomID = roomID
self.roomName = roomName
@@ -92,13 +84,46 @@ public enum DuctSizing {
self.coolingLoad = coolingLoad
self.heatingCFM = heatingCFM
self.coolingCFM = coolingCFM
self.designCFM = designCFM
self.roundSize = roundSize
self.finalSize = finalSize
self.velocity = velocity
self.flexSize = flexSize
self.rectangularSize = rectangularSize
self.rectangularWidth = rectangularWidth
self.ductSize = ductSize
}
// public init(
// roomID: Room.ID,
// roomName: String,
// roomRegister: Int,
// heatingLoad: Double,
// coolingLoad: Double,
// heatingCFM: Double,
// coolingCFM: Double,
// designCFM: DesignCFM,
// roundSize: Double,
// finalSize: Int,
// velocity: Int,
// flexSize: Int,
// rectangularSize: RectangularDuct? = nil,
// rectangularWidth: Int? = nil
// ) {
// self.roomID = roomID
// self.roomName = roomName
// self.roomRegister = roomRegister
// self.heatingLoad = heatingLoad
// self.coolingLoad = coolingLoad
// self.heatingCFM = heatingCFM
// self.coolingCFM = coolingCFM
// self.ductSize = .init(
// rectangularID: rectangularSize?.id,
// designCFM: designCFM,
// roundSize: roundSize,
// finalSize: finalSize,
// velocity: velocity,
// flexSize: flexSize,
// height: rectangularSize?.height,
// width: rectangularWidth
// )
// }
public subscript<T>(dynamicMember keyPath: KeyPath<DuctSizing.SizeContainer, T>) -> T {
ductSize[keyPath: keyPath]
}
}

View File

@@ -77,13 +77,12 @@ extension ManualDClient {
coolingLoad: coolingLoad,
heatingCFM: heatingCFM,
coolingCFM: coolingCFM,
designCFM: designCFM,
roundSize: sizes.ductulatorSize,
finalSize: sizes.finalSize,
velocity: sizes.velocity,
flexSize: sizes.flexSize,
rectangularSize: rectangularSize,
rectangularWidth: rectangularWidth
ductSize: .init(
designCFM: designCFM,
sizes: sizes,
rectangularSize: rectangularSize,
width: rectangularWidth
)
)
)
}
@@ -127,10 +126,7 @@ extension ManualDClient {
trunk: trunk,
ductSize: .init(
designCFM: designCFM,
roundSize: sizes.ductulatorSize,
finalSize: sizes.finalSize,
velocity: sizes.velocity,
flexSize: sizes.flexSize,
sizes: sizes,
height: trunk.height,
width: width
)
@@ -143,6 +139,44 @@ extension ManualDClient {
}
extension DuctSizing.SizeContainer {
init(
designCFM: DuctSizing.DesignCFM,
sizes: ManualDClient.DuctSizeResponse,
height: Int?,
width: Int?
) {
self.init(
rectangularID: nil,
designCFM: designCFM,
roundSize: sizes.ductulatorSize,
finalSize: sizes.finalSize,
velocity: sizes.velocity,
flexSize: sizes.flexSize,
height: height,
width: width
)
}
init(
designCFM: DuctSizing.DesignCFM,
sizes: ManualDClient.DuctSizeResponse,
rectangularSize: DuctSizing.RectangularDuct?,
width: Int?
) {
self.init(
rectangularID: rectangularSize?.id,
designCFM: designCFM,
roundSize: sizes.ductulatorSize,
finalSize: sizes.finalSize,
velocity: sizes.velocity,
flexSize: sizes.flexSize,
height: rectangularSize?.height,
width: width
)
}
}
extension Room {
var heatingLoadPerRegister: Double {

View File

@@ -40,7 +40,7 @@ struct RectangularSizeForm: HTML, Sendable {
}
var height: Int? {
room.rectangularSize?.height
room.ductSize.height
}
var body: some HTML<HTMLTag.dialog> {
@@ -54,7 +54,7 @@ struct RectangularSizeForm: HTML, Sendable {
.hx.swap(.outerHTML)
) {
input(.class("hidden"), .name("register"), .value(room.roomRegister))
input(.class("hidden"), .name("id"), .value(room.rectangularSize?.id))
input(.class("hidden"), .name("id"), .value(room.ductSize.rectangularID))
LabeledInput(
"Height",

View File

@@ -44,7 +44,7 @@ extension DuctSizingView {
let formID = UUID().idString
var deleteRoute: String {
guard let id = room.rectangularSize?.id else { return "" }
guard let id = room.rectangularID else { return "" }
return SiteRoute.View.router.path(
for: .project(
@@ -80,7 +80,7 @@ extension DuctSizingView {
span(.class("label")) { "Design" }
div(.class("flex justify-center")) {
Badge(number: room.designCFM.value, digits: 0)
Badge(number: room.ductSize.designCFM.value, digits: 0)
}
span(.class("label")) { "Heating" }
@@ -103,28 +103,28 @@ extension DuctSizingView {
div(.class("label")) { "Calculated" }
div(.class("flex justify-center")) {
Badge(number: room.roundSize, digits: 2)
Badge(number: room.ductSize.roundSize, digits: 2)
}
div {}
div(.class("label")) { "Final" }
div(.class("flex justify-center")) {
Badge(number: room.finalSize)
Badge(number: room.ductSize.finalSize)
.attributes(.class("badge-secondary"))
}
div {}
div(.class("label")) { "Flex" }
div(.class("flex justify-center")) {
Badge(number: room.flexSize)
Badge(number: room.ductSize.flexSize)
.attributes(.class("badge-primary"))
}
div {}
div(.class("label")) { "Rectangular" }
div(.class("flex justify-center")) {
if let width = room.rectangularWidth,
let height = room.rectangularSize?.height
if let width = room.ductSize.width,
let height = room.ductSize.height
{
Badge {
span { "\(width) x \(height)" }
@@ -134,7 +134,7 @@ extension DuctSizingView {
}
div(.class("flex justify-end")) {
div(.class("join")) {
if room.rectangularSize != nil {
if room.ductSize.width != nil {
Tooltip("Delete Size", position: .bottom) {
TrashButton()
.attributes(.class("join-item btn-ghost"))
@@ -142,7 +142,7 @@ extension DuctSizingView {
.hx.delete(deleteRoute),
.hx.target("#\(rowID)"),
.hx.swap(.outerHTML),
when: room.rectangularSize != nil
when: room.ductSize.width != nil
)
}
}