diff --git a/src/frontend/src/components/editors/NotesEditor.tsx b/src/frontend/src/components/editors/NotesEditor.tsx index ec37ab247c..7534dab4fa 100644 --- a/src/frontend/src/components/editors/NotesEditor.tsx +++ b/src/frontend/src/components/editors/NotesEditor.tsx @@ -22,6 +22,7 @@ import { Button, Flex, Group, + HoverCard, Paper, Stack, Tabs, @@ -35,6 +36,7 @@ import { IconReload, IconStar } from '@tabler/icons-react'; +import { formatDate } from '../../defaults/formatters'; import { useNoteFields } from '../../forms/CommonForms'; import { useCreateApiFormModal, @@ -47,6 +49,43 @@ import { EditItemAction, OptionsActionDropdown } from '../items/ActionDropdown'; +import { RenderUser } from '../render/User'; + +function NoteInfoHover({ note }: { note: any }) { + if (!note?.pk) { + return null; + } + + return ( + + + + + + + + + + {note.updated && ( + + {t`Updated`} + + {formatDate(note.updated, { showTime: true })} + + + )} + {note.updated_by_detail && ( + + {t`Updated by`} + + + )} + + + + + ); +} export default function NotesEditor({ modelType, @@ -67,7 +106,7 @@ export default function NotesEditor({ const [isDirty, setIsDirty] = useState(false); // The ID of the selected note - const [selectedNote, setSelectedNote] = useState( + const [selectedNoteId, setSelectedNoteId] = useState( undefined ); @@ -94,10 +133,14 @@ export default function NotesEditor({ return editor.onChange(() => setIsDirty(true)); }, [editor]); + const [selectedNote, setSelectedNote] = useState(undefined); + const loadNote = useCallback( (noteId: number) => { const note = notesQuery.data?.find((note: any) => note.pk === noteId); + setSelectedNote(note); + if (note) { const blocks = editor.tryParseHTMLToBlocks(note.content ?? ''); @@ -114,20 +157,20 @@ export default function NotesEditor({ ); useEffect(() => { - loadNote(selectedNote ?? -1); - }, [editor, selectedNote, notesQuery.data]); + loadNote(selectedNoteId ?? -1); + }, [editor, selectedNoteId, notesQuery.data]); // Adjust the note selection useEffect(() => { if (!notesQuery.data) return; const stillExists = - selectedNote && - notesQuery.data.some((note: any) => note.pk === selectedNote); + selectedNoteId && + notesQuery.data.some((note: any) => note.pk === selectedNoteId); if (stillExists) return; const primary = notesQuery.data.find((note: any) => note.primary); - setSelectedNote((primary ?? notesQuery.data[0])?.pk ?? undefined); + setSelectedNoteId((primary ?? notesQuery.data[0])?.pk ?? undefined); }, [notesQuery.data]); const canEdit = useMemo( @@ -154,7 +197,7 @@ export default function NotesEditor({ onFormSuccess: (response: any) => { notesQuery.refetch().then(() => { // Select the newly created note - setSelectedNote(response.pk); + setSelectedNoteId(response.pk); }); } }); @@ -162,9 +205,9 @@ export default function NotesEditor({ const deleteNote = useDeleteApiFormModal({ title: t`Delete Note`, url: apiUrl(ApiEndpoints.note_list), - pk: selectedNote, + pk: selectedNoteId, onFormSuccess: () => { - setSelectedNote(undefined); + setSelectedNoteId(undefined); notesQuery.refetch(); } }); @@ -173,21 +216,21 @@ export default function NotesEditor({ title: t`Edit Note`, fields: noteFields, url: apiUrl(ApiEndpoints.note_list), - pk: selectedNote, + pk: selectedNoteId, onFormSuccess: (response: any) => { notesQuery.refetch().then(() => { // Select the updated note - setSelectedNote(response.pk); + setSelectedNoteId(response.pk); }); } }); const reloadNote = useCallback(() => { - loadNote(selectedNote ?? -1); - }, [selectedNote, loadNote]); + loadNote(selectedNoteId ?? -1); + }, [selectedNoteId, loadNote]); const saveNote = useCallback(() => { - if (!selectedNote) { + if (!selectedNoteId || !editor) { return; } @@ -197,8 +240,8 @@ export default function NotesEditor({ // Sanitize the HTML content before sending to the server (or ensure it's sanitized on the back-end) - if (selectedNote) { - const url = apiUrl(ApiEndpoints.note_list, selectedNote); + if (selectedNoteId) { + const url = apiUrl(ApiEndpoints.note_list, selectedNoteId); notifications.hide('note-update-status'); @@ -227,7 +270,7 @@ export default function NotesEditor({ notesQuery.refetch(); }); } - }, [selectedNote, editor, setIsDirty]); + }, [selectedNoteId, editor, setIsDirty]); useHotkeys([['mod+s', saveNote]]); @@ -243,8 +286,9 @@ export default function NotesEditor({ - Note Title Here - Note description here + + {selectedNote?.title} + {selectedNote?.description} {canEdit && ( @@ -331,7 +375,7 @@ export default function NotesEditor({ {notesQuery.data?.map((note: any) => ( @@ -339,7 +383,7 @@ export default function NotesEditor({ key={note.pk} disabled={isDirty} value={note.pk?.toString()} - onClick={() => setSelectedNote(note.pk)} + onClick={() => setSelectedNoteId(note.pk)} > {note.title}