Path: blob/master/src/packages/frontend/course/common/private-notes.tsx
10799 views
/*1* This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.2* License: MS-RSL – see LICENSE.md for details3*/45import { Button, Space } from "antd";6import { useEffect, useState } from "react";7import { useIntl } from "react-intl";89import { Icon, Tip } from "@cocalc/frontend/components";10import MultiMarkdownInput from "@cocalc/frontend/editors/markdown-input/multimode";11import StaticMarkdown from "@cocalc/frontend/editors/slate/static-markdown";1213interface PrivateNotesProps {14title: string;15tip: string;16value: string;17onSave: (value: string) => void;18placeholder: string;19persistId: string;20}2122interface PersistedNoteState {23editing: boolean;24value: string;25}2627const persistedNotes = new Map<string, PersistedNoteState>();2829export function PrivateNotes({30title,31tip,32value,33onSave,34placeholder,35persistId,36}: PrivateNotesProps) {37const intl = useIntl();38const [noteValue, setNoteValue] = useState<string>(value);39const [editing, setEditing] = useState<boolean>(false);40const editLabel = intl.formatMessage({41id: "course.notes.edit_label",42defaultMessage: "Notes:",43});44const doneLabel = intl.formatMessage({45id: "course.notes.done_label",46defaultMessage: "Done",47});4849useEffect(() => {50const persisted = persistedNotes.get(persistId);51if (persisted != null) {52setNoteValue(persisted.value);53setEditing(persisted.editing);54} else {55setNoteValue(value);56setEditing(false);57}58}, [persistId]);5960useEffect(() => {61if (editing) return;62const persisted = persistedNotes.get(persistId);63if (persisted?.editing) return;64setNoteValue(value);65}, [editing, persistId, value]);6667useEffect(() => {68if (editing || noteValue !== value) {69persistedNotes.set(persistId, { editing, value: noteValue });70} else {71persistedNotes.delete(persistId);72}73}, [editing, noteValue, persistId, value]);7475function toggle() {76if (editing) {77onSave(noteValue);78}79setEditing(!editing);80}8182return (83<Space84key="note"85align="start"86style={{87display: "grid",88gridTemplateColumns: "auto 1fr",89}}90>91<Tip title={title} tip={tip}>92<Button93icon={<Icon name="pencil" />}94type={editing ? "primary" : "default"}95onClick={toggle}96>97{editing ? doneLabel : editLabel}98</Button>99</Tip>100<div style={{ minWidth: 0, width: "100%" }}>101{editing ? (102<MultiMarkdownInput103value={noteValue}104onChange={setNoteValue}105placeholder={placeholder}106height="200px"107minimal108enableUpload={false}109/>110) : (111<StaticMarkdown value={noteValue ?? ""} />112)}113</div>114</Space>115);116}117118119