Skip to content

Commit

Permalink
Add New Science Data notification checkbox to Program tab
Browse files Browse the repository at this point in the history
  • Loading branch information
toddburnside committed Jan 29, 2025
1 parent 1d3593b commit 21257cd
Show file tree
Hide file tree
Showing 8 changed files with 110 additions and 42 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,7 @@ object ExploreStyles:
val ProgramDetailsTile: Css = Css("program-details-tile")
val ProgramDetailsInfoArea: Css = Css("program-details-info-area")
val ProgramDetailsLeft: Css = Css("program-details-left")
val ProgramDetailsRight: Css = Css("program-details-right")
val ProgramTabTable: Css = Css("program-tab-table")
val ProgramDetailsUsers: Css = Css("program-details-users")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,7 @@ object ExploreGridLayouts:
end observationList

object programs:
private lazy val DetailsHeight: NonNegInt = 6.refined
private lazy val DetailsHeight: NonNegInt = 10.refined
private lazy val NotesHeight: NonNegInt = 6.refined
private lazy val ChangeRequestsHeight: NonNegInt = 6.refined
private lazy val UnrequestedConfigsHeight: NonNegInt = 6.refined
Expand Down
9 changes: 7 additions & 2 deletions common/src/main/webapp/sass/explore.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3384,13 +3384,18 @@ a.explore-upgrade-link {
flex: 1 1 0;
padding: 1em;

&.program-details-left {
&.program-details-left,
.program-details-right {
display: grid;
grid-template-columns: [label] auto [value] 1fr;
gap: 0.25em 1em;
gap: 0.25em 3em;
grid-auto-rows: max-content;
}

.program-details-right {
margin-top: 3rem;
}

label {
text-align: right;
font-weight: bold;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ object ProgramDetailsSubquery
allocations $AllocationSubquery
goa {
proprietaryMonths
shouldNotify
}
}
"""
11 changes: 11 additions & 0 deletions explore/src/main/scala/explore/common/ProgramQueries.scala
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,17 @@ object ProgramQueries:
SET = ProgramPropertiesInput(name = name.orUnassign)
)

def updateGoaShouldNotify[F[_]: Async](id: Program.Id, shouldNotify: Boolean)(using
FetchClient[F, ObservationDB]
): F[Unit] =
updateProgram:
UpdateProgramsInput(
WHERE = id.toWhereProgram.assign,
SET = ProgramPropertiesInput(
goa = GoaPropertiesInput(shouldNotify = shouldNotify.assign).assign
)
)

def updateAttachmentDescription[F[_]: Async](
oid: Attachment.Id,
desc: Option[NonEmptyString]
Expand Down
118 changes: 82 additions & 36 deletions explore/src/main/scala/explore/programs/ProgramDetailsTile.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,14 @@

package explore.programs

import cats.effect.IO
import cats.syntax.all.*
import crystal.Pot
import crystal.react.View
import crystal.react.syntax.effect.*
import explore.common.ProgramQueries
import explore.components.ui.ExploreStyles
import explore.model.AppContext
import explore.model.Constants
import explore.model.ProgramDetails
import explore.model.ProgramTimes
Expand All @@ -17,52 +21,94 @@ import lucuma.core.model.Program
import lucuma.core.model.Semester
import lucuma.core.syntax.display.*
import lucuma.react.common.ReactFnProps
import lucuma.refined.*
import lucuma.ui.primereact.CheckboxView
import lucuma.ui.primereact.FormInfo
import lucuma.ui.primereact.given

case class ProgramDetailsTile(
programId: Program.Id,
programDetails: View[ProgramDetails],
programTimes: Pot[ProgramTimes],
semester: Semester
programId: Program.Id,
programDetails: View[ProgramDetails],
programTimes: Pot[ProgramTimes],
semester: Semester,
userIsReadonlyCoi: Boolean
) extends ReactFnProps(ProgramDetailsTile.component)

object ProgramDetailsTile:
private type Props = ProgramDetailsTile

private val component = ScalaFnComponent[Props]: props =>
val details: ProgramDetails = props.programDetails.get
val thesis: Boolean = details.allUsers.exists(_.thesis.exists(_ === true))
val users: View[List[ProgramUser]] = props.programDetails.zoom(ProgramDetails.allUsers)
useContext(AppContext.ctx).map: ctx =>
import ctx.given

<.div(ExploreStyles.ProgramDetailsTile)(
<.div(ExploreStyles.ProgramDetailsInfoArea, ExploreStyles.ProgramDetailsLeft)(
FormInfo(details.reference.map(_.label).getOrElse("---"), "Reference"),
FormInfo(Constants.GppDateFormatter.format(props.semester.start.localDate), "Start"),
FormInfo(Constants.GppDateFormatter.format(props.semester.end.localDate), "End"),
// Thesis should be set True if any of the investigators will use the proposal as part of their thesis (3390)
FormInfo(if (thesis) "Yes" else "No", "Thesis"),
FormInfo(s"${details.proprietaryMonths} months", "Proprietary")
),
<.div(
TimeAwardTable(details.allocations),
TimeAccountingTable(props.programTimes)
),
<.div(ExploreStyles.ProgramDetailsInfoArea)(
SupportUsers(
props.programId,
users,
"Principal Support",
SupportUsers.SupportRole.Primary
val details: ProgramDetails = props.programDetails.get
val thesis: Boolean = details.allUsers.exists(_.thesis.exists(_ === true))
val users: View[List[ProgramUser]] = props.programDetails.zoom(ProgramDetails.allUsers)
val newDataNotificationView =
props.programDetails
.zoom(ProgramDetails.shouldNotify)
.withOnMod(b => ProgramQueries.updateGoaShouldNotify[IO](props.programId, b).runAsync)

<.div(ExploreStyles.ProgramDetailsTile)(
<.div(ExploreStyles.ProgramDetailsInfoArea, ExploreStyles.ProgramDetailsLeft)(
FormInfo(details.reference.map(_.label).getOrElse("---"), "Reference"),
FormInfo(Constants.GppDateFormatter.format(props.semester.start.localDate), "Start"),
FormInfo(Constants.GppDateFormatter.format(props.semester.end.localDate), "End"),
// Thesis should be set True if any of the investigators will use the proposal as part of their thesis (3390)
FormInfo(if (thesis) "Yes" else "No", "Thesis"),
FormInfo(s"${details.proprietaryMonths} months", "Proprietary")
),
<.div(
TimeAwardTable(details.allocations),
TimeAccountingTable(props.programTimes)
),
SupportUsers(
props.programId,
users,
"Additional Support",
SupportUsers.SupportRole.Secondary
<.div(ExploreStyles.ProgramDetailsInfoArea)(
SupportUsers(
props.programId,
users,
"Principal Support",
SupportUsers.SupportRole.Primary
),
SupportUsers(
props.programId,
users,
"Additional Support",
SupportUsers.SupportRole.Secondary
),

// The two Notifications flags are user-settable and determine whether the archive sends email notifications for new data and whether the ODB sends notifications for expired timing windows (3388, 3389)
<.div(
ExploreStyles.ProgramDetailsRight,
FormInfo(
CheckboxView(
id = "shouldNotify".refined,
value = newDataNotificationView,
label = "New Science Data",
disabled = props.userIsReadonlyCoi
),
"Notifications"
)
// FormInfo(
// CheckboxView(
// id = "expiredTimingWindows".refined,
// value = ???,
// label = "Expired Timing Windows"
// ),
// ""
// )
)

// The Eavesdropping` UI will allow PIs of accepted programs to select dates when they are available for eavesdropping. This is not needed for XT. (NEED TICKET)
// <.div(
// ExploreStyles.ProgramDetailsRight,
// FormInfo(
// CheckboxView(
// id = "eavesdropping".refined,
// value = ???,
// label = ??? // instead of a label there will be a date picker or something?
// ),
// "Eavesdropping"
// )
// )
)
// The two Notifications flags are user-settable and determine whether the archive sends email notifications for new data and whether the ODB sends notifications for expired timing windows (3388, 3389)
// FormInfo("", "Notifications")
// The Eavesdropping` UI will allow PIs of accepted programs to select dates when they are available for eavesdropping. This is not needed for XT. (NEED TICKET)
// FormInfo("", "Eavesdropping")
)
)
3 changes: 2 additions & 1 deletion explore/src/main/scala/explore/tabs/ProgramTabContents.scala
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,8 @@ object ProgramTabContents:
props.programId,
props.programDetails,
props.programTimes,
props.semester
props.semester,
props.userIsReadonlyCoi
)
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ case class ProgramDetails(
users: List[ProgramUser],
reference: Option[ProgramReference],
allocations: CategoryAllocationList,
proprietaryMonths: NonNegInt
proprietaryMonths: NonNegInt,
shouldNotify: Boolean
) derives Eq:
val allUsers: List[ProgramUser] = pi.fold(users)(_ :: users)

Expand All @@ -47,6 +48,7 @@ object ProgramDetails:
val pi: Lens[ProgramDetails, Option[ProgramUser]] = Focus[ProgramDetails](_.pi)
val piPartner: Optional[ProgramDetails, Option[PartnerLink]] =
pi.some.andThen(ProgramUser.partnerLink)
val shouldNotify: Lens[ProgramDetails, Boolean] = Focus[ProgramDetails](_.shouldNotify)

given Decoder[ProgramDetails] = Decoder.instance(c =>
for {
Expand All @@ -61,5 +63,6 @@ object ProgramDetails:
c.downField("reference").downField("label").success.traverse(_.as[Option[ProgramReference]])
as <- c.downField("allocations").as[CategoryAllocationList]
pm <- c.downField("goa").downField("proprietaryMonths").as[NonNegInt]
} yield ProgramDetails(n, d, t, p, ps, pi, us, r.flatten, as, pm)
sn <- c.downField("goa").downField("shouldNotify").as[Boolean]
} yield ProgramDetails(n, d, t, p, ps, pi, us, r.flatten, as, pm, sn)
)

0 comments on commit 21257cd

Please sign in to comment.