Skip to content

Commit

Permalink
Merge pull request #4281 from gemini-hlsw/unrequested-configs
Browse files Browse the repository at this point in the history
  • Loading branch information
toddburnside authored Nov 4, 2024
2 parents 6902c68 + 8360d29 commit 5cae632
Show file tree
Hide file tree
Showing 15 changed files with 589 additions and 199 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,9 @@ object ExploreStyles:
val TargetSearchPreviewPlaceholder: Css = Css("explore-target-search-preview-placeholder")
val TargetSearchResults: Css = Css("explore-target-search-results")

// Configuration Request Editor Popup
val ConfigurationRequestEditorPopup: Css = Css("explore-config-request-editor")

// Aladin Target classes
val ScienceTarget: Css = Css("science-target")
val ScienceSelectedTarget: Css = Css("science-selected-target")
Expand Down
14 changes: 11 additions & 3 deletions common/src/main/scala/explore/model/ExploreGridLayouts.scala
Original file line number Diff line number Diff line change
Expand Up @@ -305,9 +305,10 @@ object ExploreGridLayouts:
end observationList

object programs:
private lazy val DetailsHeight: NonNegInt = 6.refined
private lazy val NotesHeight: NonNegInt = 6.refined
private lazy val ChangeRequestsHeight: NonNegInt = 6.refined
private lazy val DetailsHeight: NonNegInt = 6.refined
private lazy val NotesHeight: NonNegInt = 6.refined
private lazy val ChangeRequestsHeight: NonNegInt = 6.refined
private lazy val UnrequestedConfigsHeight: NonNegInt = 6.refined

private lazy val layoutMedium: Layout = Layout(
List(
Expand All @@ -331,6 +332,13 @@ object ExploreGridLayouts:
y = (DetailsHeight |+| NotesHeight).value,
w = DefaultWidth.value,
h = ChangeRequestsHeight.value
),
LayoutItem(
i = ProgramTabTileIds.UnrequestedConfigsId.id.value,
x = 0,
y = (DetailsHeight |+| NotesHeight |+| ChangeRequestsHeight).value,
w = DefaultWidth.value,
h = UnrequestedConfigsHeight.value
)
)
)
Expand Down
14 changes: 14 additions & 0 deletions common/src/main/webapp/sass/explore.scss
Original file line number Diff line number Diff line change
Expand Up @@ -1994,6 +1994,20 @@ svg.fa-triangle-exclamation.explore-error-icon {
vertical-align: middle;
}

// -------
// Configuration Request Editor Popup
// -------
.explore-config-request-editor {
textarea {
width: 100%;
height: 9rem;
}

.p-dialog-footer .p-button:first-child {
float: left;
}
}

// ------
// Proposals and Partner Splits
// ------
Expand Down
4 changes: 3 additions & 1 deletion explore/src/main/scala/explore/Routing.scala
Original file line number Diff line number Diff line change
Expand Up @@ -169,8 +169,10 @@ object Routing:
yield ProgramTabContents(
routingInfo.programId,
programDetails,
programSummaries.get.configurationRequests,
programSummaries.model.zoom(ProgramSummaries.configurationRequests),
programSummaries.model.zoom(ProgramSummaries.observations),
programSummaries.get.obs4ConfigRequests,
programSummaries.get.configsWithoutRequests,
programSummaries.get.targets,
model.rootModel.zoom(RootModel.vault).get,
programSummaries.get.programTimesPot,
Expand Down
23 changes: 23 additions & 0 deletions explore/src/main/scala/explore/model/AppContext.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ import fs2.dom.BroadcastChannel
import japgolly.scalajs.react.*
import japgolly.scalajs.react.extra.router.SetRouteVia
import japgolly.scalajs.react.feature.Context
import japgolly.scalajs.react.vdom.html_<^.*
import lucuma.core.enums.ExecutionEnvironment
import lucuma.core.model.Observation
import lucuma.core.model.Program
import lucuma.react.primereact.ToastRef
import lucuma.schemas.ObservationDB
Expand Down Expand Up @@ -53,6 +55,27 @@ case class AppContext[F[_]](
def replacePage(appTab: AppTab, programId: Program.Id, focused: Focused): Callback =
setPageVia(appTab, programId, focused, SetRouteVia.HistoryReplace)

def routingLink(
appTab: AppTab,
programId: Program.Id,
focused: Focused,
text: String,
via: SetRouteVia = SetRouteVia.HistoryPush
): VdomNode =
<.a(^.href := pageUrl(appTab, programId, focused),
^.onClick ==> (e =>
e.preventDefaultCB >> e.stopPropagationCB >>
setPageVia(appTab, programId, focused, via)
)
)(text)

def obsIdRoutingLink(
programId: Program.Id,
obsId: Observation.Id,
via: SetRouteVia = SetRouteVia.HistoryPush
): VdomNode =
routingLink(AppTab.Observations, programId, Focused.singleObs(obsId), obsId.show)

given WebSocketJSClient[F, ObservationDB] = clients.odb
given WebSocketJSClient[F, UserPreferencesDB] = clients.preferencesDB
given FetchJSClient[F, SSO] = clients.sso
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -186,55 +186,20 @@ object ObsSummaryTable:
ctx.pushPage(AppTab.Constraints, props.programId, Focused.singleObs(constraintId))

def targetLink(obsId: Observation.Id, tWId: TargetWithId): VdomNode =
<.a(
^.href := ctx.pageUrl(
AppTab.Observations,
props.programId,
Focused.singleObs(obsId, tWId.id.some)
),
^.onClick ==> (e =>
e.preventDefaultCB >> e.stopPropagationCB >>
ctx.pushPage(
AppTab.Observations,
props.programId,
Focused.singleObs(obsId, tWId.id.some)
)
)
)(tWId.target.name.value)
val text = tWId.target.name.value
ctx.routingLink(
AppTab.Observations,
props.programId,
Focused.singleObs(obsId, tWId.id.some),
text
)

def obsLink(obsId: Observation.Id): VdomNode =
<.a(
^.href := ctx.pageUrl(
AppTab.Observations,
props.programId,
Focused.singleObs(obsId)
),
^.onClick ==> { (e: ReactMouseEvent) =>
e.preventDefaultCB >> e.stopPropagationCB >>
ctx.pushPage(
AppTab.Observations,
props.programId,
Focused.singleObs(obsId)
)
}
)(obsId.toString)
ctx.obsIdRoutingLink(props.programId, obsId)

def groupLink(group: Group): VdomNode =
<.a(
^.href := ctx.pageUrl(
AppTab.Observations,
props.programId,
Focused.group(group.id)
),
^.onClick ==> { (e: ReactMouseEvent) =>
e.preventDefaultCB >> e.stopPropagationCB >>
ctx.pushPage(
AppTab.Observations,
props.programId,
Focused.group(group.id)
)
}
)(group.name.map(_.toString).getOrElse(group.id.toString))
val text = group.name.map(_.toString).getOrElse(group.id.toString)
ctx.routingLink(AppTab.Observations, props.programId, Focused.group(group.id), text)

List(
ColDef(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
// Copyright (c) 2016-2023 Association of Universities for Research in Astronomy, Inc. (AURA)
// For license information see LICENSE or https://opensource.org/licenses/BSD-3-Clause

package explore.programs

import cats.syntax.all.*
import crystal.react.hooks.*
import explore.Icons
import explore.components.ui.ExploreStyles
import explore.model.AppContext
import japgolly.scalajs.react.*
import japgolly.scalajs.react.vdom.html_<^.*
import lucuma.core.util.NewType
import lucuma.react.common.ReactFnProps
import lucuma.react.primereact.Button
import lucuma.react.primereact.Dialog
import lucuma.react.primereact.DialogPosition
import lucuma.react.primereact.Divider
import lucuma.refined.*
import lucuma.ui.primereact.*
import lucuma.ui.primereact.given

case class ConfigurationRequestEditorPopup(
trigger: Button,
onSubmit: String => Callback
) extends ReactFnProps(ConfigurationRequestEditorPopup.component)

object ConfigurationRequestEditorPopup:
private type Props = ConfigurationRequestEditorPopup

private object PopupState extends NewType[Boolean]:
inline def Open: PopupState = PopupState(true)
inline def Closed: PopupState = PopupState(false)

private type PopupState = PopupState.Type

val component = ScalaFnComponent
.withHooks[Props]
.useContext(AppContext.ctx)
.useStateView(PopupState.Closed)
.useStateView("") // message
.render: (props, ctx, popupState, message) =>
val close = popupState.set(PopupState.Closed)

val notice =
"""Please briefly describe and justify the requested changes to the approved
|coordinates + instrument configurations + constraints. These changes will
|be approved by the Head of Science Operations at the site of the observations.
""".stripMargin.linesIterator.mkString(" ")

val footer = React.Fragment(
Button(
label = "Clear Text",
icon = Icons.Eraser,
disabled = message.get.isEmpty,
onClick = message.set("")
).small,
Button(
label = "Cancel",
icon = Icons.Close,
severity = Button.Severity.Danger,
onClick = close
).small,
Button(
label = "Submit",
icon = Icons.PaperPlaneTop,
disabled = message.get.isBlank,
onClick = close >> props.onSubmit(message.get)
).small
)

React.Fragment(
props.trigger.copy(onClick = props.trigger.onClick >> popupState.set(PopupState.Open)),
Dialog(
visible = popupState.get.value,
onHide = close,
closable = true,
closeOnEscape = true,
dismissableMask = true,
resizable = true,
clazz = LucumaPrimeStyles.Dialog.Small |+| ExploreStyles.ConfigurationRequestEditorPopup,
header = "Request Editor",
footer = footer
)(
<.div(
notice,
Divider(),
FormInputTextAreaView(
id = "message_text_area".refined,
value = message
)
)
)
)
Loading

0 comments on commit 5cae632

Please sign in to comment.