feat: Adding improvements to pressure estimations feature.
This commit is contained in:
@@ -3,35 +3,82 @@ import SharedModels
|
||||
import Styleguide
|
||||
import SwiftUI
|
||||
|
||||
#warning("Use shared settings, don't display filter pressure drop if current flagged measurement pressure drop is not set.")
|
||||
@Reducer
|
||||
public struct EstimationForm {
|
||||
public init() { }
|
||||
|
||||
@ObservableState
|
||||
public struct State: Equatable, Sendable {
|
||||
public var cfmPerTon: Int
|
||||
@SharedReader public var existingMeasurement: EquipmentMeasurement?
|
||||
|
||||
public let id: SharedPressureEstimationState.FlaggedEstimationContainer.ID?
|
||||
public var airflowSelection: AirflowSelection
|
||||
public var cfmTextField: Int?
|
||||
public var coolingCapacity: EquipmentMetadata.CoolingCapacity
|
||||
public var filterPressureDrop: Double?
|
||||
public var name: String
|
||||
|
||||
public init(
|
||||
cfmPerTon: Int = 350,
|
||||
id: SharedPressureEstimationState.FlaggedEstimationContainer.ID? = nil,
|
||||
existingMeasurement: SharedReader<EquipmentMeasurement?>,
|
||||
airflowSelection: AirflowSelection = .cfmPerTon,
|
||||
cfmTextField: Int? = nil,
|
||||
coolingCapacity: EquipmentMetadata.CoolingCapacity = .default,
|
||||
filterPressureDrop: Double? = nil,
|
||||
name: String = ""
|
||||
) {
|
||||
self.cfmPerTon = cfmPerTon
|
||||
self.id = id
|
||||
self._existingMeasurement = existingMeasurement
|
||||
self.airflowSelection = airflowSelection
|
||||
self.cfmTextField = cfmTextField
|
||||
self.filterPressureDrop = filterPressureDrop
|
||||
self.coolingCapacity = coolingCapacity
|
||||
self.name = name
|
||||
}
|
||||
|
||||
public var airflow: Double {
|
||||
Double(cfmPerTon) * coolingCapacity.rawValue
|
||||
let cfmTextField = Double(self.cfmTextField ?? 0)
|
||||
switch airflowSelection {
|
||||
case .cfmPerTon:
|
||||
return Double(cfmTextField) * coolingCapacity.rawValue
|
||||
case .cfm:
|
||||
return Double(cfmTextField)
|
||||
}
|
||||
}
|
||||
|
||||
public var isValid: Bool { !name.isEmpty }
|
||||
public var isValid: Bool {
|
||||
!name.isEmpty
|
||||
&& cfmTextField != nil
|
||||
}
|
||||
|
||||
// Note: Keep in display order of the picker.
|
||||
public enum AirflowSelection: Hashable, CaseIterable, Identifiable, CustomStringConvertible {
|
||||
case cfmPerTon
|
||||
case cfm
|
||||
|
||||
init(
|
||||
_ container: SharedPressureEstimationState.FlaggedEstimationContainer.EstimationState.CFMContainer
|
||||
) {
|
||||
switch container {
|
||||
case .cfm:
|
||||
self = .cfm
|
||||
case .cfmPerTon:
|
||||
self = .cfmPerTon
|
||||
}
|
||||
}
|
||||
|
||||
public var id: Self { self }
|
||||
|
||||
public var description: String {
|
||||
switch self {
|
||||
case .cfm:
|
||||
return "CFM"
|
||||
case .cfmPerTon:
|
||||
return "CFM / Ton"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public enum Action: BindableAction {
|
||||
@@ -68,47 +115,61 @@ public struct EstimationFormView: View {
|
||||
}
|
||||
}
|
||||
Section("Airflow") {
|
||||
Grid(alignment: .leading, horizontalSpacing: 40) {
|
||||
GridRow {
|
||||
HStack {
|
||||
TextLabel("Capacity")
|
||||
Spacer()
|
||||
CoolingCapacityPicker(
|
||||
selection: $store.coolingCapacity
|
||||
)
|
||||
VStack {
|
||||
CaseIterablePicker(
|
||||
"Airflow Type",
|
||||
selection: $store.airflowSelection
|
||||
)
|
||||
.pickerStyle(.segmented)
|
||||
|
||||
Grid(alignment: .leading, horizontalSpacing: 40) {
|
||||
if store.airflowSelection == .cfmPerTon {
|
||||
GridRow {
|
||||
HStack {
|
||||
TextLabel("Capacity")
|
||||
Spacer()
|
||||
CoolingCapacityPicker(
|
||||
selection: $store.coolingCapacity
|
||||
)
|
||||
}
|
||||
.gridCellColumns(2)
|
||||
}
|
||||
}
|
||||
.gridCellColumns(2)
|
||||
}
|
||||
GridRow {
|
||||
HStack {
|
||||
TextLabel("CFM / Ton")
|
||||
Spacer()
|
||||
TextField(
|
||||
"CFM / Ton",
|
||||
value: $store.cfmPerTon,
|
||||
format: .number,
|
||||
prompt: Text("CFM")
|
||||
)
|
||||
.frame(width: 100)
|
||||
.numberPad()
|
||||
GridRow {
|
||||
HStack {
|
||||
TextLabel(store.airflowSelection.description)
|
||||
Spacer()
|
||||
TextField(
|
||||
"CFM / Ton",
|
||||
value: $store.cfmTextField,
|
||||
format: .number,
|
||||
prompt: Text("CFM")
|
||||
)
|
||||
.frame(width: 100)
|
||||
.numberPad()
|
||||
}
|
||||
.gridCellColumns(2)
|
||||
}
|
||||
.gridCellColumns(2)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Section("Filter Pressure Drop") {
|
||||
HStack {
|
||||
TextLabel("Pressure Drop")
|
||||
Spacer()
|
||||
TextField(
|
||||
"Filter Drop",
|
||||
value: $store.filterPressureDrop,
|
||||
fractionLength: 2,
|
||||
prompt: Text("Optional")
|
||||
)
|
||||
.frame(width: 100)
|
||||
.decimalPad()
|
||||
if let existingsMeasurement = store.existingMeasurement,
|
||||
existingsMeasurement.hasFilterDrop
|
||||
{
|
||||
Section("Filter Pressure Drop") {
|
||||
HStack {
|
||||
TextLabel("Pressure Drop")
|
||||
Spacer()
|
||||
TextField(
|
||||
"Filter Drop",
|
||||
value: $store.filterPressureDrop,
|
||||
fractionLength: 2,
|
||||
prompt: Text("Optional")
|
||||
)
|
||||
.frame(width: 100)
|
||||
.decimalPad()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -118,9 +179,27 @@ public struct EstimationFormView: View {
|
||||
}
|
||||
}
|
||||
|
||||
fileprivate extension EquipmentMeasurement {
|
||||
|
||||
var hasFilterDrop: Bool {
|
||||
switch self {
|
||||
case let .airHandler(airHandler):
|
||||
return airHandler.postFilterPressure > 0
|
||||
case let .furnaceAndCoil(furnace):
|
||||
return furnace.postFilterPressure > 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#Preview {
|
||||
EstimationFormView(
|
||||
store: Store(initialState: EstimationForm.State()) {
|
||||
store: Store(
|
||||
initialState: EstimationForm.State(
|
||||
existingMeasurement: SharedReader(
|
||||
Shared(EquipmentMeasurement.mock(type: .airHandler))
|
||||
)
|
||||
)
|
||||
) {
|
||||
EstimationForm()
|
||||
}
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user