From 4aca134abdbd1d0fe0d4a96a2ca340e5eb66c87b Mon Sep 17 00:00:00 2001 From: Michael Housh Date: Mon, 5 Jan 2026 07:38:25 -0500 Subject: [PATCH] WIP: --- Sources/ManualDCore/Routes/ViewRoute.swift | 26 +++--- Sources/Styleguide/HTMXExtensions.swift | 7 ++ Sources/ViewController/Live.swift | 5 +- .../EffectiveLength/EffectiveLengthForm.swift | 82 ++++++++++++++++--- Sources/ViewController/Views/MainPage.swift | 10 ++- 5 files changed, 101 insertions(+), 29 deletions(-) diff --git a/Sources/ManualDCore/Routes/ViewRoute.swift b/Sources/ManualDCore/Routes/ViewRoute.swift index a2832da..b7ecbc5 100644 --- a/Sources/ManualDCore/Routes/ViewRoute.swift +++ b/Sources/ManualDCore/Routes/ViewRoute.swift @@ -187,11 +187,12 @@ extension SiteRoute.View.FrictionRateRoute { case equipmentInfo case componentPressureLoss } + } extension SiteRoute.View { public enum EffectiveLengthRoute: Equatable, Sendable { - case field(FieldType) + case field(FieldType, style: EffectiveLength.EffectiveLengthType? = nil) case form(dismiss: Bool = false) case index @@ -220,6 +221,11 @@ extension SiteRoute.View { Method.get Query { Field("type") { FieldType.parser() } + Optionally { + Field("style", default: nil) { + EffectiveLength.EffectiveLengthType.parser() + } + } } } } @@ -231,19 +237,13 @@ extension SiteRoute.View.EffectiveLengthRoute { case straightLength case group } -} -// extension SiteRoute.View { -// public enum UserRoute: Equatable, Sendable { -// case signup(Signup) -// -// public static let router = OneOf { -// Route(.case(Self.signup)) { -// SiteRoute.View.UserRoute.Signup.router -// } -// } -// } -// } + public enum FormStep: String, CaseIterable, Equatable, Sendable { + case nameAndType + case straightLengths + case groups + } +} extension SiteRoute.View { diff --git a/Sources/Styleguide/HTMXExtensions.swift b/Sources/Styleguide/HTMXExtensions.swift index 5e79840..d6d4736 100644 --- a/Sources/Styleguide/HTMXExtensions.swift +++ b/Sources/Styleguide/HTMXExtensions.swift @@ -28,3 +28,10 @@ extension HTMLAttribute.hx { // delete(SiteRoute.Api.router.path(for: route)) // } } + +extension HTMLAttribute.hx { + @Sendable + public static func indicator() -> HTMLAttribute { + indicator(".hx-indicator") + } +} diff --git a/Sources/ViewController/Live.swift b/Sources/ViewController/Live.swift index 98b0705..fbac6da 100644 --- a/Sources/ViewController/Live.swift +++ b/Sources/ViewController/Live.swift @@ -196,12 +196,13 @@ extension SiteRoute.View.EffectiveLengthRoute { case .form(let dismiss): return EffectiveLengthForm(dismiss: dismiss) - case .field(let type): + case .field(let type, let style): switch type { case .straightLength: return StraightLengthField() case .group: - return GroupField() + // FIX: + return GroupField(style: style ?? .supply) } } } diff --git a/Sources/ViewController/Views/EffectiveLength/EffectiveLengthForm.swift b/Sources/ViewController/Views/EffectiveLength/EffectiveLengthForm.swift index 1bbc11d..8cba94e 100644 --- a/Sources/ViewController/Views/EffectiveLength/EffectiveLengthForm.swift +++ b/Sources/ViewController/Views/EffectiveLength/EffectiveLengthForm.swift @@ -3,8 +3,20 @@ import ElementaryHTMX import ManualDCore import Styleguide +// TODO: May need a multi-step form were the the effective length type is +// determined before groups selections are made in order to use the +// appropriate select field values when the type is supply vs. return. +// Currently when the select field is changed it doesn't change the group +// I can get it to add a new one. + struct EffectiveLengthForm: HTML, Sendable { let dismiss: Bool + let type: EffectiveLength.EffectiveLengthType + + init(dismiss: Bool, type: EffectiveLength.EffectiveLengthType = .supply) { + self.dismiss = dismiss + self.type = type + } var body: some HTML { ModalForm(id: "effectiveLengthForm", dismiss: dismiss) { @@ -17,13 +29,8 @@ struct EffectiveLengthForm: HTML, Sendable { } div { label(.for("type")) { "Type" } - select( - .id("type"), .name("type"), - .class("w-full border rounded-md") - ) { - option(.value("supply")) { "Supply" } - option(.value("return")) { "Return" } - } + GroupTypeSelect(selected: type) + .attributes(.class("w-full border rounded-md")) } Row { Label { "Straigth Lengths" } @@ -44,7 +51,7 @@ struct EffectiveLengthForm: HTML, Sendable { Label { "Groups" } button( .type(.button), - .hx.get(route: .effectiveLength(.field(.group))), + .hx.get(route: .effectiveLength(.field(.group, style: type))), .hx.target("#groups"), .hx.swap(.beforeEnd) ) { @@ -52,7 +59,7 @@ struct EffectiveLengthForm: HTML, Sendable { } } div(.id("groups"), .class("space-y-4")) { - GroupField() + GroupField(style: type) } Row { @@ -92,10 +99,13 @@ struct StraightLengthField: HTML, Sendable { struct GroupField: HTML, Sendable { + let style: EffectiveLength.EffectiveLengthType + var body: some HTML { Row { - Input(name: "group[][group]", placeholder: "Group") - .attributes(.type(.number), .min("0")) + // Input(name: "group[][group]", placeholder: "Group") + // .attributes(.type(.number), .min("0")) + GroupSelect(style: style) Input(name: "group[][letter]", placeholder: "Letter") .attributes(.type(.text)) Input(name: "group[][length]", placeholder: "Length") @@ -106,3 +116,53 @@ struct GroupField: HTML, Sendable { .attributes(.class("space-x-2")) } } + +struct GroupSelect: HTML, Sendable { + + let style: EffectiveLength.EffectiveLengthType + + var body: some HTML { + select( + .name("group") + ) { + for value in style.selectOptions { + option(.value("\(value)")) { "\(value)" } + } + } + } + +} + +struct GroupTypeSelect: HTML, Sendable { + + var selected: EffectiveLength.EffectiveLengthType + + var body: some HTML { + select(.name("type"), .id("type")) { + for value in EffectiveLength.EffectiveLengthType.allCases { + option( + .value("\(value.rawValue)"), + .hx.get(route: .effectiveLength(.field(.group, style: value))), + .hx.target("#groups"), + .hx.swap(.beforeEnd), + .hx.trigger(.event(.change).from("#type")) + ) { value.title } + .attributes(.selected, when: value == selected) + } + } + } +} + +extension EffectiveLength.EffectiveLengthType { + + var title: String { rawValue.capitalized } + + var selectOptions: [Int] { + switch self { + case .return: + return [5, 6, 7, 8, 10, 11, 12] + case .supply: + return [1, 2, 4, 8, 9, 11, 12] + } + } +} diff --git a/Sources/ViewController/Views/MainPage.swift b/Sources/ViewController/Views/MainPage.swift index a95b5d6..12356ab 100644 --- a/Sources/ViewController/Views/MainPage.swift +++ b/Sources/ViewController/Views/MainPage.swift @@ -37,15 +37,19 @@ public struct MainPage: SendableHTMLDocument where Inner: Sendable } struct LoggedIn: HTML, Sendable { - let next: String? + let next: String + + init(next: String? = nil) { + self.next = next ?? SiteRoute.View.router.path(for: .project(.index)) + } var body: some HTML { div( - .hx.get(next ?? SiteRoute.View.router.path(for: .project(.index))), + .hx.get(next), .hx.pushURL(true), .hx.target("body"), .hx.trigger(.event(.revealed)), - .hx.indicator(".hx-indicator") + .hx.indicator() ) { Indicator() }