WIP: Inital duct rectangular form, needs better thought out.
This commit is contained in:
@@ -18,6 +18,7 @@ public struct DatabaseClient: Sendable {
|
||||
public var equipment: Equipment
|
||||
public var componentLoss: ComponentLoss
|
||||
public var effectiveLength: EffectiveLengthClient
|
||||
// public var rectangularDuct: RectangularDuct
|
||||
public var users: Users
|
||||
}
|
||||
|
||||
@@ -29,6 +30,7 @@ extension DatabaseClient: TestDependencyKey {
|
||||
equipment: .testValue,
|
||||
componentLoss: .testValue,
|
||||
effectiveLength: .testValue,
|
||||
// rectangularDuct: .testValue,
|
||||
users: .testValue
|
||||
)
|
||||
|
||||
@@ -40,6 +42,7 @@ extension DatabaseClient: TestDependencyKey {
|
||||
equipment: .live(database: database),
|
||||
componentLoss: .live(database: database),
|
||||
effectiveLength: .live(database: database),
|
||||
// rectangularDuct: .live(database: database),
|
||||
users: .live(database: database)
|
||||
)
|
||||
}
|
||||
@@ -67,6 +70,7 @@ extension DatabaseClient.Migrations: DependencyKey {
|
||||
EquipmentInfo.Migrate(),
|
||||
Room.Migrate(),
|
||||
EffectiveLength.Migrate(),
|
||||
// DuctSizing.RectangularDuct.Migrate(),
|
||||
]
|
||||
}
|
||||
)
|
||||
|
||||
175
Sources/DatabaseClient/RectangularDuct.swift
Normal file
175
Sources/DatabaseClient/RectangularDuct.swift
Normal file
@@ -0,0 +1,175 @@
|
||||
// import Dependencies
|
||||
// import DependenciesMacros
|
||||
// import Fluent
|
||||
// import Foundation
|
||||
// import ManualDCore
|
||||
//
|
||||
// extension DatabaseClient {
|
||||
// @DependencyClient
|
||||
// public struct RectangularDuct: Sendable {
|
||||
// public var create:
|
||||
// @Sendable (DuctSizing.RectangularDuct.Create) async throws -> DuctSizing.RectangularDuct
|
||||
// public var delete: @Sendable (DuctSizing.RectangularDuct.ID) async throws -> Void
|
||||
// public var fetch: @Sendable (Room.ID) async throws -> [DuctSizing.RectangularDuct]
|
||||
// public var get:
|
||||
// @Sendable (DuctSizing.RectangularDuct.ID) async throws -> DuctSizing.RectangularDuct?
|
||||
// public var update:
|
||||
// @Sendable (DuctSizing.RectangularDuct.ID, DuctSizing.RectangularDuct.Update) async throws ->
|
||||
// DuctSizing.RectangularDuct
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// extension DatabaseClient.RectangularDuct: TestDependencyKey {
|
||||
// public static let testValue = Self()
|
||||
//
|
||||
// public static func live(database: any Database) -> Self {
|
||||
// .init(
|
||||
// create: { request in
|
||||
// try request.validate()
|
||||
// let model = request.toModel()
|
||||
// try await model.save(on: database)
|
||||
// return try model.toDTO()
|
||||
// },
|
||||
// delete: { id in
|
||||
// guard let model = try await RectangularDuctModel.find(id, on: database) else {
|
||||
// throw NotFoundError()
|
||||
// }
|
||||
// try await model.delete(on: database)
|
||||
// },
|
||||
// fetch: { roomID in
|
||||
// try await RectangularDuctModel.query(on: database)
|
||||
// .with(\.$room)
|
||||
// .filter(\.$room.$id == roomID)
|
||||
// .all()
|
||||
// .map { try $0.toDTO() }
|
||||
// },
|
||||
// get: { id in
|
||||
// try await RectangularDuctModel.find(id, on: database)
|
||||
// .map { try $0.toDTO() }
|
||||
// },
|
||||
// update: { id, updates in
|
||||
// guard let model = try await RectangularDuctModel.find(id, on: database) else {
|
||||
// throw NotFoundError()
|
||||
// }
|
||||
// try updates.validate()
|
||||
// model.applyUpdates(updates)
|
||||
// if model.hasChanges {
|
||||
// try await model.save(on: database)
|
||||
// }
|
||||
// return try model.toDTO()
|
||||
// }
|
||||
// )
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// extension DuctSizing.RectangularDuct.Create {
|
||||
//
|
||||
// func validate() throws(ValidationError) {
|
||||
// guard height > 0 else {
|
||||
// throw ValidationError("Rectangular duct size height should be greater than 0.")
|
||||
// }
|
||||
// if let register {
|
||||
// guard register > 0 else {
|
||||
// throw ValidationError("Rectangular duct size register should be greater than 0.")
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// func toModel() -> RectangularDuctModel {
|
||||
// .init(roomID: roomID, height: height)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// extension DuctSizing.RectangularDuct.Update {
|
||||
//
|
||||
// func validate() throws(ValidationError) {
|
||||
// if let height {
|
||||
// guard height > 0 else {
|
||||
// throw ValidationError("Rectangular duct size height should be greater than 0.")
|
||||
// }
|
||||
// }
|
||||
// if let register {
|
||||
// guard register > 0 else {
|
||||
// throw ValidationError("Rectangular duct size register should be greater than 0.")
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// extension DuctSizing.RectangularDuct {
|
||||
// struct Migrate: AsyncMigration {
|
||||
// let name = "CreateRectangularDuct"
|
||||
//
|
||||
// func prepare(on database: any Database) async throws {
|
||||
// try await database.schema(RectangularDuctModel.schema)
|
||||
// .id()
|
||||
// .field("register", .int8)
|
||||
// .field("height", .int8, .required)
|
||||
// .field("roomID", .uuid, .required, .references(RoomModel.schema, "id", onDelete: .cascade))
|
||||
// .field("createdAt", .datetime)
|
||||
// .field("updatedAt", .datetime)
|
||||
// .create()
|
||||
// }
|
||||
//
|
||||
// func revert(on database: any Database) async throws {
|
||||
// try await database.schema(RectangularDuctModel.schema).delete()
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// final class RectangularDuctModel: Model, @unchecked Sendable {
|
||||
//
|
||||
// static let schema = "rectangularDuct"
|
||||
//
|
||||
// @ID(key: .id)
|
||||
// var id: UUID?
|
||||
//
|
||||
// @Parent(key: "roomID")
|
||||
// var room: RoomModel
|
||||
//
|
||||
// @Field(key: "height")
|
||||
// var height: Int
|
||||
//
|
||||
// @Field(key: "register")
|
||||
// var register: Int?
|
||||
//
|
||||
// @Timestamp(key: "createdAt", on: .create, format: .iso8601)
|
||||
// var createdAt: Date?
|
||||
//
|
||||
// @Timestamp(key: "updatedAt", on: .update, format: .iso8601)
|
||||
// var updatedAt: Date?
|
||||
//
|
||||
// init() {}
|
||||
//
|
||||
// init(
|
||||
// id: UUID? = nil,
|
||||
// roomID: Room.ID,
|
||||
// register: Int? = nil,
|
||||
// height: Int
|
||||
// ) {
|
||||
// self.id = id
|
||||
// $room.id = roomID
|
||||
// self.register = register
|
||||
// self.height = height
|
||||
// }
|
||||
//
|
||||
// func toDTO() throws -> DuctSizing.RectangularDuct {
|
||||
// return try .init(
|
||||
// id: requireID(),
|
||||
// roomID: $room.id,
|
||||
// register: register,
|
||||
// height: height,
|
||||
// createdAt: createdAt!,
|
||||
// updatedAt: updatedAt!
|
||||
// )
|
||||
// }
|
||||
//
|
||||
// func applyUpdates(_ updates: DuctSizing.RectangularDuct.Update) {
|
||||
// if let height = updates.height, height != self.height {
|
||||
// self.height = height
|
||||
// }
|
||||
// if let register = updates.register, register != self.register {
|
||||
// self.register = register
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
@@ -38,6 +38,7 @@ extension DatabaseClient.Rooms: TestDependencyKey {
|
||||
try await RoomModel.query(on: database)
|
||||
.with(\.$project)
|
||||
.filter(\.$project.$id, .equal, projectID)
|
||||
.sort(\.$name, .ascending)
|
||||
.all()
|
||||
.map { try $0.toDTO() }
|
||||
},
|
||||
@@ -135,6 +136,7 @@ extension Room {
|
||||
.field("coolingTotal", .double, .required)
|
||||
.field("coolingSensible", .double)
|
||||
.field("registerCount", .int8, .required)
|
||||
.field("rectangularSizes", .array)
|
||||
.field("createdAt", .datetime)
|
||||
.field("updatedAt", .datetime)
|
||||
.field(
|
||||
@@ -172,6 +174,9 @@ final class RoomModel: Model, @unchecked Sendable {
|
||||
@Field(key: "registerCount")
|
||||
var registerCount: Int
|
||||
|
||||
@Field(key: "rectangularSizes")
|
||||
var rectangularSizes: [DuctSizing.RectangularDuct]?
|
||||
|
||||
@Timestamp(key: "createdAt", on: .create, format: .iso8601)
|
||||
var createdAt: Date?
|
||||
|
||||
@@ -190,6 +195,7 @@ final class RoomModel: Model, @unchecked Sendable {
|
||||
coolingTotal: Double,
|
||||
coolingSensible: Double? = nil,
|
||||
registerCount: Int,
|
||||
rectangularSizes: [DuctSizing.RectangularDuct]? = nil,
|
||||
createdAt: Date? = nil,
|
||||
updatedAt: Date? = nil,
|
||||
projectID: Project.ID
|
||||
@@ -200,6 +206,7 @@ final class RoomModel: Model, @unchecked Sendable {
|
||||
self.coolingTotal = coolingTotal
|
||||
self.coolingSensible = coolingSensible
|
||||
self.registerCount = registerCount
|
||||
self.rectangularSizes = rectangularSizes
|
||||
self.createdAt = createdAt
|
||||
self.updatedAt = updatedAt
|
||||
$project.id = projectID
|
||||
@@ -214,6 +221,7 @@ final class RoomModel: Model, @unchecked Sendable {
|
||||
coolingTotal: coolingTotal,
|
||||
coolingSensible: coolingSensible,
|
||||
registerCount: registerCount,
|
||||
rectangularSizes: rectangularSizes,
|
||||
createdAt: createdAt!,
|
||||
updatedAt: updatedAt!
|
||||
)
|
||||
@@ -236,6 +244,9 @@ final class RoomModel: Model, @unchecked Sendable {
|
||||
if let registerCount = updates.registerCount, registerCount != self.registerCount {
|
||||
self.registerCount = registerCount
|
||||
}
|
||||
if let rectangularSizes = updates.rectangularSizes, rectangularSizes != self.rectangularSizes {
|
||||
self.rectangularSizes = rectangularSizes
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ public struct ManualDClient: Sendable {
|
||||
projectSHR: Double,
|
||||
logger: Logger? = nil
|
||||
) async throws -> [DuctSizing.RoomContainer] {
|
||||
|
||||
var registerIDCount = 1
|
||||
var retval: [DuctSizing.RoomContainer] = []
|
||||
let totalHeatingLoad = rooms.totalHeatingLoad
|
||||
@@ -38,6 +39,18 @@ public struct ManualDClient: Sendable {
|
||||
)
|
||||
|
||||
for n in 1...room.registerCount {
|
||||
|
||||
var rectangularWidth: Int? = nil
|
||||
let rectangularSize = room.rectangularSizes?
|
||||
.first(where: { $0.register == nil || $0.register == n })
|
||||
|
||||
if let rectangularSize {
|
||||
let response = try await self.equivalentRectangularDuct(
|
||||
.init(round: sizes.finalSize, height: rectangularSize.height)
|
||||
)
|
||||
rectangularWidth = response.width
|
||||
}
|
||||
|
||||
retval.append(
|
||||
.init(
|
||||
registerID: "SR-\(registerIDCount)",
|
||||
@@ -51,7 +64,9 @@ public struct ManualDClient: Sendable {
|
||||
roundSize: sizes.ductulatorSize,
|
||||
finalSize: sizes.finalSize,
|
||||
velocity: sizes.velocity,
|
||||
flexSize: sizes.flexSize
|
||||
flexSize: sizes.flexSize,
|
||||
rectangularSize: rectangularSize,
|
||||
rectangularWidth: rectangularWidth
|
||||
)
|
||||
)
|
||||
registerIDCount += 1
|
||||
|
||||
@@ -3,6 +3,21 @@ import Foundation
|
||||
|
||||
public enum DuctSizing {
|
||||
|
||||
public struct RectangularDuct: Codable, Equatable, Sendable {
|
||||
|
||||
public let register: Int?
|
||||
public let height: Int
|
||||
|
||||
public init(
|
||||
register: Int? = nil,
|
||||
height: Int,
|
||||
) {
|
||||
self.register = register
|
||||
self.height = height
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public struct RoomContainer: Codable, Equatable, Sendable {
|
||||
|
||||
public let registerID: String
|
||||
@@ -17,6 +32,8 @@ public enum DuctSizing {
|
||||
public let finalSize: Int
|
||||
public let velocity: Int
|
||||
public let flexSize: Int
|
||||
public let rectangularSize: RectangularDuct?
|
||||
public let rectangularWidth: Int?
|
||||
|
||||
public init(
|
||||
registerID: String,
|
||||
@@ -30,7 +47,9 @@ public enum DuctSizing {
|
||||
roundSize: Double,
|
||||
finalSize: Int,
|
||||
velocity: Int,
|
||||
flexSize: Int
|
||||
flexSize: Int,
|
||||
rectangularSize: RectangularDuct? = nil,
|
||||
rectangularWidth: Int? = nil
|
||||
) {
|
||||
self.registerID = registerID
|
||||
self.roomID = roomID
|
||||
@@ -44,6 +63,8 @@ public enum DuctSizing {
|
||||
self.finalSize = finalSize
|
||||
self.velocity = velocity
|
||||
self.flexSize = flexSize
|
||||
self.rectangularSize = rectangularSize
|
||||
self.rectangularWidth = rectangularWidth
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ public struct Room: Codable, Equatable, Identifiable, Sendable {
|
||||
public let coolingTotal: Double
|
||||
public let coolingSensible: Double?
|
||||
public let registerCount: Int
|
||||
public let rectangularSizes: [DuctSizing.RectangularDuct]?
|
||||
public let createdAt: Date
|
||||
public let updatedAt: Date
|
||||
|
||||
@@ -20,6 +21,7 @@ public struct Room: Codable, Equatable, Identifiable, Sendable {
|
||||
coolingTotal: Double,
|
||||
coolingSensible: Double? = nil,
|
||||
registerCount: Int = 1,
|
||||
rectangularSizes: [DuctSizing.RectangularDuct]? = nil,
|
||||
createdAt: Date,
|
||||
updatedAt: Date
|
||||
) {
|
||||
@@ -30,6 +32,7 @@ public struct Room: Codable, Equatable, Identifiable, Sendable {
|
||||
self.coolingTotal = coolingTotal
|
||||
self.coolingSensible = coolingSensible
|
||||
self.registerCount = registerCount
|
||||
self.rectangularSizes = rectangularSizes
|
||||
self.createdAt = createdAt
|
||||
self.updatedAt = updatedAt
|
||||
}
|
||||
@@ -68,6 +71,7 @@ extension Room {
|
||||
public let coolingTotal: Double?
|
||||
public let coolingSensible: Double?
|
||||
public let registerCount: Int?
|
||||
public let rectangularSizes: [DuctSizing.RectangularDuct]?
|
||||
|
||||
public init(
|
||||
name: String? = nil,
|
||||
@@ -81,6 +85,18 @@ extension Room {
|
||||
self.coolingTotal = coolingTotal
|
||||
self.coolingSensible = coolingSensible
|
||||
self.registerCount = registerCount
|
||||
self.rectangularSizes = nil
|
||||
}
|
||||
|
||||
public init(
|
||||
rectangularSizes: [DuctSizing.RectangularDuct]
|
||||
) {
|
||||
self.name = nil
|
||||
self.heatingLoad = nil
|
||||
self.coolingTotal = nil
|
||||
self.coolingSensible = nil
|
||||
self.registerCount = nil
|
||||
self.rectangularSizes = rectangularSizes
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -677,6 +677,7 @@ extension SiteRoute.View.ProjectRoute {
|
||||
|
||||
public enum DuctSizingRoute: Equatable, Sendable {
|
||||
case index
|
||||
case roomRectangularForm(Room.ID, RoomRectangularForm)
|
||||
|
||||
static let rootPath = "duct-sizing"
|
||||
|
||||
@@ -685,6 +686,26 @@ extension SiteRoute.View.ProjectRoute {
|
||||
Path { rootPath }
|
||||
Method.get
|
||||
}
|
||||
Route(.case(Self.roomRectangularForm)) {
|
||||
Path {
|
||||
rootPath
|
||||
"room"
|
||||
Room.ID.parser()
|
||||
}
|
||||
Method.post
|
||||
Body {
|
||||
FormData {
|
||||
Field("register") { Int.parser() }
|
||||
Field("height") { Int.parser() }
|
||||
}
|
||||
.map(.memberwise(RoomRectangularForm.init))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public struct RoomRectangularForm: Equatable, Sendable {
|
||||
public let register: Int
|
||||
public let height: Int
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ extension ManualDClient {
|
||||
logger: logger
|
||||
)
|
||||
|
||||
logger?.debug("Rooms: \(ductRooms)")
|
||||
// logger?.debug("Rooms: \(ductRooms)")
|
||||
|
||||
return ductRooms
|
||||
|
||||
|
||||
@@ -342,11 +342,31 @@ extension SiteRoute.View.ProjectRoute.DuctSizingRoute {
|
||||
func renderView(on request: ViewController.Request, projectID: Project.ID) async throws
|
||||
-> AnySendableHTML
|
||||
{
|
||||
@Dependency(\.database) var database
|
||||
@Dependency(\.manualD) var manualD
|
||||
|
||||
switch self {
|
||||
case .index:
|
||||
return request.view {
|
||||
ProjectView(projectID: projectID, activeTab: .ductSizing, logger: request.logger)
|
||||
}
|
||||
case .roomRectangularForm(let roomID, let form):
|
||||
let _ = try await database.rooms.update(
|
||||
roomID,
|
||||
.init(rectangularSizes: [.init(register: form.register, height: form.height)])
|
||||
)
|
||||
// request.logger.debug("Got room rectangular form: \(roomID)")
|
||||
//
|
||||
// let containers = try await manualD.calculate(
|
||||
// rooms: [room],
|
||||
// designFrictionRateResult: database.designFrictionRate(projectID: projectID),
|
||||
// projectSHR: database.projects.getSensibleHeatRatio(projectID)
|
||||
// )
|
||||
// request.logger.debug("Room Containers: \(containers)")
|
||||
// let container = containers.first(where: { $0.roomName == "\(room.name)-\(form.register)" })!
|
||||
// request.logger.debug("Room Container: \(container)")
|
||||
// return DuctSizingView.RoomRow(projectID: projectID, room: container)
|
||||
return ProjectView(projectID: projectID, activeTab: .ductSizing, logger: request.logger)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@ import ElementaryHTMX
|
||||
import ManualDCore
|
||||
import Styleguide
|
||||
|
||||
// FIX: The value field is sometimes wonky as far as what values it accepts.
|
||||
|
||||
struct ComponentLossForm: HTML, Sendable {
|
||||
|
||||
static func id(_ componentLoss: ComponentPressureLoss? = nil) -> String {
|
||||
@@ -49,7 +51,7 @@ struct ComponentLossForm: HTML, Sendable {
|
||||
label(.for("value")) { "Value" }
|
||||
Input(id: "value", placeholder: "Pressure loss")
|
||||
.attributes(
|
||||
.type(.number), .min("0.03"), .max("1.0"), .step("0.1"), .required,
|
||||
.type(.number), .min("0.03"), .max("1.0"), .step("0.01"), .required,
|
||||
.value(componentLoss?.value)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -7,12 +7,27 @@ import Styleguide
|
||||
|
||||
struct DuctSizingView: HTML, Sendable {
|
||||
|
||||
let projectID: Project.ID
|
||||
let rooms: [DuctSizing.RoomContainer]
|
||||
|
||||
var body: some HTML {
|
||||
div {
|
||||
h1(.class("text-2xl py-4")) { "Duct Sizes" }
|
||||
if rooms.count == 0 {
|
||||
p(.class("text-error italic")) {
|
||||
"Must complete all the previous sections to display duct sizing calculations."
|
||||
}
|
||||
} else {
|
||||
RoomsTable(projectID: projectID, rooms: rooms)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct RoomsTable: HTML, Sendable {
|
||||
let projectID: Project.ID
|
||||
let rooms: [DuctSizing.RoomContainer]
|
||||
|
||||
var body: some HTML<HTMLTag.div> {
|
||||
div(.class("overflow-x-auto")) {
|
||||
table(.class("table table-zebra")) {
|
||||
thead {
|
||||
@@ -27,12 +42,14 @@ struct DuctSizingView: HTML, Sendable {
|
||||
th(.class("hidden xl:table-cell")) { "Round Size" }
|
||||
th { "Velocity" }
|
||||
th { "Final Size" }
|
||||
th { "Height" }
|
||||
th { "Width" }
|
||||
th { "Flex Size" }
|
||||
}
|
||||
}
|
||||
tbody {
|
||||
for room in rooms {
|
||||
RoomRow(room: room)
|
||||
RoomRow(projectID: projectID, room: room)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -41,10 +58,19 @@ struct DuctSizingView: HTML, Sendable {
|
||||
}
|
||||
|
||||
struct RoomRow: HTML, Sendable {
|
||||
let projectID: Project.ID
|
||||
let room: DuctSizing.RoomContainer
|
||||
|
||||
var route: String {
|
||||
SiteRoute.View.router.path(
|
||||
for: .project(.detail(projectID, .ductSizing(.index)))
|
||||
)
|
||||
.appendingPath("room")
|
||||
.appendingPath(room.roomID)
|
||||
}
|
||||
|
||||
var body: some HTML<HTMLTag.tr> {
|
||||
tr(.class("text-lg")) {
|
||||
tr(.class("text-lg"), .id(room.roomID.idString)) {
|
||||
td { room.registerID }
|
||||
td { room.roomName }
|
||||
td { Number(room.heatingLoad, digits: 0) }
|
||||
@@ -62,6 +88,32 @@ struct DuctSizingView: HTML, Sendable {
|
||||
Number(room.finalSize)
|
||||
.attributes(.class("badge badge-outline badge-secondary text-xl font-bold"))
|
||||
}
|
||||
td {
|
||||
form(
|
||||
.hx.post(route),
|
||||
.hx.target("body"),
|
||||
.hx.swap(.outerHTML)
|
||||
// .hx.trigger(
|
||||
// .event(.change).from("#rectangularSize_\(room.roomID.idString)")
|
||||
// )
|
||||
) {
|
||||
input(.class("hidden"), .name("register"), .value("\(room.roomName.last!)"))
|
||||
Row {
|
||||
Input(
|
||||
id: "height",
|
||||
name: "height",
|
||||
placeholder: "Height"
|
||||
)
|
||||
.attributes(.type(.number), .min("0"), .value(room.rectangularSize?.height))
|
||||
SubmitButton()
|
||||
}
|
||||
}
|
||||
}
|
||||
td {
|
||||
if let width = room.rectangularWidth {
|
||||
Number(width)
|
||||
}
|
||||
}
|
||||
td {
|
||||
Number(room.flexSize)
|
||||
.attributes(.class("badge badge-outline badge-primary text-xl font-bold"))
|
||||
|
||||
@@ -2,6 +2,8 @@ import Elementary
|
||||
import ManualDCore
|
||||
import Styleguide
|
||||
|
||||
// FIX: Need to update available static, etc. when equipment info is submitted.
|
||||
|
||||
struct FrictionRateView: HTML, Sendable {
|
||||
|
||||
let equipmentInfo: EquipmentInfo?
|
||||
@@ -46,8 +48,8 @@ struct FrictionRateView: HTML, Sendable {
|
||||
div(.class("p-4 space-y-6")) {
|
||||
h1(.class("text-4xl font-bold pb-6")) { "Friction Rate" }
|
||||
div(.class("flex space-x-4")) {
|
||||
Label("Available Static Pressure")
|
||||
if let availableStaticPressure {
|
||||
Label("Available Static Pressure")
|
||||
Number(availableStaticPressure, digits: 2)
|
||||
.attributes(.class("badge badge-lg badge-outline font-bold ms-4"))
|
||||
}
|
||||
|
||||
@@ -68,6 +68,7 @@ struct ProjectView: HTML, Sendable {
|
||||
)
|
||||
case .ductSizing:
|
||||
try await DuctSizingView(
|
||||
projectID: projectID,
|
||||
rooms: manualD.calculate(
|
||||
rooms: database.rooms.fetch(projectID),
|
||||
designFrictionRateResult: database.designFrictionRate(projectID: projectID),
|
||||
|
||||
Reference in New Issue
Block a user