feat: Working on pressure estimations feature, integrating all views and shared settings

This commit is contained in:
2024-06-10 13:34:38 -04:00
parent 51f7a30701
commit a6bfbd6877
15 changed files with 447 additions and 348 deletions

View File

@@ -1,9 +1,9 @@
import ComposableArchitecture
import DependenciesAdditions
import SharedModels
import Styleguide
import SwiftUI
@Reducer
public struct EquipmentMeasurementForm {
@@ -11,12 +11,14 @@ public struct EquipmentMeasurementForm {
@Reducer(state: .equatable)
public enum Destination {
case flaggedMeasurementsList(FlaggedMeasurementsList)
case infoView(InfoViewFeature)
}
@ObservableState
public struct State: Equatable {
@Presents public var destination: Destination.State?
@Shared public var sharedSettings: SharedPressureEstimationSettings
public var allowEquipmentTypeSelection: Bool
public var equipmentType: EquipmentMeasurement.EquipmentType
public var focusedField: Field?
@@ -25,12 +27,14 @@ public struct EquipmentMeasurementForm {
public init(
allowEquipmentTypeSelection: Bool = true,
destination: Destination.State? = nil,
sharedSettings: Shared<SharedPressureEstimationSettings>,
equipmentType: EquipmentMeasurement.EquipmentType = .airHandler,
focusedField: Field? = nil,
measurements: Measurements = .init()
) {
self.allowEquipmentTypeSelection = allowEquipmentTypeSelection
self.destination = destination
self._sharedSettings = sharedSettings
self.equipmentType = equipmentType
self.focusedField = focusedField
self.measurements = measurements
@@ -39,14 +43,27 @@ public struct EquipmentMeasurementForm {
public var equipmentMeasurement: EquipmentMeasurement {
measurements.equipmentMeasurement(type: equipmentType)
}
public var isValid: Bool {
measurements.airflow != nil
private var baseValidations: Bool {
return measurements.airflow != nil
&& measurements.returnPlenumPressure != nil
&& measurements.postFilterPressure != nil
&& measurements.coilPressure != nil
&& measurements.supplyPlenumPressure != nil
}
private var furnaceAndCoilValidations: Bool {
return measurements.postFilterPressure != nil
&& measurements.coilPressure != nil
&& baseValidations
}
public var isValid: Bool {
switch equipmentType {
case .airHandler:
return baseValidations
case .furnaceAndCoil:
return furnaceAndCoilValidations
}
}
public struct Measurements: Equatable {
public var airflow: Double?
@@ -96,23 +113,24 @@ public struct EquipmentMeasurementForm {
type: EquipmentMeasurement.EquipmentType
) -> EquipmentMeasurement {
switch type {
case .airHandler:
return .airHandler(.init(
airflow: airflow,
returnPlenumPressure: returnPlenumPressure,
postFilterPressure: postFilterPressure,
postCoilPressure: coilPressure,
supplyPlenumPressure: supplyPlenumPressure
airflow: airflow ?? 0,
manufacturersIncludedFilterPressureDrop: 0.1,
returnPlenumPressure: returnPlenumPressure ?? 0,
postFilterPressure: postFilterPressure ?? 0,
postCoilPressure: coilPressure ?? 0,
supplyPlenumPressure: supplyPlenumPressure ?? 0
))
case .furnaceAndCoil:
return .furnaceAndCoil(.init(
airflow: airflow,
returnPlenumPressure: returnPlenumPressure,
postFilterPressure: postFilterPressure,
preCoilPressure: coilPressure,
supplyPlenumPressure: supplyPlenumPressure
airflow: airflow ?? 0,
manufacturersIncludedFilterPressureDrop: 0,
returnPlenumPressure: returnPlenumPressure ?? 0,
postFilterPressure: postFilterPressure ?? 0,
preCoilPressure: coilPressure ?? 0,
supplyPlenumPressure: supplyPlenumPressure ?? 0
))
}
}
@@ -138,11 +156,15 @@ public struct EquipmentMeasurementForm {
@CasePathable
public enum View {
case infoButtonTapped
case nextButtonTapped
case onAppear
case resetButtonTapped
case submitField
}
}
@Dependency(\.logger["\(Self.self)"]) var logger
public var body: some Reducer<State, Action> {
BindingReducer()
Reduce<State, Action> { state, action in
@@ -160,12 +182,37 @@ public struct EquipmentMeasurementForm {
case .infoButtonTapped:
state.destination = .infoView(.init())
return .none
case .nextButtonTapped:
guard state.isValid else {
return .fail(
"""
Received next button tapped action, but the state is not valid.
This is considered an application logic error.
""",
logger: logger
)
}
state.sharedSettings.equipmentMeasurement = state.equipmentMeasurement
state.destination = .flaggedMeasurementsList(.init(sharedSettings: state.$sharedSettings))
return .none
case .onAppear:
guard let measurement = state.sharedSettings.equipmentMeasurement else {
return .none
}
state.measurements = .init(equipmentMeasurement: measurement)
return .none
case .resetButtonTapped:
state.measurements = .init()
return .none
case .submitField:
if state.focusedField == .airflow {
return .send(.view(.nextButtonTapped))
}
state.focusedField = state.focusedField?.next
return .none
@@ -183,6 +230,12 @@ extension Store where State == EquipmentMeasurementForm.State {
) -> String {
let label = label(field: field)
guard field != .airflow else { return label }
if field == .coilPressure && state.equipmentType == .airHandler {
return "\(label) (Optional)"
}
if field == .postFilterPressure && state.equipmentType == .airHandler {
return "\(label) (Optional)"
}
return "\(label) Pressure"
}
@@ -269,8 +322,14 @@ public struct EquipmentMeasurementFormView: View {
}
}
}
.onAppear { send(.onAppear) }
.textLabelStyle(.boldSecondary)
.textFieldStyle(.roundedBorder)
.toolbar {
NextButton { send(.nextButtonTapped) }
.nextButtonStyle(.toolbar)
.disabled(!store.isValid)
}
.sheet(
item: $store.scope(state: \.destination?.infoView, action: \.destination.infoView)
){ store in
@@ -278,6 +337,14 @@ public struct EquipmentMeasurementFormView: View {
InfoView(store: store)
}
}
.navigationDestination(
item: $store.scope(
state: \.destination?.flaggedMeasurementsList,
action: \.destination.flaggedMeasurementsList
)
) { store in
FlaggedMeasurementListView(store: store)
}
}
private func textField(
@@ -350,7 +417,9 @@ fileprivate extension InfoViewFeature.State {
#Preview {
NavigationStack {
EquipmentMeasurementFormView(
store: Store(initialState: EquipmentMeasurementForm.State()) {
store: Store(initialState: EquipmentMeasurementForm.State(
sharedSettings: Shared(SharedPressureEstimationSettings()))
) {
EquipmentMeasurementForm()
}
)