WIP: Moves friction rate route to be part of project detail routes.

This commit is contained in:
2026-01-05 09:01:49 -05:00
parent 4aca134abd
commit 55a3adde25
14 changed files with 71 additions and 6759 deletions

View File

@@ -39,10 +39,6 @@ extension ViewController.Request {
}
case .project(let route):
return try await route.renderView(on: self)
// case .room(let route):
// return try await route.renderView(on: self)
case .frictionRate(let route):
return try await route.renderView(isHtmxRequest: isHtmxRequest)
case .effectiveLength(let route):
return try await route.renderView(isHtmxRequest: isHtmxRequest)
// case .user(let route):
@@ -110,6 +106,9 @@ extension SiteRoute.View.ProjectRoute {
ProjectDetail(project: project)
}
}
case .frictionRate(let route):
return try await route.renderView(on: request, projectID: projectID)
case .rooms(let route):
return try await route.renderView(on: request, projectID: projectID)
}
@@ -155,26 +154,34 @@ extension SiteRoute.View.ProjectRoute.RoomRoute {
}
}
extension SiteRoute.View.FrictionRateRoute {
func renderView(isHtmxRequest: Bool) async throws -> AnySendableHTML {
extension SiteRoute.View.ProjectRoute.FrictionRateRoute {
func renderView(on request: ViewController.Request, projectID: Project.ID) async throws
-> AnySendableHTML
{
@Dependency(\.database) var database
switch self {
case .index:
return _render(isHtmxRequest: isHtmxRequest, active: .frictionRate) {
FrictionRateView()
let componentLosses = try await database.componentLoss.fetch(projectID)
return request.view {
ProjectView(projectID: projectID, activeTab: .frictionRate) {
FrictionRateView(componentLosses: componentLosses, projectID: projectID)
}
}
case .form(let type, let dismiss):
// FIX: Forms need to reference existing items.
switch type {
case .equipmentInfo:
return EquipmentForm(dismiss: dismiss)
return EquipmentForm(dismiss: dismiss, projectID: projectID)
case .componentPressureLoss:
return ComponentLossForm(dismiss: dismiss)
return ComponentLossForm(dismiss: dismiss, projectID: projectID)
}
}
}
}
extension SiteRoute.View.FrictionRateRoute.FormType {
extension SiteRoute.View.ProjectRoute.FrictionRateRoute.FormType {
var id: String {
switch self {
case .equipmentInfo:

View File

@@ -5,6 +5,7 @@ import Styleguide
struct ComponentLossForm: HTML, Sendable {
let dismiss: Bool
let projectID: Project.ID
var body: some HTML {
ModalForm(id: "componentLossForm", dismiss: dismiss) {
@@ -25,7 +26,10 @@ struct ComponentLossForm: HTML, Sendable {
div {
CancelButton()
.attributes(
.hx.get(route: .frictionRate(.form(.componentPressureLoss, dismiss: true))),
.hx.get(
route: .project(
.detail(projectID, .frictionRate(.form(.componentPressureLoss, dismiss: true))))
),
.hx.target("#componentLossForm"),
.hx.swap(.outerHTML)
)

View File

@@ -3,9 +3,12 @@ import ElementaryHTMX
import ManualDCore
import Styleguide
// TODO: Load component losses when view appears??
struct ComponentPressureLossesView: HTML, Sendable {
let componentPressureLosses: [ComponentPressureLoss]
let projectID: Project.ID
private var total: Double {
componentPressureLosses.reduce(into: 0) { $0 += $1.value }
@@ -23,7 +26,10 @@ struct ComponentPressureLossesView: HTML, Sendable {
h1(.class("text-2xl font-bold")) { "Component Pressure Losses" }
PlusButton()
.attributes(
.hx.get(route: .frictionRate(.form(.componentPressureLoss, dismiss: false))),
.hx.get(
route: .project(
.detail(projectID, .frictionRate(.form(.componentPressureLoss, dismiss: false))))
),
.hx.target("#componentLossForm"),
.hx.swap(.outerHTML)
)
@@ -43,8 +49,7 @@ struct ComponentPressureLossesView: HTML, Sendable {
.attributes(.class("text-xl font-bold"))
}
}
// div(.id("componentLossForm")) {}
ComponentLossForm(dismiss: true)
ComponentLossForm(dismiss: true, projectID: projectID)
}
}

View File

@@ -6,6 +6,7 @@ import Styleguide
struct EquipmentForm: HTML, Sendable {
let dismiss: Bool
let projectID: Project.ID
var body: some HTML {
ModalForm(id: "equipmentForm", dismiss: dismiss) {
@@ -33,7 +34,11 @@ struct EquipmentForm: HTML, Sendable {
div(.class("space-x-4")) {
CancelButton()
.attributes(
.hx.get(route: .frictionRate(.form(.equipmentInfo, dismiss: true))),
.hx.get(
route: .project(
.detail(projectID, .frictionRate(.form(.equipmentInfo, dismiss: true)))
)
),
.hx.target("#equipmentForm"),
.hx.swap(.outerHTML)
)

View File

@@ -4,6 +4,7 @@ import Styleguide
struct EquipmentInfoView: HTML, Sendable {
let equipmentInfo: EquipmentInfo
var projectID: Project.ID { equipmentInfo.projectID }
var body: some HTML {
div(.class("space-y-4 border border-gray-200 rounded-lg shadow-lg p-4")) {
@@ -33,7 +34,7 @@ struct EquipmentInfoView: HTML, Sendable {
div {}
EditButton()
.attributes(
.hx.get(route: .frictionRate(.form(.equipmentInfo))),
.hx.get(route: .project(.detail(projectID, .frictionRate(.form(.equipmentInfo))))),
.hx.target("#equipmentForm"),
.hx.swap(.outerHTML)
)

View File

@@ -4,11 +4,16 @@ import Styleguide
struct FrictionRateView: HTML, Sendable {
let componentLosses: [ComponentPressureLoss]
let projectID: Project.ID
var body: some HTML {
div(.class("p-4 space-y-6")) {
h1(.class("text-4xl font-bold pb-6")) { "Friction Rate" }
EquipmentInfoView(equipmentInfo: EquipmentInfo.mock)
ComponentPressureLossesView(componentPressureLosses: ComponentPressureLoss.mock)
ComponentPressureLossesView(
componentPressureLosses: componentLosses, projectID: projectID
)
}
}
}

View File

@@ -65,8 +65,12 @@ struct Sidebar: HTML {
row(title: "Equivalent Lengths", icon: .rulerDimensionLine, route: .effectiveLength(.index))
.attributes(.data("active", value: active == .effectiveLength ? "true" : "false"))
row(title: "Friction Rate", icon: .squareFunction, route: .frictionRate(.index))
.attributes(.data("active", value: active == .frictionRate ? "true" : "false"))
row(
title: "Friction Rate",
icon: .squareFunction,
route: .project(.detail(projectID, .frictionRate(.index)))
)
.attributes(.data("active", value: active == .frictionRate ? "true" : "false"))
row(title: "Duct Sizes", icon: .wind, href: "#")
.attributes(.data("active", value: active == .ductSizing ? "true" : "false"))