diff --git a/optuna_dashboard/ts/components/Note.tsx b/optuna_dashboard/ts/components/Note.tsx
index f563c7f4..86091ddc 100644
--- a/optuna_dashboard/ts/components/Note.tsx
+++ b/optuna_dashboard/ts/components/Note.tsx
@@ -4,6 +4,11 @@ import {
Card,
CardContent,
CardHeader,
+ Dialog,
+ DialogActions,
+ DialogContent,
+ DialogContentText,
+ DialogTitle,
IconButton,
SxProps,
TextField,
@@ -23,6 +28,8 @@ import {
CodeComponent,
ReactMarkdownNames,
} from "react-markdown/lib/ast-to-react"
+import HtmlIcon from "@mui/icons-material/Html"
+import ModeEditIcon from "@mui/icons-material/ModeEdit"
import { Prism as SyntaxHighlighter } from "react-syntax-highlighter"
import { darcula } from "react-syntax-highlighter/dist/esm/styles/prism"
@@ -75,20 +82,72 @@ export const StudyNote: FC<{
return
}
+const useConfirmCloseDialog = (
+ handleClose: () => void
+): [() => void, () => React.ReactNode] => {
+ const theme = useTheme()
+ const [open, setOpen] = useState(false)
+
+ const zIndex = theme.zIndex.snackbar - 1
+ const openDialog = () => {
+ setOpen(true)
+ }
+ const renderDialog = () => {
+ return (
+
+ )
+ }
+ return [openDialog, renderDialog]
+}
+
const MarkdownEditorModal: FC<{
studyId: number
trialId?: number
latestNote: Note
- onClose: () => void
-}> = ({ studyId, trialId, latestNote, onClose }) => {
+ setEditorUnmount: () => void
+}> = ({ studyId, trialId, latestNote, setEditorUnmount }) => {
const theme = useTheme()
const action = actionCreator()
+ const [openConfirmCloseDialog, renderConfirmCloseDialog] =
+ useConfirmCloseDialog(() => {
+ setEditorUnmount()
+ window.onbeforeunload = null
+ })
+
const [saving, setSaving] = useState(false)
const [edited, setEdited] = useState(false)
const [curNote, setCurNote] = useState({ version: 0, body: "" })
const textAreaRef = createRef()
const notLatest = latestNote.version > curNote.version
+ const [previewMarkdown, setPreviewMarkdown] = useState("")
+ const [preview, setPreview] = useState(false)
+
useEffect(() => {
setCurNote(latestNote)
}, [])
@@ -118,6 +177,7 @@ const MarkdownEditorModal: FC<{
.then(() => {
setCurNote(newNote)
window.onbeforeunload = null
+ setEditorUnmount()
})
.finally(() => {
setSaving(false)
@@ -134,7 +194,7 @@ const MarkdownEditorModal: FC<{
}
// See https://github.com/iamhosseindhv/notistack/issues/231#issuecomment-825924840
- const zIndex = theme.zIndex.snackbar - 1
+ const zIndex = theme.zIndex.snackbar - 2
return (
+ {
+ setPreview(!preview)
+ setPreviewMarkdown(
+ textAreaRef.current ? textAreaRef.current.value : ""
+ )
+ }}
+ >
+ {preview ? (
+
+ ) : (
+
+ )}
+
+ }
+ title="Markdown Editor"
+ />
+
+
+
{
const cur = textAreaRef.current ? textAreaRef.current.value : ""
- setEdited(cur !== curNote.body)
+ if (edited !== (cur !== curNote.body)) {
+ setEdited(cur !== curNote.body)
+ }
}}
/>
@@ -201,7 +297,17 @@ const MarkdownEditorModal: FC<{
>
)}
- }>
+
+ {renderConfirmCloseDialog()}
)
}
@@ -227,18 +334,18 @@ const NoteBase: FC<{
cardSx?: SxProps
}> = ({ studyId, trialId, latestNote, cardSx }) => {
const theme = useTheme()
- const [editorOpen, setEditorOpen] = useState(false)
+ const [editorMounted, setEditorMounted] = useState(false)
const defaultBody =
"*A markdown editor for taking a memo, related to the study. Click the 'Edit' button in the upper right corner to access the editor.*"
return (
-
+
{
- setEditorOpen(true)
+ setEditorMounted(true)
}}
>
@@ -254,13 +361,13 @@ const NoteBase: FC<{
components={{ code: CodeBlock }}
/>
- {editorOpen && (
+ {editorMounted && (
{
- setEditorOpen(false)
+ setEditorUnmount={() => {
+ setEditorMounted(false)
}}
/>
)}