From b366191d828aad0c3e21da23ffb4e3a6fb24f73b Mon Sep 17 00:00:00 2001 From: c-bata Date: Sat, 19 Mar 2022 02:27:20 +0900 Subject: [PATCH] Add saving state --- optuna_dashboard/_app.py | 11 +++++---- optuna_dashboard/static/action.ts | 5 ++-- optuna_dashboard/static/apiClient.ts | 2 +- optuna_dashboard/static/components/Note.tsx | 24 +++++++++++++------ .../static/components/StudyDetail.tsx | 7 +++++- 5 files changed, 34 insertions(+), 15 deletions(-) diff --git a/optuna_dashboard/_app.py b/optuna_dashboard/_app.py index 3caec909..50762650 100644 --- a/optuna_dashboard/_app.py +++ b/optuna_dashboard/_app.py @@ -282,20 +282,23 @@ def create_app(storage: BaseStorage) -> Bottle: ], } - @app.post("/api/studies//note") + @app.put("/api/studies//note") @handle_json_api_exception def save_note(study_id: int) -> BottleViewReturn: response.content_type = "application/json" - system_attrs = storage.get_study_system_attrs(study_id) req_note_ver = request.json.get("version", None) req_note_body = request.json.get("body", None) if req_note_ver is None or req_note_body is None: response.status = 400 # Bad request return {"reason": "Invalid request."} + + system_attrs = storage.get_study_system_attrs(study_id) if not note.version_is_incremented(system_attrs, req_note_ver): - response.status = 400 # Bad request - return {"reason": "The text you are editing has changed. Please copy your edits and refresh the page."} + response.status = 409 # Conflict + return { + "reason": "The text you are editing has changed. Please copy your edits and refresh the page.", + } note.save_note(storage, study_id, req_note_ver, req_note_body) response.status = 204 # No content diff --git a/optuna_dashboard/static/action.ts b/optuna_dashboard/static/action.ts index 4f398497..76118c3f 100644 --- a/optuna_dashboard/static/action.ts +++ b/optuna_dashboard/static/action.ts @@ -96,8 +96,8 @@ export const actionCreator = () => { }) } - const saveNote = (studyId: number, note: Note) => { - saveNoteAPI(studyId, note) + const saveNote = (studyId: number, note: Note): Promise => { + return saveNoteAPI(studyId, note) .then(() => { const newStudy = Object.assign({}, studyDetails[studyId]) newStudy.note = note @@ -113,6 +113,7 @@ export const actionCreator = () => { enqueueSnackbar(`Failed: ${reason}`, { variant: "error", }) + throw err }) } diff --git a/optuna_dashboard/static/apiClient.ts b/optuna_dashboard/static/apiClient.ts index ab76c74e..55495b77 100644 --- a/optuna_dashboard/static/apiClient.ts +++ b/optuna_dashboard/static/apiClient.ts @@ -189,7 +189,7 @@ export const saveNoteAPI = ( note: { version: number; body: string } ): Promise => { return axiosInstance - .post(`/api/studies/${studyId}/note`, note) + .put(`/api/studies/${studyId}/note`, note) .then((res) => { return }) diff --git a/optuna_dashboard/static/components/Note.tsx b/optuna_dashboard/static/components/Note.tsx index 0e01d1a9..24b7bf7c 100644 --- a/optuna_dashboard/static/components/Note.tsx +++ b/optuna_dashboard/static/components/Note.tsx @@ -10,6 +10,7 @@ export const Note: FC<{ latestNote: Note }> = ({ studyId, latestNote }) => { const theme = useTheme() + const [saving, setSaving] = useState(false) const [disable, setDisable] = useState(true) const [curNote, setCurNote] = useState({ version: 0, body: "" }) const textAreaRef = createRef() @@ -20,12 +21,20 @@ export const Note: FC<{ setCurNote(latestNote) }, []) const handleSave = () => { + const nextVersion = curNote.version + 1 const newNote = { - version: curNote.version + 1, - body: textAreaRef.current ? textAreaRef.current.value : "" + version: nextVersion, + body: textAreaRef.current ? textAreaRef.current.value : "", } - setCurNote(newNote) - action.saveNote(studyId, newNote) + setSaving(true) + action + .saveNote(studyId, newNote) + .then(() => { + setCurNote(newNote) + }) + .finally(() => { + setSaving(false) + }) } const handleRefresh = () => { if (!textAreaRef.current) { @@ -39,6 +48,7 @@ export const Note: FC<{ return ( <> { const cur = textAreaRef.current ? textAreaRef.current.value : "" - setDisable(cur === latestNote.body) + setDisable(cur === curNote.body) }} /> - {notLatest && ( + {notLatest && !saving && ( <> } variant="contained" diff --git a/optuna_dashboard/static/components/StudyDetail.tsx b/optuna_dashboard/static/components/StudyDetail.tsx index 1796bcec..1373e5ed 100644 --- a/optuna_dashboard/static/components/StudyDetail.tsx +++ b/optuna_dashboard/static/components/StudyDetail.tsx @@ -385,7 +385,12 @@ export const StudyDetail: FC<{ - Note + + Note + {studyDetail !== null && ( )}