141 lines
3.7 KiB
Swift
141 lines
3.7 KiB
Swift
import ComposableArchitecture
|
|
import DependenciesAdditions
|
|
import SharedModels
|
|
import Styleguide
|
|
import SwiftUI
|
|
import TCAExtras
|
|
|
|
#warning("Fix shared settings.")
|
|
@Reducer
|
|
public struct PressureEstimationsFeature {
|
|
|
|
public init() { }
|
|
|
|
@Reducer(state: .equatable)
|
|
public enum Destination {
|
|
case equipmentMeasurements(EquipmentMeasurementForm)
|
|
}
|
|
|
|
@ObservableState
|
|
public struct State: Equatable {
|
|
@Presents public var destination: Destination.State?
|
|
@Shared(.sharedPressureEstimationSettings) var sharedSettings = SharedPressureEstimationState()
|
|
public var equipmentSettings: EquipmentSettingsForm.State
|
|
|
|
public init(
|
|
destination: Destination.State? = nil,
|
|
sharedSettings: SharedPressureEstimationState = .init()
|
|
) {
|
|
self.destination = destination
|
|
self._sharedSettings = Shared(sharedSettings)
|
|
self._equipmentSettings = .init(sharedSettings: self._sharedSettings)
|
|
}
|
|
}
|
|
|
|
public enum Action: ViewAction {
|
|
case destination(PresentationAction<Destination.Action>)
|
|
case equipmentSettings(EquipmentSettingsForm.Action)
|
|
case view(View)
|
|
|
|
@CasePathable
|
|
public enum View {
|
|
case nextButtonTapped
|
|
}
|
|
}
|
|
|
|
@Dependency(\.logger["\(Self.self)"]) var logger
|
|
|
|
public var body: some Reducer<State, Action> {
|
|
Scope(state: \.equipmentSettings, action: \.equipmentSettings) {
|
|
EquipmentSettingsForm()
|
|
}
|
|
Reduce<State, Action> { state, action in
|
|
switch action {
|
|
case .destination:
|
|
return .none
|
|
|
|
case .equipmentSettings:
|
|
return .none
|
|
|
|
case let .view(action):
|
|
switch action {
|
|
case .nextButtonTapped:
|
|
return handleNextButtonTapped(&state)
|
|
}
|
|
}
|
|
}
|
|
.ifLet(\.$destination, action: \.destination)
|
|
}
|
|
|
|
private func handleNextButtonTapped(_ state: inout State) -> Effect<Action> {
|
|
guard state.destination == nil else {
|
|
return .fail(
|
|
"""
|
|
Received next button tapped action on equipment settings form, but the destination is not nil.
|
|
|
|
This is considered an application logic error.
|
|
""",
|
|
logger: logger
|
|
)
|
|
}
|
|
guard state.equipmentSettings.isValid else {
|
|
return .fail(
|
|
"""
|
|
Received next button tapped action on equipment settings form, but the form is invalid.
|
|
|
|
This is considered an application logic error.
|
|
""",
|
|
logger: logger
|
|
)
|
|
}
|
|
state.destination = .equipmentMeasurements(.init(
|
|
allowEquipmentTypeSelection: false,
|
|
sharedSettings: state.$sharedSettings,
|
|
equipmentType: state.equipmentSettings.equipmentType
|
|
))
|
|
return .none
|
|
}
|
|
|
|
}
|
|
|
|
@ViewAction(for: PressureEstimationsFeature.self)
|
|
public struct PressureEstimationsView: View {
|
|
|
|
@Bindable public var store: StoreOf<PressureEstimationsFeature>
|
|
|
|
public init(store: StoreOf<PressureEstimationsFeature>) {
|
|
self.store = store
|
|
}
|
|
|
|
public var body: some View {
|
|
EquipmentSettingsFormView(
|
|
store: store.scope(state: \.equipmentSettings, action: \.equipmentSettings)
|
|
)
|
|
.navigationTitle("Equipment Settings")
|
|
.toolbar {
|
|
NextButton { send(.nextButtonTapped) }
|
|
.nextButtonStyle(.toolbar)
|
|
.disabled(!store.equipmentSettings.isValid)
|
|
}
|
|
.navigationDestination(
|
|
item: $store.scope(
|
|
state: \.destination?.equipmentMeasurements,
|
|
action: \.destination.equipmentMeasurements
|
|
)
|
|
) { measurementStore in
|
|
EquipmentMeasurementFormView(store: measurementStore)
|
|
.navigationTitle("Existing Measurements")
|
|
}
|
|
}
|
|
}
|
|
|
|
#Preview {
|
|
NavigationStack {
|
|
PressureEstimationsView(
|
|
store: Store(initialState: PressureEstimationsFeature.State()) {
|
|
PressureEstimationsFeature()._printChanges()
|
|
}
|
|
)
|
|
}
|
|
}
|