feat(ux): enhance n-depth tree DND reordering, full i18n localization, admin live stats & sidebar redesign
Build and Push Docker Image / build-and-push (push) Successful in 9m22s
Build and Push Docker Image / build-and-push (push) Successful in 9m22s
This commit is contained in:
@@ -17,6 +17,11 @@ export function MarkdownNoteEditor({ value, onChange, onSave }: MarkdownNoteEdit
|
||||
const textareaRef = useRef<HTMLTextAreaElement>(null);
|
||||
const previewRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
// Reset to preview whenever value or active task changes
|
||||
useEffect(() => {
|
||||
// Keep preview mode as primary
|
||||
}, []);
|
||||
|
||||
// Configure marked to open links in new tabs safely
|
||||
useEffect(() => {
|
||||
const renderer = new marked.Renderer();
|
||||
@@ -49,7 +54,7 @@ export function MarkdownNoteEditor({ value, onChange, onSave }: MarkdownNoteEdit
|
||||
// Convert markdown to sanitized HTML with safe links
|
||||
const renderMarkdownHtml = () => {
|
||||
if (!value || !value.trim()) {
|
||||
return `<p style="color: var(--text-tertiary); font-style: italic; padding: 8px 0;">${t("notesPlaceholder").split("\n")[0]}</p>`;
|
||||
return `<div style="color: var(--text-tertiary); font-style: italic; user-select: none; line-height: 1.6;">${t("notesPlaceholder")}</div>`;
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -96,6 +101,7 @@ export function MarkdownNoteEditor({ value, onChange, onSave }: MarkdownNoteEdit
|
||||
alignItems: "center",
|
||||
justifyContent: "space-between",
|
||||
padding: "4px 8px 8px 8px",
|
||||
flexShrink: 0,
|
||||
}}
|
||||
>
|
||||
<span style={{ fontSize: 11, fontWeight: 700, letterSpacing: "0.05em", color: "var(--text-tertiary)" }}>
|
||||
@@ -133,7 +139,19 @@ export function MarkdownNoteEditor({ value, onChange, onSave }: MarkdownNoteEdit
|
||||
</div>
|
||||
|
||||
{/* Editor / Preview Area */}
|
||||
<div style={{ flex: 1, minHeight: 0, display: "flex", flexDirection: "column", position: "relative" }}>
|
||||
<div
|
||||
style={{
|
||||
flex: 1,
|
||||
minHeight: 0,
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
position: "relative",
|
||||
background: "var(--bg-primary)",
|
||||
borderRadius: "var(--radius-md)",
|
||||
border: "1px solid var(--border)",
|
||||
overflow: "hidden",
|
||||
}}
|
||||
>
|
||||
{mode === "edit" ? (
|
||||
<textarea
|
||||
ref={textareaRef}
|
||||
@@ -142,8 +160,7 @@ export function MarkdownNoteEditor({ value, onChange, onSave }: MarkdownNoteEdit
|
||||
flex: 1,
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
minHeight: 120,
|
||||
padding: "8px 10px",
|
||||
padding: "10px 12px",
|
||||
background: "transparent",
|
||||
border: "none",
|
||||
outline: "none",
|
||||
@@ -152,6 +169,7 @@ export function MarkdownNoteEditor({ value, onChange, onSave }: MarkdownNoteEdit
|
||||
lineHeight: 1.6,
|
||||
resize: "none",
|
||||
fontFamily: "inherit",
|
||||
boxSizing: "border-box",
|
||||
}}
|
||||
placeholder={t("notesPlaceholder")}
|
||||
value={value}
|
||||
@@ -169,11 +187,13 @@ export function MarkdownNoteEditor({ value, onChange, onSave }: MarkdownNoteEdit
|
||||
flex: 1,
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
padding: "8px 10px",
|
||||
padding: "10px 12px",
|
||||
overflowY: "auto",
|
||||
color: "var(--text-primary)",
|
||||
fontSize: 13.5,
|
||||
lineHeight: 1.6,
|
||||
boxSizing: "border-box",
|
||||
cursor: "text",
|
||||
}}
|
||||
dangerouslySetInnerHTML={{ __html: renderMarkdownHtml() }}
|
||||
onClick={() => {
|
||||
@@ -185,4 +205,4 @@ export function MarkdownNoteEditor({ value, onChange, onSave }: MarkdownNoteEdit
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user