import Elementary import ElementaryHTMX import Foundation import ManualDCore import Styleguide extension DuctSizingView { // TODO: Remove register ID. struct RoomsTable: HTML, Sendable { @Environment(ProjectViewValue.$projectID) var projectID let rooms: [DuctSizes.RoomContainer] var body: some HTML { table(.class("table table-zebra text-lg")) { thead { tr(.class("text-lg")) { th { "Name" } th { "BTU" } th { "CFM" } th { "Velocity" } th(.class("w-[330px]")) { "Size" } } } tbody { for room in rooms { RoomRow(room: room) } } } } } struct RoomRow: HTML, Sendable { static func id(_ room: DuctSizes.RoomContainer) -> String { "roomRow_\(room.roomName.idString)" } @Environment(ProjectViewValue.$projectID) var projectID let room: DuctSizes.RoomContainer let formID = UUID().idString var deleteRoute: String { guard let id = room.rectangularID else { return "" } return SiteRoute.View.router.path( for: .project( .detail( projectID, .ductSizing( .deleteRectangularSize( room.roomID, .init(rectangularSizeID: id, register: room.roomRegister) )) ) ) ) } var rowID: String { Self.id(room) } var body: some HTML { tr(.class("text-lg"), .id(rowID)) { td { room.roomName } td { div(.class("flex flex-wrap grid grid-cols-2 gap-2")) { span(.class("label")) { "Heating" } Number(room.heatingLoad, digits: 0) span(.class("label")) { "Cooling" } Number(room.coolingLoad, digits: 0) } } td { div(.class("flex flex-wrap grid grid-cols-2 gap-2")) { span(.class("label")) { "Design" } div(.class("flex justify-center")) { Badge(number: room.ductSize.designCFM.value, digits: 0) } span(.class("label")) { "Heating" } div(.class("flex justify-center")) { Number(room.heatingCFM, digits: 0) } span(.class("label")) { "Cooling" } div(.class("flex justify-center")) { Number(room.coolingCFM, digits: 0) } } } td { Number(room.velocity) } td { div(.class("grid grid-cols-3 gap-2 w-[330px]")) { div(.class("label")) { "Calculated" } div(.class("flex justify-center")) { Badge(number: room.ductSize.roundSize, digits: 2) } div {} div(.class("label")) { "Final" } div(.class("flex justify-center")) { Badge(number: room.ductSize.finalSize) .attributes(.class("badge-secondary")) } div {} div(.class("label")) { "Flex" } div(.class("flex justify-center")) { Badge(number: room.ductSize.flexSize) .attributes(.class("badge-primary")) } div {} div(.class("label")) { "Rectangular" } div(.class("flex justify-center")) { if let width = room.ductSize.width, let height = room.ductSize.height { Badge { span { "\(width) x \(height)" } } .attributes(.class("badge-info")) } } div(.class("flex justify-end")) { div(.class("join")) { if room.ductSize.width != nil { Tooltip("Delete Size", position: .bottom) { TrashButton() .attributes(.class("join-item btn-ghost")) .attributes( .hx.delete(deleteRoute), .hx.target("#\(rowID)"), .hx.swap(.outerHTML), when: room.ductSize.width != nil ) } } Tooltip("Edit Size", position: .bottom) { EditButton() .attributes( .class("join-item btn-ghost"), .showModal(id: RectangularSizeForm.id(room)) ) } } } RectangularSizeForm(room: room) } } } } } }