feat: Reorganizes / creates duct sizes container, uses it in views and projectClient.
This commit is contained in:
@@ -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<T>(dynamicMember keyPath: KeyPath<DuctSizing.SizeContainer, T>) -> T {
|
||||
public subscript<T>(dynamicMember keyPath: KeyPath<DuctSizes.SizeContainer, T>) -> 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<T>(dynamicMember keyPath: KeyPath<DuctSizing.SizeContainer, T>) -> T {
|
||||
public subscript<T>(dynamicMember keyPath: KeyPath<DuctSizes.SizeContainer, T>) -> T {
|
||||
ductSize[keyPath: keyPath]
|
||||
}
|
||||
}
|
||||
@@ -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]
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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?
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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<HTMLTag.table> {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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<HTMLTag.tr> {
|
||||
tr {
|
||||
|
||||
@@ -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)
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user