WIP: Moves friction rate route to be part of project detail routes.
This commit is contained in:
@@ -103,6 +103,7 @@ let package = Package(
|
|||||||
.target(
|
.target(
|
||||||
name: "ViewController",
|
name: "ViewController",
|
||||||
dependencies: [
|
dependencies: [
|
||||||
|
.target(name: "DatabaseClient"),
|
||||||
.target(name: "ManualDCore"),
|
.target(name: "ManualDCore"),
|
||||||
.target(name: "Styleguide"),
|
.target(name: "Styleguide"),
|
||||||
.product(name: "Dependencies", package: "swift-dependencies"),
|
.product(name: "Dependencies", package: "swift-dependencies"),
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -15,7 +15,6 @@ extension SiteRoute.View {
|
|||||||
var middleware: [any Middleware]? {
|
var middleware: [any Middleware]? {
|
||||||
switch self {
|
switch self {
|
||||||
case .project,
|
case .project,
|
||||||
.frictionRate,
|
|
||||||
.effectiveLength:
|
.effectiveLength:
|
||||||
return viewRouteMiddleware
|
return viewRouteMiddleware
|
||||||
case .login, .signup:
|
case .login, .signup:
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ extension DatabaseClient {
|
|||||||
public var create:
|
public var create:
|
||||||
@Sendable (ComponentPressureLoss.Create) async throws -> ComponentPressureLoss
|
@Sendable (ComponentPressureLoss.Create) async throws -> ComponentPressureLoss
|
||||||
public var delete: @Sendable (ComponentPressureLoss.ID) async throws -> Void
|
public var delete: @Sendable (ComponentPressureLoss.ID) async throws -> Void
|
||||||
public var fetch: @Sendable (Project.ID) async throws -> ComponentPressureLoss
|
public var fetch: @Sendable (Project.ID) async throws -> [ComponentPressureLoss]
|
||||||
public var get: @Sendable (ComponentPressureLoss.ID) async throws -> ComponentPressureLoss?
|
public var get: @Sendable (ComponentPressureLoss.ID) async throws -> ComponentPressureLoss?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -34,14 +34,11 @@ extension DatabaseClient.ComponentLoss {
|
|||||||
try await model.delete(on: database)
|
try await model.delete(on: database)
|
||||||
},
|
},
|
||||||
fetch: { projectID in
|
fetch: { projectID in
|
||||||
guard
|
try await ComponentLossModel.query(on: database)
|
||||||
let model = try await ComponentLossModel.query(on: database)
|
.with(\.$project)
|
||||||
.filter("projectID", .equal, projectID)
|
.filter(\.$project.$id, .equal, projectID)
|
||||||
.first()
|
.all()
|
||||||
else {
|
.map { try $0.toDTO() }
|
||||||
throw NotFoundError()
|
|
||||||
}
|
|
||||||
return try model.toDTO()
|
|
||||||
|
|
||||||
},
|
},
|
||||||
get: { id in
|
get: { id in
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ extension SiteRoute {
|
|||||||
case login(LoginRoute)
|
case login(LoginRoute)
|
||||||
case signup(SignupRoute)
|
case signup(SignupRoute)
|
||||||
case project(ProjectRoute)
|
case project(ProjectRoute)
|
||||||
case frictionRate(FrictionRateRoute)
|
// case frictionRate(FrictionRateRoute)
|
||||||
case effectiveLength(EffectiveLengthRoute)
|
case effectiveLength(EffectiveLengthRoute)
|
||||||
// case user(UserRoute)
|
// case user(UserRoute)
|
||||||
|
|
||||||
@@ -24,9 +24,9 @@ extension SiteRoute {
|
|||||||
Route(.case(Self.project)) {
|
Route(.case(Self.project)) {
|
||||||
SiteRoute.View.ProjectRoute.router
|
SiteRoute.View.ProjectRoute.router
|
||||||
}
|
}
|
||||||
Route(.case(Self.frictionRate)) {
|
// Route(.case(Self.frictionRate)) {
|
||||||
SiteRoute.View.FrictionRateRoute.router
|
// SiteRoute.View.FrictionRateRoute.router
|
||||||
}
|
// }
|
||||||
Route(.case(Self.effectiveLength)) {
|
Route(.case(Self.effectiveLength)) {
|
||||||
SiteRoute.View.EffectiveLengthRoute.router
|
SiteRoute.View.EffectiveLengthRoute.router
|
||||||
}
|
}
|
||||||
@@ -102,12 +102,16 @@ extension SiteRoute.View.ProjectRoute {
|
|||||||
|
|
||||||
public enum DetailRoute: Equatable, Sendable {
|
public enum DetailRoute: Equatable, Sendable {
|
||||||
case index
|
case index
|
||||||
|
case frictionRate(FrictionRateRoute)
|
||||||
case rooms(RoomRoute)
|
case rooms(RoomRoute)
|
||||||
|
|
||||||
static let router = OneOf {
|
static let router = OneOf {
|
||||||
Route(.case(Self.index)) {
|
Route(.case(Self.index)) {
|
||||||
Method.get
|
Method.get
|
||||||
}
|
}
|
||||||
|
Route(.case(Self.frictionRate)) {
|
||||||
|
FrictionRateRoute.router
|
||||||
|
}
|
||||||
Route(.case(Self.rooms)) {
|
Route(.case(Self.rooms)) {
|
||||||
RoomRoute.router
|
RoomRoute.router
|
||||||
}
|
}
|
||||||
@@ -153,9 +157,7 @@ extension SiteRoute.View.ProjectRoute {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
extension SiteRoute.View {
|
|
||||||
public enum FrictionRateRoute: Equatable, Sendable {
|
public enum FrictionRateRoute: Equatable, Sendable {
|
||||||
case index
|
case index
|
||||||
case form(FormType, dismiss: Bool = false)
|
case form(FormType, dismiss: Bool = false)
|
||||||
@@ -179,15 +181,12 @@ extension SiteRoute.View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension SiteRoute.View.FrictionRateRoute {
|
public enum FormType: String, CaseIterable, Codable, Equatable, Sendable {
|
||||||
public enum FormType: String, CaseIterable, Codable, Equatable, Sendable {
|
case equipmentInfo
|
||||||
case equipmentInfo
|
case componentPressureLoss
|
||||||
case componentPressureLoss
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extension SiteRoute.View {
|
extension SiteRoute.View {
|
||||||
|
|||||||
@@ -39,10 +39,6 @@ extension ViewController.Request {
|
|||||||
}
|
}
|
||||||
case .project(let route):
|
case .project(let route):
|
||||||
return try await route.renderView(on: self)
|
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):
|
case .effectiveLength(let route):
|
||||||
return try await route.renderView(isHtmxRequest: isHtmxRequest)
|
return try await route.renderView(isHtmxRequest: isHtmxRequest)
|
||||||
// case .user(let route):
|
// case .user(let route):
|
||||||
@@ -110,6 +106,9 @@ extension SiteRoute.View.ProjectRoute {
|
|||||||
ProjectDetail(project: project)
|
ProjectDetail(project: project)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
case .frictionRate(let route):
|
||||||
|
return try await route.renderView(on: request, projectID: projectID)
|
||||||
|
|
||||||
case .rooms(let route):
|
case .rooms(let route):
|
||||||
return try await route.renderView(on: request, projectID: projectID)
|
return try await route.renderView(on: request, projectID: projectID)
|
||||||
}
|
}
|
||||||
@@ -155,26 +154,34 @@ extension SiteRoute.View.ProjectRoute.RoomRoute {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension SiteRoute.View.FrictionRateRoute {
|
extension SiteRoute.View.ProjectRoute.FrictionRateRoute {
|
||||||
func renderView(isHtmxRequest: Bool) async throws -> AnySendableHTML {
|
func renderView(on request: ViewController.Request, projectID: Project.ID) async throws
|
||||||
|
-> AnySendableHTML
|
||||||
|
{
|
||||||
|
@Dependency(\.database) var database
|
||||||
|
|
||||||
switch self {
|
switch self {
|
||||||
case .index:
|
case .index:
|
||||||
return _render(isHtmxRequest: isHtmxRequest, active: .frictionRate) {
|
let componentLosses = try await database.componentLoss.fetch(projectID)
|
||||||
FrictionRateView()
|
|
||||||
|
return request.view {
|
||||||
|
ProjectView(projectID: projectID, activeTab: .frictionRate) {
|
||||||
|
FrictionRateView(componentLosses: componentLosses, projectID: projectID)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
case .form(let type, let dismiss):
|
case .form(let type, let dismiss):
|
||||||
// FIX: Forms need to reference existing items.
|
// FIX: Forms need to reference existing items.
|
||||||
switch type {
|
switch type {
|
||||||
case .equipmentInfo:
|
case .equipmentInfo:
|
||||||
return EquipmentForm(dismiss: dismiss)
|
return EquipmentForm(dismiss: dismiss, projectID: projectID)
|
||||||
case .componentPressureLoss:
|
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 {
|
var id: String {
|
||||||
switch self {
|
switch self {
|
||||||
case .equipmentInfo:
|
case .equipmentInfo:
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import Styleguide
|
|||||||
|
|
||||||
struct ComponentLossForm: HTML, Sendable {
|
struct ComponentLossForm: HTML, Sendable {
|
||||||
let dismiss: Bool
|
let dismiss: Bool
|
||||||
|
let projectID: Project.ID
|
||||||
|
|
||||||
var body: some HTML {
|
var body: some HTML {
|
||||||
ModalForm(id: "componentLossForm", dismiss: dismiss) {
|
ModalForm(id: "componentLossForm", dismiss: dismiss) {
|
||||||
@@ -25,7 +26,10 @@ struct ComponentLossForm: HTML, Sendable {
|
|||||||
div {
|
div {
|
||||||
CancelButton()
|
CancelButton()
|
||||||
.attributes(
|
.attributes(
|
||||||
.hx.get(route: .frictionRate(.form(.componentPressureLoss, dismiss: true))),
|
.hx.get(
|
||||||
|
route: .project(
|
||||||
|
.detail(projectID, .frictionRate(.form(.componentPressureLoss, dismiss: true))))
|
||||||
|
),
|
||||||
.hx.target("#componentLossForm"),
|
.hx.target("#componentLossForm"),
|
||||||
.hx.swap(.outerHTML)
|
.hx.swap(.outerHTML)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -3,9 +3,12 @@ import ElementaryHTMX
|
|||||||
import ManualDCore
|
import ManualDCore
|
||||||
import Styleguide
|
import Styleguide
|
||||||
|
|
||||||
|
// TODO: Load component losses when view appears??
|
||||||
|
|
||||||
struct ComponentPressureLossesView: HTML, Sendable {
|
struct ComponentPressureLossesView: HTML, Sendable {
|
||||||
|
|
||||||
let componentPressureLosses: [ComponentPressureLoss]
|
let componentPressureLosses: [ComponentPressureLoss]
|
||||||
|
let projectID: Project.ID
|
||||||
|
|
||||||
private var total: Double {
|
private var total: Double {
|
||||||
componentPressureLosses.reduce(into: 0) { $0 += $1.value }
|
componentPressureLosses.reduce(into: 0) { $0 += $1.value }
|
||||||
@@ -23,7 +26,10 @@ struct ComponentPressureLossesView: HTML, Sendable {
|
|||||||
h1(.class("text-2xl font-bold")) { "Component Pressure Losses" }
|
h1(.class("text-2xl font-bold")) { "Component Pressure Losses" }
|
||||||
PlusButton()
|
PlusButton()
|
||||||
.attributes(
|
.attributes(
|
||||||
.hx.get(route: .frictionRate(.form(.componentPressureLoss, dismiss: false))),
|
.hx.get(
|
||||||
|
route: .project(
|
||||||
|
.detail(projectID, .frictionRate(.form(.componentPressureLoss, dismiss: false))))
|
||||||
|
),
|
||||||
.hx.target("#componentLossForm"),
|
.hx.target("#componentLossForm"),
|
||||||
.hx.swap(.outerHTML)
|
.hx.swap(.outerHTML)
|
||||||
)
|
)
|
||||||
@@ -43,8 +49,7 @@ struct ComponentPressureLossesView: HTML, Sendable {
|
|||||||
.attributes(.class("text-xl font-bold"))
|
.attributes(.class("text-xl font-bold"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// div(.id("componentLossForm")) {}
|
ComponentLossForm(dismiss: true, projectID: projectID)
|
||||||
ComponentLossForm(dismiss: true)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import Styleguide
|
|||||||
struct EquipmentForm: HTML, Sendable {
|
struct EquipmentForm: HTML, Sendable {
|
||||||
|
|
||||||
let dismiss: Bool
|
let dismiss: Bool
|
||||||
|
let projectID: Project.ID
|
||||||
|
|
||||||
var body: some HTML {
|
var body: some HTML {
|
||||||
ModalForm(id: "equipmentForm", dismiss: dismiss) {
|
ModalForm(id: "equipmentForm", dismiss: dismiss) {
|
||||||
@@ -33,7 +34,11 @@ struct EquipmentForm: HTML, Sendable {
|
|||||||
div(.class("space-x-4")) {
|
div(.class("space-x-4")) {
|
||||||
CancelButton()
|
CancelButton()
|
||||||
.attributes(
|
.attributes(
|
||||||
.hx.get(route: .frictionRate(.form(.equipmentInfo, dismiss: true))),
|
.hx.get(
|
||||||
|
route: .project(
|
||||||
|
.detail(projectID, .frictionRate(.form(.equipmentInfo, dismiss: true)))
|
||||||
|
)
|
||||||
|
),
|
||||||
.hx.target("#equipmentForm"),
|
.hx.target("#equipmentForm"),
|
||||||
.hx.swap(.outerHTML)
|
.hx.swap(.outerHTML)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import Styleguide
|
|||||||
|
|
||||||
struct EquipmentInfoView: HTML, Sendable {
|
struct EquipmentInfoView: HTML, Sendable {
|
||||||
let equipmentInfo: EquipmentInfo
|
let equipmentInfo: EquipmentInfo
|
||||||
|
var projectID: Project.ID { equipmentInfo.projectID }
|
||||||
|
|
||||||
var body: some HTML {
|
var body: some HTML {
|
||||||
div(.class("space-y-4 border border-gray-200 rounded-lg shadow-lg p-4")) {
|
div(.class("space-y-4 border border-gray-200 rounded-lg shadow-lg p-4")) {
|
||||||
@@ -33,7 +34,7 @@ struct EquipmentInfoView: HTML, Sendable {
|
|||||||
div {}
|
div {}
|
||||||
EditButton()
|
EditButton()
|
||||||
.attributes(
|
.attributes(
|
||||||
.hx.get(route: .frictionRate(.form(.equipmentInfo))),
|
.hx.get(route: .project(.detail(projectID, .frictionRate(.form(.equipmentInfo))))),
|
||||||
.hx.target("#equipmentForm"),
|
.hx.target("#equipmentForm"),
|
||||||
.hx.swap(.outerHTML)
|
.hx.swap(.outerHTML)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -4,11 +4,16 @@ import Styleguide
|
|||||||
|
|
||||||
struct FrictionRateView: HTML, Sendable {
|
struct FrictionRateView: HTML, Sendable {
|
||||||
|
|
||||||
|
let componentLosses: [ComponentPressureLoss]
|
||||||
|
let projectID: Project.ID
|
||||||
|
|
||||||
var body: some HTML {
|
var body: some HTML {
|
||||||
div(.class("p-4 space-y-6")) {
|
div(.class("p-4 space-y-6")) {
|
||||||
h1(.class("text-4xl font-bold pb-6")) { "Friction Rate" }
|
h1(.class("text-4xl font-bold pb-6")) { "Friction Rate" }
|
||||||
EquipmentInfoView(equipmentInfo: EquipmentInfo.mock)
|
EquipmentInfoView(equipmentInfo: EquipmentInfo.mock)
|
||||||
ComponentPressureLossesView(componentPressureLosses: ComponentPressureLoss.mock)
|
ComponentPressureLossesView(
|
||||||
|
componentPressureLosses: componentLosses, projectID: projectID
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,8 +65,12 @@ struct Sidebar: HTML {
|
|||||||
row(title: "Equivalent Lengths", icon: .rulerDimensionLine, route: .effectiveLength(.index))
|
row(title: "Equivalent Lengths", icon: .rulerDimensionLine, route: .effectiveLength(.index))
|
||||||
.attributes(.data("active", value: active == .effectiveLength ? "true" : "false"))
|
.attributes(.data("active", value: active == .effectiveLength ? "true" : "false"))
|
||||||
|
|
||||||
row(title: "Friction Rate", icon: .squareFunction, route: .frictionRate(.index))
|
row(
|
||||||
.attributes(.data("active", value: active == .frictionRate ? "true" : "false"))
|
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: "#")
|
row(title: "Duct Sizes", icon: .wind, href: "#")
|
||||||
.attributes(.data("active", value: active == .ductSizing ? "true" : "false"))
|
.attributes(.data("active", value: active == .ductSizing ? "true" : "false"))
|
||||||
|
|||||||
2
justfile
2
justfile
@@ -4,7 +4,7 @@ install-deps:
|
|||||||
@curl -sL daisyui.com/fast | bash
|
@curl -sL daisyui.com/fast | bash
|
||||||
|
|
||||||
run-css:
|
run-css:
|
||||||
@./tailwindcss -i input.css -o output.css --watch
|
@./tailwindcss -i Public/css/main.css -o Public/css/output.css --watch
|
||||||
|
|
||||||
run:
|
run:
|
||||||
@swift run App serve --log debug
|
@swift run App serve --log debug
|
||||||
|
|||||||
4051
output.css
4051
output.css
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user