diff --git a/modules/engine/src/main/scala/observe/engine/Sequence.scala b/modules/engine/src/main/scala/observe/engine/Sequence.scala index 311e22f8b..23939766d 100644 --- a/modules/engine/src/main/scala/observe/engine/Sequence.scala +++ b/modules/engine/src/main/scala/observe/engine/Sequence.scala @@ -232,7 +232,7 @@ object Sequence { def isRunning[F[_]](st: State[F]): Boolean = st.status.isRunning - def userStopRequested[F[_]](st: State[F]): Boolean = st.status.userStopRequested + def userStopRequested[F[_]](st: State[F]): Boolean = st.status.isUserStopRequested def anyStopRequested[F[_]](st: State[F]): Boolean = st.status match { case SequenceState.Running(u, i, _, _) => u || i diff --git a/modules/model/shared/src/main/scala/observe/model/SequenceState.scala b/modules/model/shared/src/main/scala/observe/model/SequenceState.scala index e5a8bb510..d79c14782 100644 --- a/modules/model/shared/src/main/scala/observe/model/SequenceState.scala +++ b/modules/model/shared/src/main/scala/observe/model/SequenceState.scala @@ -26,18 +26,18 @@ enum SequenceState(val name: String) derives Eq, Encoder, Decoder: case Failed(msg: String) extends SequenceState("Failed") case Aborted extends SequenceState("Aborted") - def userStopRequested: Boolean = + def isUserStopRequested: Boolean = this match case SequenceState.Running(b, _, _, _) => b case _ => false - def internalStopRequested: Boolean = + def isInternalStopRequested: Boolean = this match case SequenceState.Running(_, b, _, _) => b case _ => false - def stopRequested: Boolean = - userStopRequested || internalStopRequested + def isStopRequested: Boolean = + isUserStopRequested || isInternalStopRequested def isError: Boolean = this match diff --git a/modules/model/shared/src/main/scala/observe/model/StepProgress.scala b/modules/model/shared/src/main/scala/observe/model/StepProgress.scala index 3c9de0ee5..9da341f35 100644 --- a/modules/model/shared/src/main/scala/observe/model/StepProgress.scala +++ b/modules/model/shared/src/main/scala/observe/model/StepProgress.scala @@ -23,6 +23,8 @@ enum StepProgress(val isNs: Boolean) derives Eq: def remaining: TimeSpan def stage: ObserveStage + def isAcquiring: Boolean = stage === ObserveStage.Acquiring + case Regular( stepId: Step.Id, total: TimeSpan, diff --git a/modules/web/client/src/main/scala/observe/ui/components/sequence/SeqControlButtons.scala b/modules/web/client/src/main/scala/observe/ui/components/sequence/SeqControlButtons.scala index d9926a0bf..7d9f089a3 100644 --- a/modules/web/client/src/main/scala/observe/ui/components/sequence/SeqControlButtons.scala +++ b/modules/web/client/src/main/scala/observe/ui/components/sequence/SeqControlButtons.scala @@ -32,7 +32,7 @@ case class SeqControlButtons( sequenceState: SequenceState, requests: ObservationRequests ) extends ReactFnProps(SeqControlButtons): - val isUserStopRequested: Boolean = sequenceState.userStopRequested + val isUserStopRequested: Boolean = sequenceState.isUserStopRequested val isPauseInFlight: Boolean = requests.pause === OperationRequest.InFlight diff --git a/modules/web/client/src/main/scala/observe/ui/components/sequence/steps/ControlButtonResolver.scala b/modules/web/client/src/main/scala/observe/ui/components/sequence/steps/ControlButtonResolver.scala index a9d509773..8c2f8fd38 100644 --- a/modules/web/client/src/main/scala/observe/ui/components/sequence/steps/ControlButtonResolver.scala +++ b/modules/web/client/src/main/scala/observe/ui/components/sequence/steps/ControlButtonResolver.scala @@ -11,7 +11,7 @@ sealed trait ControlButtonResolver[A]: def controlButtonsActive(a: A): Boolean = val (clientMode, state, isRunningStep) = extractor(a) - (clientMode.canOperate) && state.isRunning && ( /*step.isObserving || step.isObservePaused ||*/ isRunningStep || state.userStopRequested) + (clientMode.canOperate) && state.isRunning && ( /*step.isObserving || step.isObservePaused ||*/ isRunningStep || state.isUserStopRequested) object ControlButtonResolver: def build[A]( diff --git a/modules/web/client/src/main/scala/observe/ui/components/sequence/steps/StepControlButtons.scala b/modules/web/client/src/main/scala/observe/ui/components/sequence/steps/ExposureControlButtons.scala similarity index 88% rename from modules/web/client/src/main/scala/observe/ui/components/sequence/steps/StepControlButtons.scala rename to modules/web/client/src/main/scala/observe/ui/components/sequence/steps/ExposureControlButtons.scala index 11f4fcb7b..08454b1ed 100644 --- a/modules/web/client/src/main/scala/observe/ui/components/sequence/steps/StepControlButtons.scala +++ b/modules/web/client/src/main/scala/observe/ui/components/sequence/steps/ExposureControlButtons.scala @@ -27,16 +27,17 @@ import observe.ui.services.SequenceApi /** * Contains a set of control buttons like stop/abort */ -case class StepControlButtons( - obsId: Observation.Id, - instrument: Instrument, - sequenceState: SequenceState, - stepId: Step.Id, - isPausedInStep: Boolean, - isReadingOut: Boolean, - isMultiLevel: Boolean, - requests: ObservationRequests -) extends ReactFnProps(StepControlButtons): +case class ExposureControlButtons( + obsId: Observation.Id, + instrument: Instrument, + sequenceState: SequenceState, + stepId: Step.Id, + isPausedInStep: Boolean, + isAcquiring: Boolean, + isStopRequested: Boolean, + isMultiLevel: Boolean, + requests: ObservationRequests +) extends ReactFnProps(ExposureControlButtons): val operations: List[Operations] = instrument.operations(OperationLevel.Observation, isPausedInStep, isMultiLevel) @@ -44,8 +45,8 @@ case class StepControlButtons( val requestInFlight: Boolean = requests.stepRequestInFlight -object StepControlButtons - extends ReactFnComponent[StepControlButtons](props => +object ExposureControlButtons + extends ReactFnComponent[ExposureControlButtons](props => for ctx <- useContext(AppContext.ctx) sequenceApi <- useContext(SequenceApi.ctx) @@ -73,7 +74,8 @@ object StepControlButtons icon = Icons.Play.withFixedWidth(), tooltip = "Resume the current exposure", tooltipOptions = DefaultTooltipOptions, - disabled = props.requestInFlight || !props.isPausedInStep || props.isReadingOut, + disabled = + props.requestInFlight || !props.isPausedInStep || !props.isAcquiring || props.isStopRequested, onClickE = _.stopPropagationCB >> sequenceApi.resumeObs(props.obsId).runAsync ) case PauseObservation => @@ -82,7 +84,8 @@ object StepControlButtons icon = Icons.Pause.withFixedWidth(), tooltip = "Pause the current exposure", tooltipOptions = DefaultTooltipOptions, - disabled = props.requestInFlight || props.isPausedInStep || props.isReadingOut, + disabled = + props.requestInFlight || props.isPausedInStep || !props.isAcquiring || props.isStopRequested, onClickE = _.stopPropagationCB >> sequenceApi.pauseObs(props.obsId).runAsync ) case StopObservation => @@ -91,7 +94,7 @@ object StepControlButtons icon = Icons.Stop.withFixedWidth().withSize(IconSize.LG), tooltip = "Stop the current exposure early", tooltipOptions = DefaultTooltipOptions, - disabled = props.requestInFlight || props.isReadingOut, + disabled = props.requestInFlight || !props.isAcquiring || props.isStopRequested, onClickE = _.stopPropagationCB >> sequenceApi.stop(props.obsId).runAsync ) case AbortObservation => @@ -100,7 +103,7 @@ object StepControlButtons icon = Icons.XMark.withFixedWidth().withSize(IconSize.LG), tooltip = "Abort the current exposure", tooltipOptions = DefaultTooltipOptions, - disabled = props.requestInFlight || props.isReadingOut, + disabled = props.requestInFlight || !props.isAcquiring, onClickE = _.stopPropagationCB >> sequenceApi.abort(props.obsId).runAsync ) // // N&S operations diff --git a/modules/web/client/src/main/scala/observe/ui/components/sequence/steps/StepProgressCell.scala b/modules/web/client/src/main/scala/observe/ui/components/sequence/steps/StepProgressCell.scala index 000d086a5..124a83ea9 100644 --- a/modules/web/client/src/main/scala/observe/ui/components/sequence/steps/StepProgressCell.scala +++ b/modules/web/client/src/main/scala/observe/ui/components/sequence/steps/StepProgressCell.scala @@ -12,7 +12,6 @@ import lucuma.core.model.sequence.Step import lucuma.core.util.TimeSpan import lucuma.react.common.* import lucuma.ui.sequence.StepTypeDisplay -import observe.model.ObserveStage import observe.model.SequenceState import observe.model.StepProgress import observe.model.SystemOverrides @@ -68,18 +67,19 @@ case class StepProgressCell( // DetailRows.NoDetailRows def isStopping: Boolean = - requests.stop === OperationRequest.InFlight || sequenceState.stopRequested + requests.stop === OperationRequest.InFlight || sequenceState.isStopRequested object StepProgressCell extends ReactFnComponent[StepProgressCell](props => - val stepControlButtons: TagMod = - StepControlButtons( + val exposureControlButtons: TagMod = + ExposureControlButtons( props.obsId, props.instrument, props.sequenceState, props.stepId, props.isPausedInStep, - props.progress.exists(_.stage === ObserveStage.ReadingOut), + props.progress.exists(_.isAcquiring), + props.sequenceState.isStopRequested, false, // props.isNs, props.requests ) // .when(props.controlButtonsActive) @@ -137,7 +137,6 @@ object StepProgressCell val fileId = ImageFileId("") <.div(ObserveStyles.ConfiguringRow)( - stepControlButtons, SubsystemControls( props.obsId, props.stepId, @@ -148,6 +147,7 @@ object StepProgressCell props.systemOverrides, props.clientMode ), + exposureControlButtons, if (props.isBias) // BiasStatus( // props.obsIdName, diff --git a/modules/web/client/src/main/webapp/styles/observe.scss b/modules/web/client/src/main/webapp/styles/observe.scss index 671f393c0..95d9c04bd 100644 --- a/modules/web/client/src/main/webapp/styles/observe.scss +++ b/modules/web/client/src/main/webapp/styles/observe.scss @@ -740,6 +740,8 @@ body { &.ObserveStyles-controlButtonStrip { height: 21px; width: 84px; + padding-left: 0.2em; + padding-right: 0.5em; & > button { height: 100%;