feat: Working on pressure estimations feature, integrating all views and shared settings
This commit is contained in:
@@ -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()
|
||||
}
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user