Remove stable ui components

This commit is contained in:
c-bata
2023-05-10 11:57:42 +09:00
parent bf1124f28f
commit ddd6492c8d
15 changed files with 35 additions and 988 deletions
+7 -17
View File
@@ -13,8 +13,6 @@ import {
} from "@mui/material"
import { CompareStudies } from "./CompareStudies"
import { StudyDetail } from "./StudyDetail"
import { StudyList } from "./StudyList"
import { StudyDetailBeta } from "./StudyDetailBeta"
import { StudyListBeta } from "./StudyListBeta"
@@ -53,15 +51,6 @@ export const App: FC = () => {
<SnackbarProvider maxSnack={3}>
<Router>
<Switch>
<Route
path={URL_PREFIX + "/studies/:studyId/beta"}
children={
<StudyDetailBeta
toggleColorMode={toggleColorMode}
page={"history"}
/>
}
/>
<Route
path={URL_PREFIX + "/studies/:studyId/analytics"}
children={
@@ -109,7 +98,12 @@ export const App: FC = () => {
/>
<Route
path={URL_PREFIX + "/studies/:studyId"}
children={<StudyDetail toggleColorMode={toggleColorMode} />}
children={
<StudyDetailBeta
toggleColorMode={toggleColorMode}
page={"history"}
/>
}
/>
<Route
path={URL_PREFIX + "/compare-studies"}
@@ -117,13 +111,9 @@ export const App: FC = () => {
<CompareStudies toggleColorMode={toggleColorMode} />
}
/>
<Route
path={URL_PREFIX + "/beta"}
children={<StudyListBeta toggleColorMode={toggleColorMode} />}
/>
<Route
path={URL_PREFIX + "/"}
children={<StudyList toggleColorMode={toggleColorMode} />}
children={<StudyListBeta toggleColorMode={toggleColorMode} />}
/>
</Switch>
</Router>
+2 -18
View File
@@ -24,7 +24,6 @@ import Brightness4Icon from "@mui/icons-material/Brightness4"
import Brightness7Icon from "@mui/icons-material/Brightness7"
import TableViewIcon from "@mui/icons-material/TableView"
import RateReviewIcon from "@mui/icons-material/RateReview"
import ClearIcon from "@mui/icons-material/Clear"
import MenuIcon from "@mui/icons-material/Menu"
import GitHubIcon from "@mui/icons-material/GitHub"
import OpenInNewIcon from "@mui/icons-material/OpenInNew"
@@ -185,7 +184,7 @@ export const AppDrawer: FC<{
<ListItem key="History" disablePadding sx={styleListItem}>
<ListItemButton
component={Link}
to={`${URL_PREFIX}/studies/${studyId}/beta`}
to={`${URL_PREFIX}/studies/${studyId}`}
sx={styleListItemButton}
selected={page === "history"}
>
@@ -304,7 +303,7 @@ export const AppDrawer: FC<{
<ListItem key="Feedback" disablePadding sx={styleListItem}>
<ListItemButton
target="_blank"
href="https://github.com/optuna/optuna-dashboard/discussions/332"
href="https://github.com/optuna/optuna-dashboard/discussions/new/choose"
sx={styleListItemButton}
>
<ListItemIcon sx={styleListItemIcon}>
@@ -314,21 +313,6 @@ export const AppDrawer: FC<{
<OpenInNewIcon sx={styleSwitch} />
</ListItemButton>
</ListItem>
<ListItem key="BetaUI" disablePadding sx={styleListItem}>
<ListItemButton
component={Link}
to={URL_PREFIX}
sx={styleListItemButton}
>
<ListItemIcon sx={styleListItemIcon}>
<ClearIcon />
</ListItemIcon>
<ListItemText
primary="Switch to stable UI"
sx={styleListItemText}
/>
</ListItemButton>
</ListItem>
</List>
</Drawer>
<Box component="main" sx={{ flexGrow: 1 }}>
@@ -99,7 +99,7 @@ export const CompareStudies: FC<{
<>
<IconButton
component={Link}
to={URL_PREFIX + "/beta"}
to={URL_PREFIX + "/"}
sx={{ marginRight: theme.spacing(1) }}
color="inherit"
title="Return to the top page"
@@ -315,8 +315,8 @@ const StudiesGraph: FC<{ studies: StudySummary[] }> = ({ studies }) => {
<CardContent>
<GraphHistoryMultiStudies
studies={showStudyDetails}
betaIncludePruned={includePruned}
betaLogScale={logScale}
includePruned={includePruned}
logScale={logScale}
/>
</CardContent>
</Card>
+3 -3
View File
@@ -37,7 +37,7 @@ export const GraphEdfBeta: FC<{
() => new Target("objective", objectiveId),
[objectiveId]
)
const trials = useFilteredTrials(study, [target], false, false)
const trials = useFilteredTrials(study, [target], false)
useEffect(() => {
if (study !== null) {
@@ -62,7 +62,7 @@ export const GraphEdf: FC<{
}> = ({ study = null }) => {
const theme = useTheme()
const [targets, selected, setTarget] = useObjectiveTargets(study)
const trials = useFilteredTrials(study, [selected], false, false)
const trials = useFilteredTrials(study, [selected], false)
const handleObjectiveChange = (event: SelectChangeEvent<string>) => {
setTarget(event.target.value)
@@ -119,7 +119,7 @@ export const GraphEdfMultiStudies: FC<{
studies.length !== 0 ? studies[0] : null
)
const trials = useFilteredTrialsFromStudies(studies, [selected], false, false)
const trials = useFilteredTrialsFromStudies(studies, [selected], false)
const edfPlotInfos = studies.map((study, index) => {
const e: EdfPlotInfo = {
study_name: study?.name,
+11 -130
View File
@@ -5,9 +5,7 @@ import {
FormControl,
FormLabel,
FormControlLabel,
Checkbox,
MenuItem,
Switch,
Select,
Radio,
RadioGroup,
@@ -34,24 +32,16 @@ interface HistoryPlotInfo {
export const GraphHistory: FC<{
study: StudyDetail | null
betaLogScale?: boolean
betaIncludePruned?: boolean
}> = ({ study, betaLogScale, betaIncludePruned }) => {
logScale: boolean
includePruned: boolean
}> = ({ study, logScale, includePruned }) => {
const theme = useTheme()
const [xAxis, setXAxis] = useState<
"number" | "datetime_start" | "datetime_complete"
>("number")
const [logScale, setLogScale] = useState<boolean>(false)
const [filterCompleteTrial, setFilterCompleteTrial] = useState<boolean>(false)
const [filterPrunedTrial, setFilterPrunedTrial] = useState<boolean>(false)
const [targets, selected, setTarget] = useObjectiveAndUserAttrTargets(study)
const trials = useFilteredTrials(
study,
[selected],
filterCompleteTrial,
betaIncludePruned === undefined ? filterPrunedTrial : !betaIncludePruned
)
const trials = useFilteredTrials(study, [selected], includePruned)
useEffect(() => {
if (study !== null) {
@@ -60,7 +50,7 @@ export const GraphHistory: FC<{
study.directions,
selected,
xAxis,
betaLogScale === undefined ? logScale : betaLogScale,
logScale,
theme.palette.mode,
study?.objective_names
)
@@ -70,7 +60,6 @@ export const GraphHistory: FC<{
study?.directions,
selected,
logScale,
betaLogScale,
xAxis,
theme.palette.mode,
study?.objective_names,
@@ -90,18 +79,6 @@ export const GraphHistory: FC<{
}
}
const handleLogScaleChange = (e: ChangeEvent<HTMLInputElement>) => {
setLogScale(!logScale)
}
const handleFilterCompleteChange = (e: ChangeEvent<HTMLInputElement>) => {
setFilterCompleteTrial(!filterCompleteTrial)
}
const handleFilterPrunedChange = (e: ChangeEvent<HTMLInputElement>) => {
setFilterPrunedTrial(!filterPrunedTrial)
}
return (
<Grid container direction="row">
<Grid
@@ -135,46 +112,6 @@ export const GraphHistory: FC<{
</Select>
</FormControl>
) : null}
{betaLogScale === undefined ? (
<FormControl
component="fieldset"
sx={{ marginBottom: theme.spacing(2) }}
>
<FormLabel component="legend">Log y scale:</FormLabel>
<Switch
checked={logScale}
onChange={handleLogScaleChange}
value="enable"
/>
</FormControl>
) : null}
{betaIncludePruned === undefined ? (
<FormControl
component="fieldset"
sx={{ marginBottom: theme.spacing(2) }}
>
<FormLabel component="legend">Filter state:</FormLabel>
<FormControlLabel
control={
<Checkbox
checked={!filterCompleteTrial}
onChange={handleFilterCompleteChange}
/>
}
label="Complete"
/>
<FormControlLabel
control={
<Checkbox
checked={!filterPrunedTrial}
disabled={!study?.has_intermediate_values}
onChange={handleFilterPrunedChange}
/>
}
label="Pruned"
/>
</FormControl>
) : null}
<FormControl
component="fieldset"
sx={{ marginBottom: theme.spacing(2) }}
@@ -213,16 +150,13 @@ export const GraphHistory: FC<{
export const GraphHistoryMultiStudies: FC<{
studies: StudyDetail[]
betaLogScale?: boolean
betaIncludePruned?: boolean
}> = ({ studies, betaLogScale, betaIncludePruned }) => {
logScale: boolean
includePruned: boolean
}> = ({ studies, logScale, includePruned }) => {
const theme = useTheme()
const [xAxis, setXAxis] = useState<
"number" | "datetime_start" | "datetime_complete"
>("number")
const [logScale, setLogScale] = useState<boolean>(false)
const [filterCompleteTrial, setFilterCompleteTrial] = useState<boolean>(false)
const [filterPrunedTrial, setFilterPrunedTrial] = useState<boolean>(false)
// TODO(umezawa): Prepare targets with all studies.
const [targets, selected, setTarget] = useObjectiveAndUserAttrTargets(
@@ -232,8 +166,7 @@ export const GraphHistoryMultiStudies: FC<{
const trials = useFilteredTrialsFromStudies(
studies,
[selected],
filterCompleteTrial,
betaIncludePruned === undefined ? filterPrunedTrial : !betaIncludePruned
!includePruned
)
const historyPlotInfos = studies.map((study, index) => {
const h: HistoryPlotInfo = {
@@ -250,10 +183,10 @@ export const GraphHistoryMultiStudies: FC<{
historyPlotInfos,
selected,
xAxis,
betaLogScale === undefined ? logScale : betaLogScale,
logScale,
theme.palette.mode
)
}, [studies, selected, logScale, betaLogScale, xAxis, theme.palette.mode])
}, [studies, selected, logScale, xAxis, theme.palette.mode])
const handleObjectiveChange = (event: SelectChangeEvent<string>) => {
setTarget(event.target.value)
@@ -269,18 +202,6 @@ export const GraphHistoryMultiStudies: FC<{
}
}
const handleLogScaleChange = (e: ChangeEvent<HTMLInputElement>) => {
setLogScale(!logScale)
}
const handleFilterCompleteChange = (e: ChangeEvent<HTMLInputElement>) => {
setFilterCompleteTrial(!filterCompleteTrial)
}
const handleFilterPrunedChange = (e: ChangeEvent<HTMLInputElement>) => {
setFilterPrunedTrial(!filterPrunedTrial)
}
return (
<Grid container direction="row">
<Grid
@@ -314,46 +235,6 @@ export const GraphHistoryMultiStudies: FC<{
</Select>
</FormControl>
) : null}
{betaLogScale === undefined ? (
<FormControl
component="fieldset"
sx={{ marginBottom: theme.spacing(2) }}
>
<FormLabel component="legend">Log y scale:</FormLabel>
<Switch
checked={logScale}
onChange={handleLogScaleChange}
value="enable"
/>
</FormControl>
) : null}
{betaIncludePruned === undefined ? (
<FormControl
component="fieldset"
sx={{ marginBottom: theme.spacing(2) }}
>
<FormLabel component="legend">Filter state:</FormLabel>
<FormControlLabel
control={
<Checkbox
checked={!filterCompleteTrial}
onChange={handleFilterCompleteChange}
/>
}
label="Complete"
/>
<FormControlLabel
control={
<Checkbox
checked={!filterPrunedTrial}
disabled={!studies[0]?.has_intermediate_values}
onChange={handleFilterPrunedChange}
/>
}
label="Pruned"
/>
</FormControl>
) : null}
<FormControl
component="fieldset"
sx={{ marginBottom: theme.spacing(2) }}
@@ -90,7 +90,7 @@ export const GraphParallelCoordinate: FC<{
const theme = useTheme()
const [targets, searchSpace, renderCheckBoxes] = useTargets(study)
const trials = useFilteredTrials(study, targets, false, false)
const trials = useFilteredTrials(study, targets, false)
useEffect(() => {
if (study !== null) {
plotCoordinate(study, trials, targets, searchSpace, theme.palette.mode)
@@ -47,7 +47,6 @@ export const GraphSlice: FC<{
selectedParamTarget !== null
? [selectedObjective, selectedParamTarget]
: [selectedObjective],
false,
false
)
@@ -1,172 +0,0 @@
import React, { useEffect, useState } from "react"
import MuiDialogTitle from "@mui/material/DialogTitle"
import CloseIcon from "@mui/icons-material/Close"
import MuiDialogContent from "@mui/material/DialogContent"
import FormControlLabel from "@mui/material/FormControlLabel"
import {
Dialog,
Checkbox,
Typography,
IconButton,
FormGroup,
useTheme,
FormLabel,
} from "@mui/material"
import { useRecoilValue } from "recoil"
import { graphVisibilityState } from "../state"
import { actionCreator } from "../action"
type UsePreferenceDialogReturn = [(open: boolean) => void, () => JSX.Element]
export const usePreferenceDialog = (
studyDetail: StudyDetail | null
): UsePreferenceDialogReturn => {
const theme = useTheme()
const action = actionCreator()
const globalGraphVisibility =
useRecoilValue<GraphVisibility>(graphVisibilityState)
const [localGraphVisibility, setLocalGraphVisibility] =
useState<GraphVisibility>(globalGraphVisibility)
useEffect(() => {
action.getGraphVisibility()
}, [])
useEffect(() => {
setLocalGraphVisibility(globalGraphVisibility)
}, [globalGraphVisibility])
const [prefOpen, setPrefOpen] = useState(false)
const handleClose = () => {
setPrefOpen(false)
action.saveGraphVisibility(localGraphVisibility)
}
const handlePreferenceOnChange = (
event: React.ChangeEvent<HTMLInputElement>
) => {
setLocalGraphVisibility({
...localGraphVisibility,
[event.target.name]: event.target.checked,
})
}
const renderPreferenceDialog = () => {
return (
<Dialog onClose={handleClose} aria-labelledby="vis-pref" open={prefOpen}>
<MuiDialogTitle
sx={{
margin: 0,
padding: theme.spacing(2),
minWidth: 300,
}}
>
<Typography variant="h6">Preferences</Typography>
<IconButton
aria-label="close"
sx={{
position: "absolute",
right: theme.spacing(1),
top: theme.spacing(1),
color: theme.palette.grey[500],
}}
onClick={handleClose}
>
<CloseIcon />
</IconButton>
</MuiDialogTitle>
<MuiDialogContent dividers>
<FormLabel component="legend">Charts</FormLabel>
<FormGroup>
<FormControlLabel
control={
<Checkbox
checked={localGraphVisibility.history}
onChange={handlePreferenceOnChange}
name="history"
/>
}
label="History"
/>
<FormControlLabel
disabled={studyDetail?.directions?.length === 1}
control={
<Checkbox
checked={localGraphVisibility.paretoFront}
onChange={handlePreferenceOnChange}
name="paretoFront"
/>
}
label="Pareto Front"
/>
<FormControlLabel
control={
<Checkbox
checked={localGraphVisibility.parallelCoordinate}
onChange={handlePreferenceOnChange}
name="parallelCoordinate"
/>
}
label="Parallel Coordinate"
/>
<FormControlLabel
disabled={
studyDetail !== null &&
(studyDetail.directions.length > 1 ||
!studyDetail.has_intermediate_values)
}
control={
<Checkbox
checked={localGraphVisibility.intermediateValues}
onChange={handlePreferenceOnChange}
name="intermediateValues"
/>
}
label="Intermediate Values"
/>
<FormControlLabel
control={
<Checkbox
checked={localGraphVisibility.edf}
onChange={handlePreferenceOnChange}
name="edf"
/>
}
label="EDF"
/>
<FormControlLabel
control={
<Checkbox
checked={localGraphVisibility.contour}
onChange={handlePreferenceOnChange}
name="contour"
/>
}
label="Contour"
/>
<FormControlLabel
control={
<Checkbox
checked={localGraphVisibility.importances}
onChange={handlePreferenceOnChange}
name="importances"
/>
}
label="Hyperparameter Importances"
/>
<FormControlLabel
control={
<Checkbox
checked={localGraphVisibility.slice}
onChange={handlePreferenceOnChange}
name="slice"
/>
}
label="Slice"
/>
</FormGroup>
</MuiDialogContent>
</Dialog>
)
}
return [setPrefOpen, renderPreferenceDialog]
}
@@ -1,86 +0,0 @@
import React, { FC } from "react"
import { styled } from "@mui/system"
import { useRecoilValue } from "recoil"
import { reloadIntervalState } from "../state"
import { MenuItem, TextField, alpha } from "@mui/material"
import { Cached } from "@mui/icons-material"
import { actionCreator } from "../action"
export const ReloadIntervalSelect: FC = () => {
const action = actionCreator()
const reloadInterval = useRecoilValue<number>(reloadIntervalState)
const Wrapper = styled("div")(({ theme }) => ({
position: "relative",
borderRadius: theme.shape.borderRadius,
backgroundColor: alpha(theme.palette.common.white, 0.15),
"&:hover": {
backgroundColor: alpha(theme.palette.common.white, 0.25),
},
marginLeft: 0,
width: "100%",
[theme.breakpoints.up("sm")]: {
marginLeft: theme.spacing(1),
width: "auto",
},
}))
const IconWrapper = styled("div")(({ theme }) => ({
padding: theme.spacing(0, 2),
height: "100%",
position: "absolute",
pointerEvents: "none",
display: "flex",
alignItems: "center",
justifyContent: "center",
}))
const Select = styled(TextField)(({ theme }) => ({
color: "inherit",
width: "14ch",
"& .MuiInput-underline:after": {
borderColor: "rgb(256,256,256,.1)",
},
"& .MuiOutlinedInput-root": {
color: "inherit",
"& fieldset": {
borderColor: "rgb(256,256,256,.1)",
},
"& .MuiSelect-icon": {
color: "white",
},
"&:hover fieldset": {
borderColor: "rgb(256,256,256,.1)",
},
"&.Mui-focused fieldset": {
borderColor: "rgb(256,256,256,.1)",
},
},
"& .MuiInputBase-input": {
// vertical padding + font size from searchIcon
paddingLeft: `calc(1em + ${theme.spacing(4)})`,
width: "100%",
},
}))
return (
<Wrapper>
<IconWrapper>
<Cached />
</IconWrapper>
<Select
select
value={reloadInterval}
onChange={(e) => {
action.saveReloadInterval(e.target.value as unknown as number)
}}
>
<MenuItem value={-1}>stop</MenuItem>
<MenuItem value={5}>5s</MenuItem>
<MenuItem value={10}>10s</MenuItem>
<MenuItem value={30}>30s</MenuItem>
<MenuItem value={60}>60s</MenuItem>
</Select>
</Wrapper>
)
}
@@ -1,249 +0,0 @@
import React, { FC, useEffect } from "react"
import { useRecoilValue } from "recoil"
import { Link, useParams } from "react-router-dom"
import {
AppBar,
Card,
Typography,
CardContent,
Container,
Toolbar,
Box,
IconButton,
useTheme,
} from "@mui/material"
import { Home, Settings } from "@mui/icons-material"
import Brightness4Icon from "@mui/icons-material/Brightness4"
import Brightness7Icon from "@mui/icons-material/Brightness7"
import { GraphParallelCoordinate } from "./GraphParallelCoordinate"
import { GraphHyperparameterImportances } from "./GraphHyperparameterImportances"
import { GraphEdf } from "./GraphEdf"
import { Contour } from "./GraphContour"
import { GraphIntermediateValues } from "./GraphIntermediateValues"
import { GraphSlice } from "./GraphSlice"
import { GraphHistory } from "./GraphHistory"
import { GraphParetoFront } from "./GraphParetoFront"
import { StudyNote } from "./Note"
import { actionCreator } from "../action"
import {
graphVisibilityState,
reloadIntervalState,
studyDetailsState,
studySummariesState,
} from "../state"
import { usePreferenceDialog } from "./PreferenceDialog"
import { ReloadIntervalSelect } from "./ReloadIntervalSelect"
import { TrialTable } from "./TrialTable"
interface ParamTypes {
studyId: string
}
const useStudyDetailValue = (studyId: number): StudyDetail | null => {
const studyDetails = useRecoilValue<StudyDetails>(studyDetailsState)
return studyDetails[studyId] || null
}
const useStudySummaryValue = (studyId: number): StudySummary | null => {
const studySummaries = useRecoilValue<StudySummary[]>(studySummariesState)
return studySummaries.find((s) => s.study_id == studyId) || null
}
export const StudyDetail: FC<{
toggleColorMode: () => void
}> = ({ toggleColorMode }) => {
const theme = useTheme()
const action = actionCreator()
const { studyId } = useParams<ParamTypes>()
const studyIdNumber = parseInt(studyId, 10)
const studyDetail = useStudyDetailValue(studyIdNumber)
const studySummary = useStudySummaryValue(studyIdNumber)
const directions = studyDetail?.directions || studySummary?.directions || null
const graphVisibility = useRecoilValue<GraphVisibility>(graphVisibilityState)
const reloadInterval = useRecoilValue<number>(reloadIntervalState)
const [openPreferenceDialog, renderPreferenceDialog] =
usePreferenceDialog(studyDetail)
useEffect(() => {
action.loadReloadInterval()
action.updateStudyDetail(studyIdNumber)
}, [])
useEffect(() => {
if (reloadInterval < 0) {
return
}
const intervalId = setInterval(function () {
action.updateStudyDetail(studyIdNumber)
}, reloadInterval * 1000)
return () => clearInterval(intervalId)
}, [reloadInterval, studyDetail])
// TODO(chenghuzi): Reduce the number of calls to setInterval and clearInterval.
const title = studyDetail !== null ? studyDetail.name : `Study #${studyId}`
const trials: Trial[] = studyDetail !== null ? studyDetail.trials : []
return (
<div>
{renderPreferenceDialog()}
<AppBar position="static">
<Container
sx={{
["@media (min-width: 1280px)"]: {
maxWidth: "100%",
},
}}
>
<Toolbar>
<Typography variant="h6">{APP_BAR_TITLE}</Typography>
<Box sx={{ flexGrow: 1 }} />
<ReloadIntervalSelect />
<IconButton
onClick={() => {
toggleColorMode()
}}
color="inherit"
title={
theme.palette.mode === "dark"
? "Switch to light mode"
: "Switch to dark mode"
}
>
{theme.palette.mode === "dark" ? (
<Brightness7Icon />
) : (
<Brightness4Icon />
)}
</IconButton>
<IconButton
color="inherit"
onClick={() => {
openPreferenceDialog(true)
}}
title="Open preference panel"
>
<Settings />
</IconButton>
<IconButton
aria-controls="menu-appbar"
aria-haspopup="true"
component={Link}
to={URL_PREFIX + "/"}
color="inherit"
title="Go to the top"
>
<Home />
</IconButton>
</Toolbar>
</Container>
</AppBar>
<Container
sx={{
["@media (min-width: 1280px)"]: {
maxWidth: "100%",
},
}}
>
<div>
<Typography
variant="h4"
sx={{
margin: `${theme.spacing(4)} ${theme.spacing(2)}`,
fontWeight: theme.typography.fontWeightBold,
fontSize: "1.8rem",
...(theme.palette.mode === "dark" && {
color: theme.palette.primary.light,
}),
}}
>
{title}
</Typography>
{graphVisibility.history ? (
<Card
sx={{
margin: theme.spacing(2),
}}
>
<CardContent>
<GraphHistory study={studyDetail} />
</CardContent>
</Card>
) : null}
{directions !== null &&
directions.length > 1 &&
graphVisibility.paretoFront ? (
<Card sx={{ margin: theme.spacing(2) }}>
<CardContent>
<GraphParetoFront study={studyDetail} />
</CardContent>
</Card>
) : null}
{graphVisibility.parallelCoordinate ? (
<Card sx={{ margin: theme.spacing(2) }}>
<CardContent>
<GraphParallelCoordinate study={studyDetail} />
</CardContent>
</Card>
) : null}
{studyDetail !== null &&
studyDetail.directions.length == 1 &&
studyDetail.has_intermediate_values &&
graphVisibility.intermediateValues ? (
<Card sx={{ margin: theme.spacing(2) }}>
<CardContent>
<GraphIntermediateValues trials={trials} />
</CardContent>
</Card>
) : null}
{graphVisibility.edf ? (
<Card sx={{ margin: theme.spacing(2) }}>
<CardContent>
<GraphEdf study={studyDetail} />
</CardContent>
</Card>
) : null}
{graphVisibility.contour ? (
<Card sx={{ margin: theme.spacing(2) }}>
<CardContent>
<Contour study={studyDetail} />
</CardContent>
</Card>
) : null}
{graphVisibility.importances ? (
<Card sx={{ margin: theme.spacing(2) }}>
<CardContent>
<GraphHyperparameterImportances
study={studyDetail}
studyId={studyIdNumber}
/>
</CardContent>
</Card>
) : null}
{studyDetail !== null && graphVisibility.slice ? (
<Card sx={{ margin: theme.spacing(2) }}>
<CardContent>
<GraphSlice study={studyDetail} />
</CardContent>
</Card>
) : null}
<Card sx={{ margin: theme.spacing(2) }}>
<TrialTable studyDetail={studyDetail} isBeta={false} />
</Card>
{studyDetail !== null ? (
<StudyNote
studyId={studyIdNumber}
latestNote={studyDetail.note}
cardSx={{ margin: theme.spacing(2) }}
/>
) : null}
</div>
</Container>
</div>
)
}
@@ -168,7 +168,7 @@ export const StudyDetailBeta: FC<{
<>
<IconButton
component={Link}
to={URL_PREFIX + "/beta"}
to={URL_PREFIX + "/"}
sx={{ marginRight: theme.spacing(1) }}
color="inherit"
title="Return to the top page"
@@ -96,8 +96,8 @@ export const StudyHistory: FC<{ studyId: number }> = ({ studyId }) => {
<CardContent>
<GraphHistory
study={studyDetail}
betaIncludePruned={includePruned}
betaLogScale={logScale}
includePruned={includePruned}
logScale={logScale}
/>
</CardContent>
</Card>
@@ -1,277 +0,0 @@
import React, { FC, useEffect, useMemo } from "react"
import { useRecoilValue } from "recoil"
import { Link } from "react-router-dom"
import {
AppBar,
Toolbar,
Typography,
Container,
Card,
Grid,
Box,
IconButton,
useTheme,
InputAdornment,
SvgIcon,
CardContent,
} from "@mui/material"
import { AddBox, Delete, Refresh, Search } from "@mui/icons-material"
import { actionCreator } from "../action"
import { DataGrid, DataGridColumn } from "./DataGrid"
import { DebouncedInputTextField } from "./Debounce"
import { studySummariesState } from "../state"
import Brightness7Icon from "@mui/icons-material/Brightness7"
import Brightness4Icon from "@mui/icons-material/Brightness4"
import { useDeleteStudyDialog } from "./DeleteStudyDialog"
import { useCreateStudyDialog } from "./CreateStudyDialog"
export const StudyList: FC<{
toggleColorMode: () => void
}> = ({ toggleColorMode }) => {
const theme = useTheme()
const [studyFilterText, setStudyFilterText] = React.useState<string>("")
const studyFilter = (row: StudySummary) => {
const keywords = studyFilterText.split(" ")
return !keywords.every((k) => {
if (k === "") {
return true
}
return row.study_name.indexOf(k) >= 0
})
}
const [openDeleteStudyDialog, renderDeleteStudyDialog] =
useDeleteStudyDialog()
const [openCreateStudyDialog, renderCreateStudyDialog] =
useCreateStudyDialog()
const linkColor = useMemo(
() =>
theme.palette.mode === "dark"
? theme.palette.primary.light
: theme.palette.primary.dark,
[theme.palette.mode]
)
const action = actionCreator()
const studies = useRecoilValue<StudySummary[]>(studySummariesState)
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}`}
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={() => {
openDeleteStudyDialog(studies[i].study_id)
}}
>
<Delete />
</IconButton>
),
},
]
const collapseAttrColumns: DataGridColumn<Attribute>[] = [
{ field: "key", label: "Key", sortable: true },
{ field: "value", label: "Value", sortable: true },
]
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>
)
}
return (
<>
<AppBar position="static">
<Container
sx={{
["@media (min-width: 1280px)"]: {
maxWidth: "100%",
},
}}
>
<Toolbar>
<Typography variant="h6">{APP_BAR_TITLE}</Typography>
<Box sx={{ flexGrow: 1 }} />
<IconButton
onClick={() => {
toggleColorMode()
}}
color="inherit"
title={
theme.palette.mode === "dark"
? "Switch to light mode"
: "Switch to dark mode"
}
>
{theme.palette.mode === "dark" ? (
<Brightness7Icon />
) : (
<Brightness4Icon />
)}
</IconButton>
<IconButton
aria-controls="menu-appbar"
aria-haspopup="true"
onClick={() => {
action.updateStudySummaries("Success to reload")
}}
color="inherit"
title="Reload studies"
>
<Refresh />
</IconButton>
<IconButton
aria-controls="menu-appbar"
aria-haspopup="true"
onClick={(e) => {
openCreateStudyDialog()
}}
color="inherit"
title="Create new study"
>
<AddBox />
</IconButton>
</Toolbar>
</Container>
</AppBar>
<Container
sx={{
["@media (min-width: 1280px)"]: {
maxWidth: "100%",
},
}}
>
<Card sx={{ margin: theme.spacing(2) }}>
<CardContent>
<Typography
variant="h5"
style={{ paddingBottom: theme.spacing(1) }}
>
Announcement
</Typography>
<Typography>
{`Please go to `}
<Link to={`${URL_PREFIX}/beta`} style={{ color: linkColor }}>
our experimental new UI page
</Link>
{" and share your thoughts with us via "}
<Link to={`${URL_PREFIX}/beta`} style={{ color: linkColor }}>
the GitHub Discussion's post
</Link>
{"."}
</Typography>
</CardContent>
</Card>
<Card sx={{ margin: theme.spacing(2) }}>
<CardContent>
<Box sx={{ maxWidth: 500 }}>
<DebouncedInputTextField
onChange={(s) => {
setStudyFilterText(s)
}}
delay={500}
textFieldProps={{
fullWidth: true,
id: "search-study",
variant: "outlined",
placeholder: "Search study",
InputProps: {
startAdornment: (
<InputAdornment position="start">
<SvgIcon fontSize="small" color="action">
<Search />
</SvgIcon>
</InputAdornment>
),
},
}}
/>
</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>
{renderCreateStudyDialog()}
{renderDeleteStudyDialog()}
</>
)
}
@@ -17,7 +17,6 @@ import {
TextField,
CardActions,
} from "@mui/material"
import MuiLink from "@mui/material/Link"
import { Delete, Refresh, Search } from "@mui/icons-material"
import SortIcon from "@mui/icons-material/Sort"
import HomeIcon from "@mui/icons-material/Home"
@@ -120,20 +119,6 @@ export const StudyListBeta: FC<{
},
}}
>
<Card sx={{ margin: theme.spacing(2) }}>
<CardContent>
<Typography>
{`Thank you for testing the new UI! We would appreciate it if you could send us the feedback via `}
<MuiLink
target="_blank"
href="https://github.com/optuna/optuna-dashboard/discussions/332"
>
this post
</MuiLink>
{" on GitHub Discussions."}
</Typography>
</CardContent>
</Card>
<Card sx={{ margin: theme.spacing(2) }}>
<CardContent>
<Box sx={{ display: "flex" }}>
@@ -201,7 +186,7 @@ export const StudyListBeta: FC<{
>
<CardActionArea
component={Link}
to={`${URL_PREFIX}/studies/${study.study_id}/beta`}
to={`${URL_PREFIX}/studies/${study.study_id}`}
>
<CardContent>
<Typography variant="h5">
+4 -12
View File
@@ -95,7 +95,6 @@ export class Target {
const filterTrials = (
study: StudyDetail | null,
targets: Target[],
filterComplete: boolean,
filterPruned: boolean
): Trial[] => {
if (study === null) {
@@ -105,9 +104,6 @@ const filterTrials = (
if (t.state !== "Complete" && t.state !== "Pruned") {
return false
}
if (t.state === "Complete" && filterComplete) {
return false
}
if (t.state === "Pruned" && filterPruned) {
return false
}
@@ -118,24 +114,20 @@ const filterTrials = (
export const useFilteredTrials = (
study: StudyDetail | null,
targets: Target[],
filterComplete: boolean,
filterPruned: boolean
): Trial[] =>
useMemo<Trial[]>(() => {
return filterTrials(study, targets, filterComplete, filterPruned)
}, [study?.trials, targets, filterComplete, filterPruned])
return filterTrials(study, targets, filterPruned)
}, [study?.trials, targets, filterPruned])
export const useFilteredTrialsFromStudies = (
studies: StudyDetail[],
targets: Target[],
filterComplete: boolean,
filterPruned: boolean
): Trial[][] =>
useMemo<Trial[][]>(() => {
return studies.map((s) =>
filterTrials(s, targets, filterComplete, filterPruned)
)
}, [studies, targets, filterComplete, filterPruned])
return studies.map((s) => filterTrials(s, targets, filterPruned))
}, [studies, targets, filterPruned])
export const useObjectiveTargets = (
study: StudyDetail | null