Skip to content

Commit

Permalink
better identification of new programs
Browse files Browse the repository at this point in the history
  • Loading branch information
rpiaggio committed Dec 23, 2024
1 parent dc4f512 commit 2b96d6f
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 28 deletions.
27 changes: 15 additions & 12 deletions explore/src/main/scala/explore/EditableLabel.scala
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import scalajs.js.JSConverters.*
case class EditableLabel(
value: Option[NonEmptyString],
mod: Option[NonEmptyString] => Callback,
forceEditing: Boolean = false,
editOnClick: Boolean = false,
textClass: Css = Css.Empty,
inputClass: Css = Css.Empty,
Expand All @@ -40,11 +41,12 @@ case class EditableLabel(
readonly: Boolean = false
) extends ReactFnProps(EditableLabel.component)

object EditableLabel {
type Props = EditableLabel
object EditableLabel:
private type Props = EditableLabel

def fromView(
value: View[Option[NonEmptyString]],
forceEditing: Boolean = false,
editOnClick: Boolean = false,
textClass: Css = Css.Empty,
inputClass: Css = Css.Empty,
Expand All @@ -62,6 +64,7 @@ object EditableLabel {
EditableLabel(
value.get,
value.set,
forceEditing,
editOnClick,
textClass,
inputClass,
Expand All @@ -77,20 +80,23 @@ object EditableLabel {
readonly
)

type Editing = Editing.Type
object Editing extends NewType[Boolean]:
inline def NotEditing = Editing(false)
inline def InEdition = Editing(true)
private type Editing = Editing.Type
private object Editing extends NewType[Boolean]:
inline def NotEditing = Editing(false)
inline def InEdition = Editing(true)
def fromBoolean(b: Boolean): Editing = Editing(b)

import Editing.*

private val component =
ScalaFnComponent
.withHooks[Props]
.useState(NotEditing) // editing
.useState("") // displayValue
.useStateBy(props => Editing.fromBoolean(props.forceEditing)) // editing
.useEffectWithDepsBy((props, _) => props.forceEditing): (_, editing) =>
forceEditing => if forceEditing then editing.setState(InEdition) else Callback.empty
.useState("") // displayValue
.useId
.render { (props, editing, displayValue, id) =>
.render: (props, editing, displayValue, id) =>
def editCB(e: ReactMouseEvent): Callback =
e.stopPropagationCB >> e.preventDefaultCB >>
displayValue.setState(props.value.map(_.value).orEmpty) >>
Expand Down Expand Up @@ -181,6 +187,3 @@ object EditableLabel {
rightButton.unless(props.readonly)
)
)
}

}
12 changes: 10 additions & 2 deletions explore/src/main/scala/explore/programs/ProgramTable.scala
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,18 @@ case class ProgramTable(
isRequired: Boolean,
onClose: Option[Callback],
onLogout: Option[IO[Unit]],
newProgramId: Option[Program.Id],
virtualizerRef: UseRef[Option[HTMLTableVirtualizer]]
) extends ReactFnProps(ProgramTable.component)

object ProgramTable:
private type Props = ProgramTable

private case class TableMeta(currentProgramId: Option[Program.Id], programCount: Int)
private case class TableMeta(
currentProgramId: Option[Program.Id],
newProgramId: Option[Program.Id],
programCount: Int
)

private val ColDef = ColumnDef.WithTableMeta[View[ProgramInfo], TableMeta]

Expand Down Expand Up @@ -139,6 +144,9 @@ object ProgramTable:
EditableLabel
.fromView(
value = cell.value,
forceEditing = cell.table.options.meta
.flatMap(_.newProgramId)
.contains_(cell.row.original.get.id),
addButtonLabel = ("Add program name": VdomNode).reuseAlways,
textClass = ExploreStyles.ProgramName,
inputClass = ExploreStyles.ProgramNameInput,
Expand All @@ -159,7 +167,7 @@ object ProgramTable:
rows,
enableSorting = true,
enableColumnResizing = false,
meta = TableMeta(props.currentProgramId, props.programInfos.size)
meta = TableMeta(props.currentProgramId, props.newProgramId, props.programInfos.size)
)
.render: (props, ctx, _, _, table) =>
PrimeAutoHeightVirtualizedTable(
Expand Down
39 changes: 25 additions & 14 deletions explore/src/main/scala/explore/programs/ProgramsPopup.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

package explore.programs

import cats.Endo
import cats.Order.*
import cats.effect.IO
import cats.syntax.all.*
Expand Down Expand Up @@ -79,15 +80,17 @@ object ProgramsPopup:
.setAlign(rawVirtual.mod.ScrollAlignment.start) // force to go as far as possible

private def addProgram(
programs: View[ProgramInfoList],
adding: View[IsAdding]
programsMod: Endo[ProgramInfoList] => Callback,
adding: View[IsAdding],
setNewProgramId: Program.Id => Callback
)(using
FetchClient[IO, ObservationDB],
Logger[IO]
): IO[Unit] =
ProgramQueries
.createProgram[IO](none)
.flatMap(pi => programs.async.mod(_.updated(pi.id, pi)))
.flatTap(pi => programsMod(_.updated(pi.id, pi)).to[IO])
.flatMap(pi => setNewProgramId(pi.id).to[IO])
.switching(adding.async, IsAdding(_))

private val component = ScalaFnComponent
Expand All @@ -96,39 +99,42 @@ object ProgramsPopup:
.useStateView(IsOpen(true))
.useStateView(IsAdding(false)) // Adding new program
.useStateView(ShowDeleted(false)) // Show deleted
.useStateView(none[Program.Id]) // Recently added program
.useRef(none[HTMLTableVirtualizer])
.render: (props, ctx, isOpen, isAdding, showDeleted, virtualizerRef) =>
.render: (props, ctx, isOpen, isAdding, showDeleted, newProgramId, virtualizerRef) =>
import ctx.given

val onHide = props.onClose.map(oc => isOpen.set(IsOpen(false)) >> oc)
val onHide: Callback =
props.onClose.map(oc => isOpen.set(IsOpen(false)) >> oc).orEmpty >> newProgramId.set(none)

val closeButton =
props.onClose.fold(none)(cb =>
props.onClose.fold(none): cb =>
Button(
label = "Cancel",
icon = Icons.Close,
severity = Button.Severity.Danger,
onClick = cb
).small.compact.some
)

val logoutButton =
props.onLogout.fold(none)(io =>
props.onLogout.fold(none): io =>
Button(
label = "Logout",
icon = Icons.Logout,
severity = Button.Severity.Danger,
onClick = (ctx.sso.logout >> io).runAsync
).small.compact.some
)

val programInfosViewOpt: Option[View[ProgramInfoList]] =
props.programInfos.toOptionView

val doSelectProgram: Program.Id => Callback =
selectProgram(props.onClose, props.undoStacks, ctx)

val programInfoViewListOpt: Option[List[View[ProgramInfo]]] =
programInfosViewOpt.map:
_.toListOfViews
.map(_._2)
.map(_._2.withOnMod(pi => newProgramId.set(none) >> doSelectProgram(pi.id)))
.filter(vpi => showDeleted.get.value || !vpi.get.deleted)
.sortBy(_.get.id)

Expand All @@ -144,7 +150,7 @@ object ProgramsPopup:

Dialog(
visible = isOpen.get.value,
onHide = onHide.orEmpty,
onHide = onHide,
position = DialogPosition.Top,
closeOnEscape = props.onClose.isDefined,
closable = props.onClose.isDefined,
Expand All @@ -160,7 +166,11 @@ object ProgramsPopup:
severity = Button.Severity.Success,
disabled = isAdding.get.value,
loading = isAdding.get.value,
onClick = addProgram(pis, isAddingWithScroll).runAsync
onClick = addProgram(
pis.mod,
isAddingWithScroll,
programId => newProgramId.set(programId.some)
).runAsync
).small.compact,
CheckboxView(
id = "show-deleted".refined,
Expand All @@ -176,10 +186,11 @@ object ProgramsPopup:
ProgramTable(
props.currentProgramId,
pis,
selectProgram = selectProgram(props.onClose, props.undoStacks, ctx),
selectProgram = doSelectProgram,
props.onClose.isEmpty,
onHide,
onHide.some,
props.onLogout,
newProgramId.get,
virtualizerRef
),
props.message.map(msg =>
Expand Down

0 comments on commit 2b96d6f

Please sign in to comment.