feat: Begins air handler measurement form
This commit is contained in:
@@ -66,9 +66,13 @@ let package = Package(
|
|||||||
.target(
|
.target(
|
||||||
name: "StaticPressureFeature",
|
name: "StaticPressureFeature",
|
||||||
dependencies: [
|
dependencies: [
|
||||||
|
"EstimatedPressureDependency",
|
||||||
"SharedModels",
|
"SharedModels",
|
||||||
"Styleguide",
|
"Styleguide",
|
||||||
.product(name: "ComposableArchitecture", package: "swift-composable-architecture"),
|
.product(name: "ComposableArchitecture", package: "swift-composable-architecture"),
|
||||||
|
.product(name: "DependenciesAdditions", package: "swift-dependencies-additions"),
|
||||||
|
.product(name: "TCAExtras", package: "swift-tca-extras")
|
||||||
|
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|||||||
116
Sources/StaticPressureFeature/AirHandlerMeasurementForm.swift
Normal file
116
Sources/StaticPressureFeature/AirHandlerMeasurementForm.swift
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
import ComposableArchitecture
|
||||||
|
import DependenciesAdditions
|
||||||
|
import EstimatedPressureDependency
|
||||||
|
import SharedModels
|
||||||
|
import SwiftUI
|
||||||
|
import TCAExtras
|
||||||
|
|
||||||
|
@Reducer
|
||||||
|
public struct AirHandlerMeasurementForm {
|
||||||
|
|
||||||
|
@ObservableState
|
||||||
|
public struct State: Equatable {
|
||||||
|
public var calculatedMeasurement: EquipmentMeasurement.AirHandler?
|
||||||
|
public var focusedField: Field?
|
||||||
|
public var measurement: EquipmentMeasurement.AirHandler
|
||||||
|
public var updatedAirflow: Double?
|
||||||
|
|
||||||
|
public init(
|
||||||
|
calculatedMeasurement: EquipmentMeasurement.AirHandler? = nil,
|
||||||
|
focusedField: Field? = nil,
|
||||||
|
measurement: EquipmentMeasurement.AirHandler = .init(),
|
||||||
|
updatedAirflow: Double? = nil
|
||||||
|
) {
|
||||||
|
self.calculatedMeasurement = calculatedMeasurement
|
||||||
|
self.focusedField = focusedField
|
||||||
|
self.measurement = measurement
|
||||||
|
self.updatedAirflow = updatedAirflow
|
||||||
|
}
|
||||||
|
|
||||||
|
public var isValid: Bool {
|
||||||
|
return measurement.returnPlenumPressure != nil
|
||||||
|
&& measurement.postFilterPressure != nil
|
||||||
|
&& measurement.postCoilPressure != nil
|
||||||
|
&& measurement.supplyPlenumPressure != nil
|
||||||
|
&& measurement.airflow != nil
|
||||||
|
&& updatedAirflow != nil
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum Field: String, Equatable, CaseIterable, FocusableField {
|
||||||
|
case returnPlenumPressure
|
||||||
|
case postFilterPressure
|
||||||
|
case postCoilPressure
|
||||||
|
case supplyPlenumPressure
|
||||||
|
case airflow
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum Action: BindableAction, ViewAction {
|
||||||
|
case binding(BindingAction<State>)
|
||||||
|
case receive(TaskResult<EquipmentMeasurement.AirHandler?>)
|
||||||
|
case view(View)
|
||||||
|
|
||||||
|
@CasePathable
|
||||||
|
public enum View {
|
||||||
|
case submitField
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Dependency(\.estimatedPressuresClient) var estimatedPressuresClient
|
||||||
|
@Dependency(\.logger["\(Self.self)"]) var logger
|
||||||
|
|
||||||
|
public var body: some Reducer<State, Action> {
|
||||||
|
BindingReducer()
|
||||||
|
Reduce<State, Action> { state, action in
|
||||||
|
switch action {
|
||||||
|
case .binding:
|
||||||
|
return .none
|
||||||
|
|
||||||
|
case let .receive(.success(calculatedMeasurement)):
|
||||||
|
state.calculatedMeasurement = calculatedMeasurement
|
||||||
|
return .none
|
||||||
|
|
||||||
|
case .receive:
|
||||||
|
return .none
|
||||||
|
|
||||||
|
case let .view(action):
|
||||||
|
switch action {
|
||||||
|
|
||||||
|
case .submitField:
|
||||||
|
state.focusedField = state.focusedField?.next
|
||||||
|
guard state.isValid else { return .none }
|
||||||
|
return calculateEstimates(state: state)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.onFailure(case: \.receive, .log(logger: logger))
|
||||||
|
}
|
||||||
|
|
||||||
|
private func calculateEstimates(state: State) -> Effect<Action> {
|
||||||
|
.receive(action: \.receive) {
|
||||||
|
let result = try await estimatedPressuresClient.estimatedPressure(
|
||||||
|
for: .airHandler(state.measurement),
|
||||||
|
at: state.updatedAirflow ?? 0
|
||||||
|
)
|
||||||
|
|
||||||
|
guard case let .airHandler(airHandler) = result else {
|
||||||
|
return .none
|
||||||
|
}
|
||||||
|
return airHandler
|
||||||
|
}
|
||||||
|
// return .receive(action: \.recieve) {
|
||||||
|
// try await estimatedPressuresClient.estimatedM
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct EquipmentMeasurementFormView: View {
|
||||||
|
public var body: some View {
|
||||||
|
Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#Preview {
|
||||||
|
EquipmentMeasurementFormView()
|
||||||
|
}
|
||||||
21
Sources/StaticPressureFeature/FocusableField.swift
Normal file
21
Sources/StaticPressureFeature/FocusableField.swift
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
import Foundation
|
||||||
|
|
||||||
|
public protocol FocusableField {
|
||||||
|
var next: Self? { get }
|
||||||
|
}
|
||||||
|
|
||||||
|
extension FocusableField where Self: CaseIterable, Self: Equatable {
|
||||||
|
|
||||||
|
public var next: Self? {
|
||||||
|
|
||||||
|
guard let index = Self.allCases.firstIndex(of: self)
|
||||||
|
else { return nil }
|
||||||
|
|
||||||
|
let endIndex = Self.allCases.endIndex
|
||||||
|
let nextIndex = Self.allCases.index(after: index)
|
||||||
|
|
||||||
|
guard nextIndex < endIndex else { return nil }
|
||||||
|
return Self.allCases[nextIndex]
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1 +1,4 @@
|
|||||||
import Foundation
|
import ComposableArchitecture
|
||||||
|
import SharedModels
|
||||||
|
import SwiftUI
|
||||||
|
import TCAExtras
|
||||||
|
|||||||
Reference in New Issue
Block a user