From 963e58a11652bf4ede4807511aec34409c4626e5 Mon Sep 17 00:00:00 2001 From: c-bata Date: Thu, 8 Aug 2024 00:59:02 +0900 Subject: [PATCH] Fix scrolling issue of jupyter lab --- Makefile | 5 +++ jupyterlab/src/apiClient.ts | 4 +- .../src/components/JupyterLabEntrypoint.tsx | 12 +++--- optuna_dashboard/ts/components/App.tsx | 20 +++++----- optuna_dashboard/ts/components/AppDrawer.tsx | 29 +++++++++----- .../ts/components/BestTrialsCard.tsx | 6 +-- .../ts/components/CompareStudies.tsx | 8 ++-- .../ts/components/GraphHistory.tsx | 4 +- .../ts/components/GraphParetoFront.tsx | 4 +- .../ts/components/StudyDetail.tsx | 4 +- optuna_dashboard/ts/components/StudyList.tsx | 6 +-- optuna_dashboard/ts/components/TrialList.tsx | 8 ++-- optuna_dashboard/ts/components/TrialTable.tsx | 4 +- optuna_dashboard/ts/constantsProvider.tsx | 38 ++++--------------- optuna_dashboard/ts/index.tsx | 22 +++++++---- optuna_dashboard/ts/pkg_index.tsx | 4 +- optuna_dashboard/webpack.config.js | 3 -- 17 files changed, 89 insertions(+), 92 deletions(-) diff --git a/Makefile b/Makefile index f0fe5624..5ec4ef58 100644 --- a/Makefile +++ b/Makefile @@ -37,6 +37,11 @@ serve-browser-app: tslib $(RUSTLIB_OUT) vscode-extension: vscode/assets/bundle.js cd vscode && npm install && npm run vscode:prepublish && vsce package +.PHONY: jupyterlab-extension +jupyterlab-extension: tslib + cd optuna_dashboard && npm install && npm run build:pkg + cd jupyterlab && python -m build --sdist + .PHONY: sdist sdist: pyproject.toml $(DASHBOARD_TS_OUT) python -m build --sdist diff --git a/jupyterlab/src/apiClient.ts b/jupyterlab/src/apiClient.ts index 2bf4faf7..c8c0a7c7 100644 --- a/jupyterlab/src/apiClient.ts +++ b/jupyterlab/src/apiClient.ts @@ -231,7 +231,9 @@ export class JupyterlabAPIClient extends APIClient { }) return } - getParamImportances = (studyId: number): Promise => + getParamImportances = ( + studyId: number + ): Promise => requestAPI( `/api/studies/${studyId}/param_importances` ).then((res) => { diff --git a/jupyterlab/src/components/JupyterLabEntrypoint.tsx b/jupyterlab/src/components/JupyterLabEntrypoint.tsx index 46dee6c4..fdd5fb84 100644 --- a/jupyterlab/src/components/JupyterLabEntrypoint.tsx +++ b/jupyterlab/src/components/JupyterLabEntrypoint.tsx @@ -11,7 +11,7 @@ import CircularProgress from "@mui/material/CircularProgress" import { APIClientProvider, App, - ConstantsProvider, + ConstantsContext, } from "@optuna/optuna-dashboard" import { SnackbarProvider, enqueueSnackbar } from "notistack" import React, { Dispatch, FC, SetStateAction, useEffect, useState } from "react" @@ -54,14 +54,16 @@ export const JupyterLabEntrypoint: FC = () => { ) } return ( - - + ) } diff --git a/optuna_dashboard/ts/components/App.tsx b/optuna_dashboard/ts/components/App.tsx index 7171b62a..2b84e182 100644 --- a/optuna_dashboard/ts/components/App.tsx +++ b/optuna_dashboard/ts/components/App.tsx @@ -50,7 +50,7 @@ export const App: FC = () => { setColorMode(colorMode === "dark" ? "light" : "dark") } - const { URL_PREFIX } = useConstants() + const { url_prefix } = useConstants() return ( @@ -69,7 +69,7 @@ export const App: FC = () => { { } /> { } /> { } /> { } /> { } /> { } /> { } /> } /> } /> diff --git a/optuna_dashboard/ts/components/AppDrawer.tsx b/optuna_dashboard/ts/components/AppDrawer.tsx index a37896c1..8b81f93b 100644 --- a/optuna_dashboard/ts/components/AppDrawer.tsx +++ b/optuna_dashboard/ts/components/AppDrawer.tsx @@ -21,7 +21,7 @@ import ListItemIcon from "@mui/material/ListItemIcon" import ListItemText from "@mui/material/ListItemText" import Modal from "@mui/material/Modal" import Toolbar from "@mui/material/Toolbar" -import { CSSObject, Theme, styled, useTheme } from "@mui/material/styles" +import { CSSObject, SxProps, Theme, styled, useTheme } from "@mui/material/styles" import React, { FC } from "react" import { Link } from "react-router-dom" import { useRecoilState, useRecoilValue } from "recoil" @@ -130,9 +130,10 @@ export const AppDrawer: FC<{ toolbar: React.ReactNode children?: React.ReactNode }> = ({ studyId, toggleColorMode, page, toolbar, children }) => { - const { URL_PREFIX } = useConstants() + const { url_prefix } = useConstants() const theme = useTheme() + const constants = useConstants() const action = actionCreator() const [open, setOpen] = useRecoilState(drawerOpenState) const reloadInterval = useRecoilValue(reloadIntervalState) @@ -158,6 +159,14 @@ export const AppDrawer: FC<{ const styleSwitch = { display: open ? "inherit" : "none", } + const mainSx: SxProps = { + flexGrow: 1, + } + if (constants.environment === "jupyterlab") { + // 100vh - (the height of Optuna Dashboard toolbar) - (the height of JupyterLab toolbar) + mainSx.height = `calc(100vh - ${theme.mixins.toolbar.minHeight}px - 29px)` + mainSx.overflow = "auto" + } const handleDrawerOpen = () => { setOpen(true) @@ -212,7 +221,7 @@ export const AppDrawer: FC<{ @@ -233,7 +242,7 @@ export const AppDrawer: FC<{ > @@ -250,7 +259,7 @@ export const AppDrawer: FC<{ @@ -264,7 +273,7 @@ export const AppDrawer: FC<{ @@ -281,7 +290,7 @@ export const AppDrawer: FC<{ @@ -294,7 +303,7 @@ export const AppDrawer: FC<{ @@ -307,7 +316,7 @@ export const AppDrawer: FC<{ @@ -419,7 +428,7 @@ export const AppDrawer: FC<{ - + {children || null} diff --git a/optuna_dashboard/ts/components/BestTrialsCard.tsx b/optuna_dashboard/ts/components/BestTrialsCard.tsx index 69291b0e..3547e133 100644 --- a/optuna_dashboard/ts/components/BestTrialsCard.tsx +++ b/optuna_dashboard/ts/components/BestTrialsCard.tsx @@ -24,7 +24,7 @@ const useBestTrials = (studyDetail: StudyDetail | null): Trial[] => { export const BestTrialsCard: FC<{ studyDetail: StudyDetail | null }> = ({ studyDetail }) => { - const { URL_PREFIX } = useConstants() + const { url_prefix } = useConstants() const theme = useTheme() const bestTrials = useBestTrials(studyDetail) @@ -64,7 +64,7 @@ export const BestTrialsCard: FC<{ variant="outlined" startIcon={} component={Link} - to={`${URL_PREFIX}/studies/${bestTrial.study_id}/trials?numbers=${bestTrial.number}`} + to={`${url_prefix}/studies/${bestTrial.study_id}/trials?numbers=${bestTrial.number}`} sx={{ margin: theme.spacing(1) }} > Details @@ -92,7 +92,7 @@ export const BestTrialsCard: FC<{ void }> = ({ toggleColorMode }) => { - const { URL_PREFIX } = useConstants() + const { url_prefix } = useConstants() const { enqueueSnackbar } = useSnackbar() const theme = useTheme() @@ -101,7 +101,7 @@ export const CompareStudies: FC<{ <> = ({ studies, logScale, includePruned }) => { - const { URL_PREFIX } = useConstants() + const { url_prefix } = useConstants() const theme = useTheme() const colorTheme = usePlotlyColorTheme(theme.palette.mode) @@ -103,7 +103,7 @@ export const GraphHistory: FC<{ studyId = studies[Math.floor(data.points[0].curveNumber / 2)].id } navigate( - URL_PREFIX + + url_prefix + `/studies/${studyId}/trials?numbers=${data.points[0].x}` ) } diff --git a/optuna_dashboard/ts/components/GraphParetoFront.tsx b/optuna_dashboard/ts/components/GraphParetoFront.tsx index 2e0237da..41444ed5 100644 --- a/optuna_dashboard/ts/components/GraphParetoFront.tsx +++ b/optuna_dashboard/ts/components/GraphParetoFront.tsx @@ -62,7 +62,7 @@ const GraphParetoFrontBackend: FC<{ const GraphParetoFrontFrontend: FC<{ study: StudyDetail | null }> = ({ study = null }) => { - const { URL_PREFIX } = useConstants() + const { url_prefix } = useConstants() const theme = useTheme() const colorTheme = usePlotlyColorTheme(theme.palette.mode) @@ -96,7 +96,7 @@ const GraphParetoFrontFrontend: FC<{ data.points[0].text.replace(/
/g, "") ) navigate( - URL_PREFIX + + url_prefix + `/studies/${study.id}/trials?numbers=${plotTextInfo.number}` ) }) diff --git a/optuna_dashboard/ts/components/StudyDetail.tsx b/optuna_dashboard/ts/components/StudyDetail.tsx index 53fc4389..f832ec7f 100644 --- a/optuna_dashboard/ts/components/StudyDetail.tsx +++ b/optuna_dashboard/ts/components/StudyDetail.tsx @@ -50,7 +50,7 @@ export const StudyDetail: FC<{ toggleColorMode: () => void page: PageId }> = ({ toggleColorMode, page }) => { - const { URL_PREFIX } = useConstants() + const { url_prefix } = useConstants() const theme = useTheme() const action = actionCreator() @@ -226,7 +226,7 @@ export const StudyDetail: FC<{ <> void }> = ({ toggleColorMode }) => { - const { URL_PREFIX } = useConstants() + const { url_prefix } = useConstants() const theme = useTheme() const action = actionCreator() @@ -155,7 +155,7 @@ export const StudyList: FC<{ > @@ -260,7 +260,7 @@ export const StudyList: FC<{ variant="outlined" startIcon={} component={Link} - to={`${URL_PREFIX}/compare-studies`} + to={`${url_prefix}/compare-studies`} sx={{ marginRight: theme.spacing(2), minWidth: "120px" }} > Compare diff --git a/optuna_dashboard/ts/components/TrialList.tsx b/optuna_dashboard/ts/components/TrialList.tsx index 606aa08a..46da5d51 100644 --- a/optuna_dashboard/ts/components/TrialList.tsx +++ b/optuna_dashboard/ts/components/TrialList.tsx @@ -335,7 +335,7 @@ const getTrialListLink = ( export const TrialList: FC<{ studyDetail: StudyDetail | null }> = ({ studyDetail, }) => { - const { URL_PREFIX } = useConstants() + const { url_prefix } = useConstants() const theme = useTheme() const query = useQuery() @@ -425,7 +425,7 @@ export const TrialList: FC<{ studyDetail: StudyDetail | null }> = ({ studyDetail.id, excludedStates, numbers, - URL_PREFIX + url_prefix ) ) }} @@ -489,7 +489,7 @@ export const TrialList: FC<{ studyDetail: StudyDetail | null }> = ({ trial.study_id, excludedStates, next, - URL_PREFIX + url_prefix ) ) } else { @@ -498,7 +498,7 @@ export const TrialList: FC<{ studyDetail: StudyDetail | null }> = ({ trial.study_id, excludedStates, [trial.number], - URL_PREFIX + url_prefix ) ) } diff --git a/optuna_dashboard/ts/components/TrialTable.tsx b/optuna_dashboard/ts/components/TrialTable.tsx index a45d56e3..99b5e8b1 100644 --- a/optuna_dashboard/ts/components/TrialTable.tsx +++ b/optuna_dashboard/ts/components/TrialTable.tsx @@ -28,7 +28,7 @@ const multiValueFilter: FilterFn = ( export const TrialTable: FC<{ studyDetail: StudyDetail | null }> = ({ studyDetail }) => { - const { URL_PREFIX } = useConstants() + const { url_prefix } = useConstants() const theme = useTheme() const trials: Trial[] = studyDetail !== null ? studyDetail.trials : [] @@ -127,7 +127,7 @@ export const TrialTable: FC<{ (undefined) +export const ConstantsContext = React.createContext({ + environment: "optuna-dashboard", + url_prefix: "", +}) export const useConstants = (): ConstantsContextType => { - const context = React.useContext(ConstantsContext) - if (context === undefined) { - throw new Error("useConstants must be used within a ConstantsProvider.") - } - return context -} - -export function ConstantsProvider({ - APP_BAR_TITLE, - API_ENDPOINT, - URL_PREFIX, - children, -}: { - APP_BAR_TITLE: string - API_ENDPOINT?: string - URL_PREFIX: string - children: React.ReactNode -}) { - return ( - - {children} - - ) + return React.useContext(ConstantsContext) } diff --git a/optuna_dashboard/ts/index.tsx b/optuna_dashboard/ts/index.tsx index 319be5a7..66d7b1f2 100644 --- a/optuna_dashboard/ts/index.tsx +++ b/optuna_dashboard/ts/index.tsx @@ -1,24 +1,30 @@ -import React from "react" +import React, { FC, ReactNode } from "react" import ReactDOM from "react-dom/client" import { APIClientProvider } from "./apiClientProvider" import { AxiosClient } from "./axiosClient" import { App } from "./components/App" -import { ConstantsProvider } from "./constantsProvider" +import { ConstantsContext } from "./constantsProvider" -declare const APP_BAR_TITLE: string declare const API_ENDPOINT: string declare const URL_PREFIX: string const axiosAPIClient = new AxiosClient(API_ENDPOINT) +const ConstantsProvider: FC<{ children: ReactNode }> = ({ children }) => ( + + {children} + +) + ReactDOM.createRoot(document.getElementById("dashboard") as HTMLElement).render( - + diff --git a/optuna_dashboard/ts/pkg_index.tsx b/optuna_dashboard/ts/pkg_index.tsx index 303a0efa..92c220f2 100644 --- a/optuna_dashboard/ts/pkg_index.tsx +++ b/optuna_dashboard/ts/pkg_index.tsx @@ -16,7 +16,7 @@ import { import { APIClientProvider } from "./apiClientProvider" import { AxiosClient } from "./axiosClient" import { App } from "./components/App" -import { ConstantsProvider } from "./constantsProvider" +import { ConstantsContext } from "./constantsProvider" import { Artifact, FeedbackComponentType, @@ -37,7 +37,7 @@ export { APIClientProvider, App, APIClient, - ConstantsProvider, + ConstantsContext, Artifact, FeedbackComponentType, FormWidgets, diff --git a/optuna_dashboard/webpack.config.js b/optuna_dashboard/webpack.config.js index 58beed84..fe8dfbdd 100644 --- a/optuna_dashboard/webpack.config.js +++ b/optuna_dashboard/webpack.config.js @@ -54,9 +54,6 @@ var config = { }, plugins: [ new webpack.DefinePlugin({ - APP_BAR_TITLE: JSON.stringify( - process.env.APP_BAR_TITLE || "Optuna Dashboard" - ), API_ENDPOINT: JSON.stringify(process.env.API_ENDPOINT), URL_PREFIX: JSON.stringify(process.env.URL_PREFIX || "/dashboard"), }),