This repository has been archived on 2026-02-12. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
swift-duct-calc/Sources/ViewController/Views/DuctSizing/RoomsTable.swift

168 lines
4.5 KiB
Swift

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: [DuctSizing.RoomContainer]
var body: some HTML<HTMLTag.table> {
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: DuctSizing.RoomContainer) -> String {
"roomRow_\(room.roomName.idString)"
}
@Environment(ProjectViewValue.$projectID) var projectID
let room: DuctSizing.RoomContainer
let formID = UUID().idString
var deleteRoute: String {
guard let id = room.rectangularSize?.id 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<HTMLTag.tr> {
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.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.roundSize, digits: 2)
}
div {}
div(.class("label")) { "Final" }
div(.class("flex justify-center")) {
Badge(number: room.finalSize)
.attributes(.class("badge-secondary"))
}
div {}
div(.class("label")) { "Flex" }
div(.class("flex justify-center")) {
Badge(number: room.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
{
Badge {
span { "\(width) x \(height)" }
}
.attributes(.class("badge-info"))
}
}
div(.class("flex justify-end")) {
div(.class("join")) {
if room.rectangularSize != 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.rectangularSize != nil
)
}
}
Tooltip("Edit Size", position: .bottom) {
EditButton()
.attributes(
.class("join-item btn-ghost"),
.showModal(id: RectangularSizeForm.id(room))
)
}
}
}
RectangularSizeForm(room: room)
}
}
}
}
}
}