Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemathinc
GitHub Repository: sagemathinc/cocalc
Path: blob/master/src/packages/frontend/course/common/private-notes.tsx
10799 views
1
/*
2
* This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.
3
* License: MS-RSL – see LICENSE.md for details
4
*/
5
6
import { Button, Space } from "antd";
7
import { useEffect, useState } from "react";
8
import { useIntl } from "react-intl";
9
10
import { Icon, Tip } from "@cocalc/frontend/components";
11
import MultiMarkdownInput from "@cocalc/frontend/editors/markdown-input/multimode";
12
import StaticMarkdown from "@cocalc/frontend/editors/slate/static-markdown";
13
14
interface PrivateNotesProps {
15
title: string;
16
tip: string;
17
value: string;
18
onSave: (value: string) => void;
19
placeholder: string;
20
persistId: string;
21
}
22
23
interface PersistedNoteState {
24
editing: boolean;
25
value: string;
26
}
27
28
const persistedNotes = new Map<string, PersistedNoteState>();
29
30
export function PrivateNotes({
31
title,
32
tip,
33
value,
34
onSave,
35
placeholder,
36
persistId,
37
}: PrivateNotesProps) {
38
const intl = useIntl();
39
const [noteValue, setNoteValue] = useState<string>(value);
40
const [editing, setEditing] = useState<boolean>(false);
41
const editLabel = intl.formatMessage({
42
id: "course.notes.edit_label",
43
defaultMessage: "Notes:",
44
});
45
const doneLabel = intl.formatMessage({
46
id: "course.notes.done_label",
47
defaultMessage: "Done",
48
});
49
50
useEffect(() => {
51
const persisted = persistedNotes.get(persistId);
52
if (persisted != null) {
53
setNoteValue(persisted.value);
54
setEditing(persisted.editing);
55
} else {
56
setNoteValue(value);
57
setEditing(false);
58
}
59
}, [persistId]);
60
61
useEffect(() => {
62
if (editing) return;
63
const persisted = persistedNotes.get(persistId);
64
if (persisted?.editing) return;
65
setNoteValue(value);
66
}, [editing, persistId, value]);
67
68
useEffect(() => {
69
if (editing || noteValue !== value) {
70
persistedNotes.set(persistId, { editing, value: noteValue });
71
} else {
72
persistedNotes.delete(persistId);
73
}
74
}, [editing, noteValue, persistId, value]);
75
76
function toggle() {
77
if (editing) {
78
onSave(noteValue);
79
}
80
setEditing(!editing);
81
}
82
83
return (
84
<Space
85
key="note"
86
align="start"
87
style={{
88
display: "grid",
89
gridTemplateColumns: "auto 1fr",
90
}}
91
>
92
<Tip title={title} tip={tip}>
93
<Button
94
icon={<Icon name="pencil" />}
95
type={editing ? "primary" : "default"}
96
onClick={toggle}
97
>
98
{editing ? doneLabel : editLabel}
99
</Button>
100
</Tip>
101
<div style={{ minWidth: 0, width: "100%" }}>
102
{editing ? (
103
<MultiMarkdownInput
104
value={noteValue}
105
onChange={setNoteValue}
106
placeholder={placeholder}
107
height="200px"
108
minimal
109
enableUpload={false}
110
/>
111
) : (
112
<StaticMarkdown value={noteValue ?? ""} />
113
)}
114
</div>
115
</Space>
116
);
117
}
118
119