Separate dialog components

This commit is contained in:
c-bata
2022-12-31 20:33:22 +09:00
parent 5054fa9c8e
commit fece9a3c16
4 changed files with 269 additions and 852 deletions
@@ -0,0 +1,148 @@
import React, { useState } from "react"
import {
Dialog,
useTheme,
FormLabel,
DialogTitle,
DialogContent,
DialogContentText,
FormControl,
Button,
DialogActions,
MenuItem,
Select,
} from "@mui/material"
import { actionCreator } from "../action"
import { DebouncedInputTextField } from "./Debounce"
import { useRecoilValue } from "recoil"
import { studySummariesState } from "../state"
import RemoveIcon from "@mui/icons-material/Remove"
import AddIcon from "@mui/icons-material/Add"
type UsePreferenceDialogReturn = [() => void, () => JSX.Element]
export const useCreateStudyDialog = (): UsePreferenceDialogReturn => {
const theme = useTheme()
const action = actionCreator()
const [newStudyName, setNewStudyName] = useState("")
const [openNewStudyDialog, setOpenNewStudyDialog] = useState(false)
const [directions, setDirections] = useState<StudyDirection[]>(["minimize"])
const studies = useRecoilValue<StudySummary[]>(studySummariesState)
const newStudyNameAlreadyUsed = studies.some(
(v) => v.study_name === newStudyName
)
const handleCloseNewStudyDialog = () => {
setOpenNewStudyDialog(false)
setNewStudyName("")
setDirections(["minimize"])
}
const handleCreateNewStudy = () => {
action.createNewStudy(newStudyName, directions)
setOpenNewStudyDialog(false)
setNewStudyName("")
setDirections(["minimize"])
}
const openDialog = () => {
setOpenNewStudyDialog(true)
}
const renderCreateNewStudyDialog = () => {
return (
<Dialog
open={openNewStudyDialog}
onClose={() => {
handleCloseNewStudyDialog()
}}
aria-labelledby="create-study-dialog-title"
>
<DialogTitle id="create-study-dialog-title">New Study</DialogTitle>
<DialogContent>
<DialogContentText>
Please enter the study name and directions here.
</DialogContentText>
<DebouncedInputTextField
onChange={(s) => {
setNewStudyName(s)
}}
delay={500}
textFieldProps={{
autoFocus: true,
fullWidth: true,
error: newStudyNameAlreadyUsed,
helperText: newStudyNameAlreadyUsed
? `"${newStudyName}" is already used`
: "",
label: "Study name",
type: "text",
}}
/>
</DialogContent>
{directions.map((d, i) => (
<DialogContent key={i}>
<FormControl component="fieldset" fullWidth={true}>
<FormLabel component="legend">Objective {i}:</FormLabel>
<Select
value={directions[i]}
onChange={(e) => {
const newVal: StudyDirection[] = [...directions]
newVal[i] = e.target.value as StudyDirection
setDirections(newVal)
}}
>
<MenuItem value="minimize">Minimize</MenuItem>
<MenuItem value="maximize">Maximize</MenuItem>
</Select>
</FormControl>
</DialogContent>
))}
<DialogContent>
<Button
variant="outlined"
startIcon={<AddIcon />}
sx={{ marginRight: theme.spacing(1) }}
onClick={() => {
const newVal: StudyDirection[] = [...directions, "minimize"]
setDirections(newVal)
}}
>
Add
</Button>
<Button
variant="outlined"
startIcon={<RemoveIcon />}
sx={{ marginRight: theme.spacing(1) }}
disabled={directions.length <= 1}
onClick={() => {
const newVal: StudyDirection[] = [...directions]
newVal.pop()
setDirections(newVal)
}}
>
Remove
</Button>
</DialogContent>
<DialogActions>
<Button onClick={handleCloseNewStudyDialog} color="primary">
Cancel
</Button>
<Button
onClick={handleCreateNewStudy}
color="primary"
disabled={
newStudyName === "" ||
newStudyNameAlreadyUsed ||
directions.length === 0
}
>
Create
</Button>
</DialogActions>
</Dialog>
)
}
return [openDialog, renderCreateNewStudyDialog]
}
@@ -0,0 +1,63 @@
import React, { useState } from "react"
import {
Dialog,
DialogTitle,
DialogContent,
DialogContentText,
Button,
DialogActions,
} from "@mui/material"
import { actionCreator } from "../action"
type UsePreferenceDialogReturn = [(studyId: number) => void, () => JSX.Element]
export const useDeleteStudyDialog = (): UsePreferenceDialogReturn => {
const action = actionCreator()
const [openDeleteStudyDialog, setOpenDeleteStudyDialog] = useState(false)
const [deleteStudyID, setDeleteStudyID] = useState(-1)
const handleCloseDeleteStudyDialog = () => {
setOpenDeleteStudyDialog(false)
setDeleteStudyID(-1)
}
const handleDeleteStudy = () => {
action.deleteStudy(deleteStudyID)
setOpenDeleteStudyDialog(false)
setDeleteStudyID(-1)
}
const openDialog = (studyId: number) => {
setDeleteStudyID(studyId)
setOpenDeleteStudyDialog(true)
}
const renderCreateNewStudyDialog = () => {
return (
<Dialog
open={openDeleteStudyDialog}
onClose={() => {
handleCloseDeleteStudyDialog()
}}
aria-labelledby="delete-study-dialog-title"
>
<DialogTitle id="delete-study-dialog-title">Delete study</DialogTitle>
<DialogContent>
<DialogContentText>
Are you sure you want to delete a study (id={deleteStudyID})?
</DialogContentText>
</DialogContent>
<DialogActions>
<Button onClick={handleCloseDeleteStudyDialog} color="primary">
No
</Button>
<Button onClick={handleDeleteStudy} color="primary">
Yes
</Button>
</DialogActions>
</Dialog>
)
}
return [openDialog, renderCreateNewStudyDialog]
}
+11 -294
View File
@@ -9,33 +9,13 @@ import {
Card,
Grid,
Box,
Button,
IconButton,
Dialog,
DialogTitle,
DialogContent,
DialogContentText,
DialogActions,
FormControlLabel,
Checkbox,
Menu,
MenuItem,
FormControl,
FormLabel,
Select,
useTheme,
InputAdornment,
SvgIcon,
CardContent,
} from "@mui/material"
import {
Add,
AddBox,
Delete,
Refresh,
Remove,
Search,
} from "@mui/icons-material"
import { AddBox, Delete, Refresh, Search } from "@mui/icons-material"
import { actionCreator } from "../action"
import { DataGrid, DataGridColumn } from "./DataGrid"
@@ -44,6 +24,8 @@ import { studySummariesState } from "../state"
import Brightness7Icon from "@mui/icons-material/Brightness7"
import Brightness4Icon from "@mui/icons-material/Brightness4"
import { useSnackbar } from "notistack"
import { useDeleteStudyDialog } from "./DeleteStudyDialog"
import { useCreateStudyDialog } from "./CreateStudyDialog"
export const StudyList: FC<{
toggleColorMode: () => void
@@ -51,21 +33,6 @@ export const StudyList: FC<{
const theme = useTheme()
const { enqueueSnackbar } = useSnackbar()
const [newStudySelectionAnchorEl, setNewStudySelectionAnchorEl] =
React.useState<null | HTMLElement>(null)
const openNewStudySelection = Boolean(newStudySelectionAnchorEl)
const [
openNewSingleObjectiveStudyDialog,
setOpenNewSingleObjectiveStudyDialog,
] = React.useState(false)
const [
openNewMultiObjectiveStudyDialog,
setOpenNewMultiObjectiveStudyDialog,
] = React.useState(false)
const [openDeleteStudyDialog, setOpenDeleteStudyDialog] =
React.useState(false)
const [deleteStudyID, setDeleteStudyID] = React.useState(-1)
const [newStudyName, setNewStudyName] = React.useState("")
const [studyFilterText, setStudyFilterText] = React.useState<string>("")
const studyFilter = (row: StudySummary) => {
const keywords = studyFilterText.split(" ")
@@ -76,11 +43,11 @@ export const StudyList: FC<{
return row.study_name.indexOf(k) >= 0
})
}
const [openDeleteStudyDialog, renderDeleteStudyDialog] =
useDeleteStudyDialog()
const [openCreateStudyDialog, renderCreateStudyDialog] =
useCreateStudyDialog()
const [maximize, setMaximize] = React.useState(false)
const [directions, setDirections] = React.useState<StudyDirection[]>([
"minimize",
])
const linkColor = useMemo(
() =>
theme.palette.mode === "dark"
@@ -92,10 +59,6 @@ export const StudyList: FC<{
const action = actionCreator()
const studies = useRecoilValue<StudySummary[]>(studySummariesState)
const newStudyNameAlreadyUsed = studies.some(
(v) => v.study_name === newStudyName
)
useEffect(() => {
action.updateStudySummaries()
}, [])
@@ -136,8 +99,7 @@ export const StudyList: FC<{
size="small"
color="inherit"
onClick={() => {
setDeleteStudyID(studies[i].study_id)
setOpenDeleteStudyDialog(true)
openDeleteStudyDialog(studies[i].study_id)
}}
>
<Delete />
@@ -151,42 +113,6 @@ export const StudyList: FC<{
{ field: "value", label: "Value", sortable: true },
]
const handleCloseNewSingleObjectiveStudyDialog = () => {
setNewStudyName("")
setOpenNewSingleObjectiveStudyDialog(false)
}
const handleCreateNewSingleObjectiveStudy = () => {
const direction = maximize ? "maximize" : "minimize"
action.createNewStudy(newStudyName, [direction])
setOpenNewSingleObjectiveStudyDialog(false)
setNewStudyName("")
}
const handleCloseNewMultiObjectiveStudyDialog = () => {
setOpenNewMultiObjectiveStudyDialog(false)
setNewStudyName("")
setDirections(["minimize"])
}
const handleCreateNewMultiObjectiveStudy = () => {
action.createNewStudy(newStudyName, directions)
setOpenNewMultiObjectiveStudyDialog(false)
setNewStudyName("")
setDirections(["minimize"])
}
const handleCloseDeleteStudyDialog = () => {
setOpenDeleteStudyDialog(false)
setDeleteStudyID(-1)
}
const handleDeleteStudy = () => {
action.deleteStudy(deleteStudyID)
setOpenDeleteStudyDialog(false)
setDeleteStudyID(-1)
}
const collapseBody = (index: number) => {
return (
<Grid container direction="row">
@@ -278,47 +204,13 @@ export const StudyList: FC<{
aria-controls="menu-appbar"
aria-haspopup="true"
onClick={(e) => {
setNewStudySelectionAnchorEl(e.currentTarget)
openCreateStudyDialog()
}}
color="inherit"
title="Create new study"
>
<AddBox />
</IconButton>
<Menu
id="menu-appbar"
anchorEl={newStudySelectionAnchorEl}
anchorOrigin={{
vertical: "top",
horizontal: "right",
}}
keepMounted
transformOrigin={{
vertical: "top",
horizontal: "right",
}}
open={openNewStudySelection}
onClose={() => {
setNewStudySelectionAnchorEl(null)
}}
>
<MenuItem
onClick={() => {
setNewStudySelectionAnchorEl(null)
setOpenNewSingleObjectiveStudyDialog(true)
}}
>
Single-objective
</MenuItem>
<MenuItem
onClick={() => {
setNewStudySelectionAnchorEl(null)
setOpenNewMultiObjectiveStudyDialog(true)
}}
>
Multi-objective
</MenuItem>
</Menu>
</Toolbar>
</Container>
</AppBar>
@@ -383,183 +275,8 @@ export const StudyList: FC<{
/>
</Card>
</Container>
<Dialog
open={openNewSingleObjectiveStudyDialog}
onClose={() => {
handleCloseNewSingleObjectiveStudyDialog()
}}
aria-labelledby="create-single-objective-study-form-dialog-title"
>
<DialogTitle id="create-single-objective-study-form-dialog-title">
New single-objective study
</DialogTitle>
<DialogContent>
<DialogContentText>
To create a new study, please enter the study name here.
</DialogContentText>
<DebouncedInputTextField
onChange={(s) => {
setNewStudyName(s)
}}
delay={500}
textFieldProps={{
type: "text",
autoFocus: true,
fullWidth: true,
error: newStudyNameAlreadyUsed,
helperText: newStudyNameAlreadyUsed
? `"${newStudyName}" is already used`
: "",
label: "Study name",
}}
/>
<FormControlLabel
control={
<Checkbox
checked={maximize}
onChange={() => {
setMaximize(!maximize)
}}
color="primary"
/>
}
label="Set maximize direction (default: minimize)"
/>
</DialogContent>
<DialogActions>
<Button
onClick={handleCloseNewSingleObjectiveStudyDialog}
color="primary"
>
Cancel
</Button>
<Button
onClick={handleCreateNewSingleObjectiveStudy}
color="primary"
disabled={newStudyName === "" || newStudyNameAlreadyUsed}
>
Create
</Button>
</DialogActions>
</Dialog>
<Dialog
open={openNewMultiObjectiveStudyDialog}
onClose={() => {
handleCloseNewMultiObjectiveStudyDialog()
}}
aria-labelledby="create-multi-objective-study-form-dialog-title"
>
<DialogTitle id="create-multi-objective-study-form-dialog-title">
New multi-objective study
</DialogTitle>
<DialogContent>
<DialogContentText>
To create a new study, please enter the study name and directions
here.
</DialogContentText>
<DebouncedInputTextField
onChange={(s) => {
setNewStudyName(s)
}}
delay={500}
textFieldProps={{
autoFocus: true,
fullWidth: true,
error: newStudyNameAlreadyUsed,
helperText: newStudyNameAlreadyUsed
? `"${newStudyName}" is already used`
: "",
label: "Study name",
type: "text",
}}
/>
</DialogContent>
{directions.map((d, i) => (
<DialogContent key={i}>
<FormControl component="fieldset" fullWidth={true}>
<FormLabel component="legend">Objective {i}:</FormLabel>
<Select
value={directions[i]}
onChange={(e) => {
const newVal: StudyDirection[] = [...directions]
newVal[i] = e.target.value as StudyDirection
setDirections(newVal)
}}
>
<MenuItem value="minimize">Minimize</MenuItem>
<MenuItem value="maximize">Maximize</MenuItem>
</Select>
</FormControl>
</DialogContent>
))}
<DialogContent>
<Button
variant="outlined"
startIcon={<Add />}
sx={{ marginRight: theme.spacing(1) }}
onClick={() => {
const newVal: StudyDirection[] = [...directions, "minimize"]
setDirections(newVal)
}}
>
Add
</Button>
<Button
variant="outlined"
startIcon={<Remove />}
sx={{ marginRight: theme.spacing(1) }}
disabled={directions.length <= 1}
onClick={() => {
const newVal: StudyDirection[] = [...directions]
newVal.pop()
setDirections(newVal)
}}
>
Remove
</Button>
</DialogContent>
<DialogActions>
<Button
onClick={handleCloseNewMultiObjectiveStudyDialog}
color="primary"
>
Cancel
</Button>
<Button
onClick={handleCreateNewMultiObjectiveStudy}
color="primary"
disabled={
newStudyName === "" ||
newStudyNameAlreadyUsed ||
directions.length === 0
}
>
Create
</Button>
</DialogActions>
</Dialog>
<Dialog
open={openDeleteStudyDialog}
onClose={() => {
handleCloseDeleteStudyDialog()
}}
aria-labelledby="delete-study-dialog-title"
>
<DialogTitle id="delete-study-dialog-title">Delete study</DialogTitle>
<DialogContent>
<DialogContentText>
Are you sure you want to delete a study (id={deleteStudyID})?
</DialogContentText>
</DialogContent>
<DialogActions>
<Button onClick={handleCloseDeleteStudyDialog} color="primary">
No
</Button>
<Button onClick={handleDeleteStudy} color="primary">
Yes
</Button>
</DialogActions>
</Dialog>
{renderCreateStudyDialog()}
{renderDeleteStudyDialog()}
</>
)
}
+47 -558
View File
@@ -5,58 +5,34 @@ import {
Typography,
Container,
Card,
Grid,
Box,
Button,
IconButton,
Dialog,
DialogTitle,
DialogContent,
DialogContentText,
DialogActions,
FormControlLabel,
Checkbox,
MenuItem,
FormControl,
FormLabel,
useTheme,
InputAdornment,
SvgIcon,
CardContent,
TextField,
Menu,
} from "@mui/material"
import { Add, Delete, Remove, Search } from "@mui/icons-material"
import { Delete, Refresh, Search } from "@mui/icons-material"
import SortIcon from "@mui/icons-material/Sort"
import AddBoxIcon from "@mui/icons-material/AddBox"
import { actionCreator } from "../action"
import { DataGrid, DataGridColumn } from "./DataGrid"
import { DebouncedInputTextField } from "./Debounce"
import { studySummariesState } from "../state"
import { styled } from "@mui/system"
import { AppDrawer } from "./AppDrawer"
import { useCreateStudyDialog } from "./CreateStudyDialog"
import { useDeleteStudyDialog } from "./DeleteStudyDialog"
export const StudyListBeta: FC<{
toggleColorMode: () => void
}> = ({ toggleColorMode }) => {
const theme = useTheme()
const action = actionCreator()
const [newStudySelectionAnchorEl, setNewStudySelectionAnchorEl] =
React.useState<null | HTMLElement>(null)
const openNewStudySelection = Boolean(newStudySelectionAnchorEl)
const [
openNewSingleObjectiveStudyDialog,
setOpenNewSingleObjectiveStudyDialog,
] = React.useState(false)
const [
openNewMultiObjectiveStudyDialog,
setOpenNewMultiObjectiveStudyDialog,
] = React.useState(false)
const [openDeleteStudyDialog, setOpenDeleteStudyDialog] =
React.useState(false)
const [deleteStudyID, setDeleteStudyID] = React.useState(-1)
const [newStudyName, setNewStudyName] = React.useState("")
const [studyFilterText, setStudyFilterText] = React.useState<string>("")
const studyFilter = (row: StudySummary) => {
const keywords = studyFilterText.split(" ")
@@ -67,11 +43,10 @@ export const StudyListBeta: FC<{
return row.study_name.indexOf(k) >= 0
})
}
const [maximize, setMaximize] = React.useState(false)
const [directions, setDirections] = React.useState<StudyDirection[]>([
"minimize",
])
const [openCreateStudyDialog, renderCreateStudyDialog] =
useCreateStudyDialog()
const [openDeleteStudyDialog, renderDeleteStudyDialog] =
useDeleteStudyDialog()
const linkColor = useMemo(
() =>
theme.palette.mode === "dark"
@@ -80,141 +55,13 @@ export const StudyListBeta: FC<{
[theme.palette.mode]
)
const action = actionCreator()
const studies = useRecoilValue<StudySummary[]>(studySummariesState)
const newStudyNameAlreadyUsed = studies.some(
(v) => v.study_name === newStudyName
)
const filteredStudy = studies.filter((s) => !studyFilter(s))
useEffect(() => {
action.updateStudySummaries()
}, [])
const columns: DataGridColumn<StudySummary>[] = [
{
field: "study_id",
label: "Study ID",
sortable: true,
},
{
field: "study_name",
label: "Name",
sortable: true,
toCellValue: (i) => (
<Link
to={`${URL_PREFIX}/studies/${studies[i].study_id}/beta`}
style={{ color: linkColor }}
>
{studies[i].study_name}
</Link>
),
},
{
field: "directions",
label: "Direction",
sortable: false,
toCellValue: (i) => studies[i].directions.join(),
},
{
field: "study_name",
label: "",
sortable: false,
padding: "none",
toCellValue: (i) => (
<IconButton
aria-label="delete study"
size="small"
color="inherit"
onClick={() => {
setDeleteStudyID(studies[i].study_id)
setOpenDeleteStudyDialog(true)
}}
>
<Delete />
</IconButton>
),
},
]
const collapseAttrColumns: DataGridColumn<Attribute>[] = [
{ field: "key", label: "Key", sortable: true },
{ field: "value", label: "Value", sortable: true },
]
const handleCloseNewSingleObjectiveStudyDialog = () => {
setNewStudyName("")
setOpenNewSingleObjectiveStudyDialog(false)
}
const handleCreateNewSingleObjectiveStudy = () => {
const direction = maximize ? "maximize" : "minimize"
action.createNewStudy(newStudyName, [direction])
setOpenNewSingleObjectiveStudyDialog(false)
setNewStudyName("")
}
const handleCloseNewMultiObjectiveStudyDialog = () => {
setOpenNewMultiObjectiveStudyDialog(false)
setNewStudyName("")
setDirections(["minimize"])
}
const handleCreateNewMultiObjectiveStudy = () => {
action.createNewStudy(newStudyName, directions)
setOpenNewMultiObjectiveStudyDialog(false)
setNewStudyName("")
setDirections(["minimize"])
}
const handleCloseDeleteStudyDialog = () => {
setOpenDeleteStudyDialog(false)
setDeleteStudyID(-1)
}
const handleDeleteStudy = () => {
action.deleteStudy(deleteStudyID)
setOpenDeleteStudyDialog(false)
setDeleteStudyID(-1)
}
const collapseBody = (index: number) => {
return (
<Grid container direction="row">
<Grid item xs={6}>
<Box margin={1}>
<Typography variant="h6" gutterBottom component="div">
Study user attributes
</Typography>
<DataGrid<Attribute>
columns={collapseAttrColumns}
rows={studies[index].user_attrs}
keyField={"key"}
dense={true}
initialRowsPerPage={5}
rowsPerPageOption={[5, 10, { label: "All", value: -1 }]}
/>
</Box>
</Grid>
<Grid item xs={6}>
<Box margin={1}>
<Typography variant="h6" gutterBottom component="div">
Study system attributes
</Typography>
<DataGrid<Attribute>
columns={collapseAttrColumns}
rows={studies[index].system_attrs}
keyField={"key"}
dense={true}
initialRowsPerPage={5}
rowsPerPageOption={[5, 10, { label: "All", value: -1 }]}
/>
</Box>
</Grid>
</Grid>
)
}
const Wrapper = styled("div")(({ theme }) => ({
position: "relative",
borderRadius: theme.shape.borderRadius,
@@ -293,417 +140,59 @@ export const StudyListBeta: FC<{
startIcon={<AddBoxIcon />}
aria-haspopup="true"
onClick={(e) => {
setNewStudySelectionAnchorEl(e.currentTarget)
openCreateStudyDialog()
}}
sx={{ marginRight: theme.spacing(2) }}
>
Create
</Button>
<Menu
id="menu-appbar"
anchorEl={newStudySelectionAnchorEl}
anchorOrigin={{
vertical: "top",
horizontal: "right",
}}
keepMounted
transformOrigin={{
vertical: "top",
horizontal: "right",
}}
open={openNewStudySelection}
onClose={() => {
setNewStudySelectionAnchorEl(null)
<Button
variant="outlined"
startIcon={<Refresh />}
aria-haspopup="true"
onClick={(e) => {
action.updateStudySummaries("Success to reload")
}}
sx={{ marginRight: theme.spacing(2) }}
>
<MenuItem
onClick={() => {
setNewStudySelectionAnchorEl(null)
setOpenNewSingleObjectiveStudyDialog(true)
}}
>
Single-objective
</MenuItem>
<MenuItem
onClick={() => {
setNewStudySelectionAnchorEl(null)
setOpenNewMultiObjectiveStudyDialog(true)
}}
>
Multi-objective
</MenuItem>
</Menu>
Refresh
</Button>
{sortBySelect}
</Box>
</CardContent>
</Card>
<Card sx={{ margin: theme.spacing(2) }}>
<DataGrid<StudySummary>
columns={columns}
rows={studies}
keyField={"study_id"}
collapseBody={collapseBody}
initialRowsPerPage={10}
rowsPerPageOption={[5, 10, { label: "All", value: -1 }]}
defaultFilter={studyFilter}
/>
</Card>
</Container>
<Dialog
open={openNewSingleObjectiveStudyDialog}
onClose={() => {
handleCloseNewSingleObjectiveStudyDialog()
}}
aria-labelledby="create-single-objective-study-form-dialog-title"
>
<DialogTitle id="create-single-objective-study-form-dialog-title">
New single-objective study
</DialogTitle>
<DialogContent>
<DialogContentText>
To create a new study, please enter the study name here.
</DialogContentText>
<DebouncedInputTextField
onChange={(s) => {
setNewStudyName(s)
}}
delay={500}
textFieldProps={{
type: "text",
autoFocus: true,
fullWidth: true,
error: newStudyNameAlreadyUsed,
helperText: newStudyNameAlreadyUsed
? `"${newStudyName}" is already used`
: "",
label: "Study name",
}}
/>
<FormControlLabel
control={
<Checkbox
checked={maximize}
onChange={() => {
setMaximize(!maximize)
}}
color="primary"
/>
}
label="Set maximize direction (default: minimize)"
/>
</DialogContent>
<DialogActions>
<Button
onClick={handleCloseNewSingleObjectiveStudyDialog}
color="primary"
>
Cancel
</Button>
<Button
onClick={handleCreateNewSingleObjectiveStudy}
color="primary"
disabled={newStudyName === "" || newStudyNameAlreadyUsed}
>
Create
</Button>
</DialogActions>
</Dialog>
<Dialog
open={openNewMultiObjectiveStudyDialog}
onClose={() => {
handleCloseNewMultiObjectiveStudyDialog()
}}
aria-labelledby="create-multi-objective-study-form-dialog-title"
>
<DialogTitle id="create-multi-objective-study-form-dialog-title">
New multi-objective study
</DialogTitle>
<DialogContent>
<DialogContentText>
To create a new study, please enter the study name and directions
here.
</DialogContentText>
<DebouncedInputTextField
onChange={(s) => {
setNewStudyName(s)
}}
delay={500}
textFieldProps={{
autoFocus: true,
fullWidth: true,
error: newStudyNameAlreadyUsed,
helperText: newStudyNameAlreadyUsed
? `"${newStudyName}" is already used`
: "",
label: "Study name",
type: "text",
}}
/>
</DialogContent>
{directions.map((d, i) => (
<DialogContent key={i}>
<FormControl component="fieldset" fullWidth={true}>
<FormLabel component="legend">Objective {i}:</FormLabel>
<Select
value={directions[i]}
onChange={(e) => {
const newVal: StudyDirection[] = [...directions]
newVal[i] = e.target.value as StudyDirection
setDirections(newVal)
{filteredStudy.map((study) => (
<Card key={study.study_id} sx={{ margin: theme.spacing(2) }}>
<CardContent sx={{ margin: theme.spacing(2) }}>
<Typography variant="h5">
<Link
to={`${URL_PREFIX}/studies/${study.study_id}/beta`}
style={{ color: linkColor }}
>
{study.study_name}
</Link>
</Typography>
<Typography>{study.study_id}</Typography>
<Typography>
{study.directions.map((d) => d.toString()).join(" ")}
</Typography>
<IconButton
aria-label="delete study"
size="small"
color="inherit"
onClick={() => {
openDeleteStudyDialog(study.study_id)
}}
>
<MenuItem value="minimize">Minimize</MenuItem>
<MenuItem value="maximize">Maximize</MenuItem>
</Select>
</FormControl>
</DialogContent>
<Delete />
</IconButton>
</CardContent>
</Card>
))}
<DialogContent>
<Button
variant="outlined"
startIcon={<Add />}
sx={{ marginRight: theme.spacing(1) }}
onClick={() => {
const newVal: StudyDirection[] = [...directions, "minimize"]
setDirections(newVal)
}}
>
Add
</Button>
<Button
variant="outlined"
startIcon={<Remove />}
sx={{ marginRight: theme.spacing(1) }}
disabled={directions.length <= 1}
onClick={() => {
const newVal: StudyDirection[] = [...directions]
newVal.pop()
setDirections(newVal)
}}
>
Remove
</Button>
</DialogContent>
<DialogActions>
<Button
onClick={handleCloseNewMultiObjectiveStudyDialog}
color="primary"
>
Cancel
</Button>
<Button
onClick={handleCreateNewMultiObjectiveStudy}
color="primary"
disabled={
newStudyName === "" ||
newStudyNameAlreadyUsed ||
directions.length === 0
}
>
Create
</Button>
</DialogActions>
</Dialog>
<Dialog
open={openDeleteStudyDialog}
onClose={() => {
handleCloseDeleteStudyDialog()
}}
aria-labelledby="delete-study-dialog-title"
>
<DialogTitle id="delete-study-dialog-title">Delete study</DialogTitle>
<DialogContent>
<DialogContentText>
Are you sure you want to delete a study (id={deleteStudyID})?
</DialogContentText>
</DialogContent>
<DialogActions>
<Button onClick={handleCloseDeleteStudyDialog} color="primary">
No
</Button>
<Button onClick={handleDeleteStudy} color="primary">
Yes
</Button>
</DialogActions>
</Dialog>
</Container>
</AppDrawer>
<Dialog
open={openNewSingleObjectiveStudyDialog}
onClose={() => {
handleCloseNewSingleObjectiveStudyDialog()
}}
aria-labelledby="create-single-objective-study-form-dialog-title"
>
<DialogTitle id="create-single-objective-study-form-dialog-title">
New single-objective study
</DialogTitle>
<DialogContent>
<DialogContentText>
To create a new study, please enter the study name here.
</DialogContentText>
<DebouncedInputTextField
onChange={(s) => {
setNewStudyName(s)
}}
delay={500}
textFieldProps={{
type: "text",
autoFocus: true,
fullWidth: true,
error: newStudyNameAlreadyUsed,
helperText: newStudyNameAlreadyUsed
? `"${newStudyName}" is already used`
: "",
label: "Study name",
}}
/>
<FormControlLabel
control={
<Checkbox
checked={maximize}
onChange={() => {
setMaximize(!maximize)
}}
color="primary"
/>
}
label="Set maximize direction (default: minimize)"
/>
</DialogContent>
<DialogActions>
<Button
onClick={handleCloseNewSingleObjectiveStudyDialog}
color="primary"
>
Cancel
</Button>
<Button
onClick={handleCreateNewSingleObjectiveStudy}
color="primary"
disabled={newStudyName === "" || newStudyNameAlreadyUsed}
>
Create
</Button>
</DialogActions>
</Dialog>
<Dialog
open={openNewMultiObjectiveStudyDialog}
onClose={() => {
handleCloseNewMultiObjectiveStudyDialog()
}}
aria-labelledby="create-multi-objective-study-form-dialog-title"
>
<DialogTitle id="create-multi-objective-study-form-dialog-title">
New multi-objective study
</DialogTitle>
<DialogContent>
<DialogContentText>
To create a new study, please enter the study name and directions
here.
</DialogContentText>
<DebouncedInputTextField
onChange={(s) => {
setNewStudyName(s)
}}
delay={500}
textFieldProps={{
autoFocus: true,
fullWidth: true,
error: newStudyNameAlreadyUsed,
helperText: newStudyNameAlreadyUsed
? `"${newStudyName}" is already used`
: "",
label: "Study name",
type: "text",
}}
/>
</DialogContent>
{directions.map((d, i) => (
<DialogContent key={i}>
<FormControl component="fieldset" fullWidth={true}>
<FormLabel component="legend">Objective {i}:</FormLabel>
<Select
value={directions[i]}
onChange={(e) => {
const newVal: StudyDirection[] = [...directions]
newVal[i] = e.target.value as StudyDirection
setDirections(newVal)
}}
>
<MenuItem value="minimize">Minimize</MenuItem>
<MenuItem value="maximize">Maximize</MenuItem>
</Select>
</FormControl>
</DialogContent>
))}
<DialogContent>
<Button
variant="outlined"
startIcon={<Add />}
sx={{ marginRight: theme.spacing(1) }}
onClick={() => {
const newVal: StudyDirection[] = [...directions, "minimize"]
setDirections(newVal)
}}
>
Add
</Button>
<Button
variant="outlined"
startIcon={<Remove />}
sx={{ marginRight: theme.spacing(1) }}
disabled={directions.length <= 1}
onClick={() => {
const newVal: StudyDirection[] = [...directions]
newVal.pop()
setDirections(newVal)
}}
>
Remove
</Button>
</DialogContent>
<DialogActions>
<Button
onClick={handleCloseNewMultiObjectiveStudyDialog}
color="primary"
>
Cancel
</Button>
<Button
onClick={handleCreateNewMultiObjectiveStudy}
color="primary"
disabled={
newStudyName === "" ||
newStudyNameAlreadyUsed ||
directions.length === 0
}
>
Create
</Button>
</DialogActions>
</Dialog>
<Dialog
open={openDeleteStudyDialog}
onClose={() => {
handleCloseDeleteStudyDialog()
}}
aria-labelledby="delete-study-dialog-title"
>
<DialogTitle id="delete-study-dialog-title">Delete study</DialogTitle>
<DialogContent>
<DialogContentText>
Are you sure you want to delete a study (id={deleteStudyID})?
</DialogContentText>
</DialogContent>
<DialogActions>
<Button onClick={handleCloseDeleteStudyDialog} color="primary">
No
</Button>
<Button onClick={handleDeleteStudy} color="primary">
Yes
</Button>
</DialogActions>
</Dialog>
{renderCreateStudyDialog()}
{renderDeleteStudyDialog()}
</Box>
)
}