mirror of
https://github.com/zadam/trilium.git
synced 2025-12-16 20:34:25 +01:00
feat(layout): edited notes underneath title details
This commit is contained in:
parent
8e6ea87754
commit
9d7e2855d3
@ -1758,7 +1758,8 @@
|
|||||||
"note_type_switcher_label": "Switch from {{type}} to:",
|
"note_type_switcher_label": "Switch from {{type}} to:",
|
||||||
"note_type_switcher_others": "More note types",
|
"note_type_switcher_others": "More note types",
|
||||||
"note_type_switcher_templates": "Templates",
|
"note_type_switcher_templates": "Templates",
|
||||||
"note_type_switcher_collection": "Collections"
|
"note_type_switcher_collection": "Collections",
|
||||||
|
"edited_notes": "Edited notes"
|
||||||
},
|
},
|
||||||
"search_result": {
|
"search_result": {
|
||||||
"no_notes_found": "No notes have been found for given search parameters.",
|
"no_notes_found": "No notes have been found for given search parameters.",
|
||||||
|
|||||||
@ -89,3 +89,21 @@ body.prefers-centered-content .inline-title {
|
|||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.edited-notes {
|
||||||
|
padding-top: 1em;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 0.3em;
|
||||||
|
|
||||||
|
.badge {
|
||||||
|
margin: 0;
|
||||||
|
a.tn-link {
|
||||||
|
color: inherit;
|
||||||
|
text-transform: none;
|
||||||
|
text-decoration: none;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@ -16,10 +16,12 @@ import server from "../../services/server";
|
|||||||
import { formatDateTime } from "../../utils/formatters";
|
import { formatDateTime } from "../../utils/formatters";
|
||||||
import NoteIcon from "../note_icon";
|
import NoteIcon from "../note_icon";
|
||||||
import NoteTitleWidget from "../note_title";
|
import NoteTitleWidget from "../note_title";
|
||||||
import { Badge, BadgeWithDropdown } from "../react/Badge";
|
import SimpleBadge, { Badge, BadgeWithDropdown } from "../react/Badge";
|
||||||
import { FormDropdownDivider, FormListItem } from "../react/FormList";
|
import { FormDropdownDivider, FormListItem } from "../react/FormList";
|
||||||
import { useNoteBlob, useNoteContext, useNoteProperty, useStaticTooltip, useTriliumEvent } from "../react/hooks";
|
import { useNoteBlob, useNoteContext, useNoteLabel, useNoteProperty, useStaticTooltip, useTriliumEvent } from "../react/hooks";
|
||||||
|
import NoteLink from "../react/NoteLink";
|
||||||
import { joinElements } from "../react/react_utils";
|
import { joinElements } from "../react/react_utils";
|
||||||
|
import { useEditedNotes } from "../ribbon/EditedNotesTab";
|
||||||
import { useNoteMetadata } from "../ribbon/NoteInfoTab";
|
import { useNoteMetadata } from "../ribbon/NoteInfoTab";
|
||||||
import { onWheelHorizontalScroll } from "../widget_utils";
|
import { onWheelHorizontalScroll } from "../widget_utils";
|
||||||
|
|
||||||
@ -72,6 +74,7 @@ export default function InlineTitle() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<NoteTitleDetails />
|
<NoteTitleDetails />
|
||||||
|
<EditedNotes />
|
||||||
<NoteTypeSwitcher />
|
<NoteTypeSwitcher />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@ -301,3 +304,38 @@ function useBuiltinTemplates() {
|
|||||||
return templates;
|
return templates;
|
||||||
}
|
}
|
||||||
//#endregion
|
//#endregion
|
||||||
|
|
||||||
|
//#region Edited Notes
|
||||||
|
function EditedNotes() {
|
||||||
|
const { note } = useNoteContext();
|
||||||
|
const [ dateNote ] = useNoteLabel(note, "dateNote");
|
||||||
|
|
||||||
|
|
||||||
|
return (note && dateNote &&
|
||||||
|
<div className="edited-notes">
|
||||||
|
<EditedNotesContent note={note} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function EditedNotesContent({ note }: { note: FNote }) {
|
||||||
|
const editedNotes = useEditedNotes(note);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<strong>{t("note_title.edited_notes")}</strong><br />
|
||||||
|
{editedNotes?.map(editedNote => (
|
||||||
|
<SimpleBadge
|
||||||
|
key={editedNote.noteId}
|
||||||
|
title={(
|
||||||
|
<NoteLink
|
||||||
|
notePath={editedNote.noteId}
|
||||||
|
showNoteIcon
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
//#endregion
|
||||||
|
|||||||
@ -10,7 +10,7 @@ import Icon from "./Icon";
|
|||||||
|
|
||||||
interface SimpleBadgeProps {
|
interface SimpleBadgeProps {
|
||||||
className?: string;
|
className?: string;
|
||||||
title: string;
|
title: ComponentChildren;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface BadgeProps {
|
interface BadgeProps {
|
||||||
|
|||||||
@ -1,24 +1,16 @@
|
|||||||
import { useEffect, useState } from "preact/hooks";
|
|
||||||
import { TabContext } from "./ribbon-interface";
|
|
||||||
import { EditedNotesResponse } from "@triliumnext/commons";
|
import { EditedNotesResponse } from "@triliumnext/commons";
|
||||||
import server from "../../services/server";
|
import { useEffect, useState } from "preact/hooks";
|
||||||
import { t } from "../../services/i18n";
|
|
||||||
|
import FNote from "../../entities/fnote";
|
||||||
import froca from "../../services/froca";
|
import froca from "../../services/froca";
|
||||||
|
import { t } from "../../services/i18n";
|
||||||
|
import server from "../../services/server";
|
||||||
import NoteLink from "../react/NoteLink";
|
import NoteLink from "../react/NoteLink";
|
||||||
import { joinElements } from "../react/react_utils";
|
import { joinElements } from "../react/react_utils";
|
||||||
|
import { TabContext } from "./ribbon-interface";
|
||||||
|
|
||||||
export default function EditedNotesTab({ note }: TabContext) {
|
export default function EditedNotesTab({ note }: TabContext) {
|
||||||
const [ editedNotes, setEditedNotes ] = useState<EditedNotesResponse>();
|
const editedNotes = useEditedNotes(note);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (!note) return;
|
|
||||||
server.get<EditedNotesResponse>(`edited-notes/${note.getLabelValue("dateNote")}`).then(async editedNotes => {
|
|
||||||
editedNotes = editedNotes.filter((n) => n.noteId !== note.noteId);
|
|
||||||
const noteIds = editedNotes.flatMap((n) => n.noteId);
|
|
||||||
await froca.getNotes(noteIds, true); // preload all at once
|
|
||||||
setEditedNotes(editedNotes);
|
|
||||||
});
|
|
||||||
}, [ note?.noteId ]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="edited-notes-widget" style={{
|
<div className="edited-notes-widget" style={{
|
||||||
@ -31,7 +23,7 @@ export default function EditedNotesTab({ note }: TabContext) {
|
|||||||
<div className="edited-notes-list use-tn-links">
|
<div className="edited-notes-list use-tn-links">
|
||||||
{joinElements(editedNotes.map(editedNote => {
|
{joinElements(editedNotes.map(editedNote => {
|
||||||
return (
|
return (
|
||||||
<span className="edited-note-line">
|
<span key={editedNote.noteId} className="edited-note-line">
|
||||||
{editedNote.isDeleted ? (
|
{editedNote.isDeleted ? (
|
||||||
<i>{`${editedNote.title} ${t("edited_notes.deleted")}`}</i>
|
<i>{`${editedNote.title} ${t("edited_notes.deleted")}`}</i>
|
||||||
) : (
|
) : (
|
||||||
@ -40,12 +32,28 @@ export default function EditedNotesTab({ note }: TabContext) {
|
|||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</span>
|
</span>
|
||||||
)
|
);
|
||||||
}), " ")}
|
}), " ")}
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="no-edited-notes-found">{t("edited_notes.no_edited_notes_found")}</div>
|
<div className="no-edited-notes-found">{t("edited_notes.no_edited_notes_found")}</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useEditedNotes(note: FNote | null | undefined) {
|
||||||
|
const [ editedNotes, setEditedNotes ] = useState<EditedNotesResponse>();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!note) return;
|
||||||
|
server.get<EditedNotesResponse>(`edited-notes/${note.getLabelValue("dateNote")}`).then(async editedNotes => {
|
||||||
|
editedNotes = editedNotes.filter((n) => n.noteId !== note.noteId);
|
||||||
|
const noteIds = editedNotes.flatMap((n) => n.noteId);
|
||||||
|
await froca.getNotes(noteIds, true); // preload all at once
|
||||||
|
setEditedNotes(editedNotes);
|
||||||
|
});
|
||||||
|
}, [ note ]);
|
||||||
|
|
||||||
|
return editedNotes;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -53,7 +53,7 @@ export const RIBBON_TAB_DEFINITIONS: TabConfiguration[] = [
|
|||||||
title: t("edited_notes.title"),
|
title: t("edited_notes.title"),
|
||||||
icon: "bx bx-calendar-edit",
|
icon: "bx bx-calendar-edit",
|
||||||
content: EditedNotesTab,
|
content: EditedNotesTab,
|
||||||
show: ({ note }) => note?.hasOwnedLabel("dateNote"),
|
show: ({ note }) => !isNewLayout && note?.hasOwnedLabel("dateNote"),
|
||||||
activate: () => options.is("editedNotesOpenInRibbon")
|
activate: () => options.is("editedNotesOpenInRibbon")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@ -18,6 +18,7 @@ type Labels = {
|
|||||||
language: string;
|
language: string;
|
||||||
originalFileName: string;
|
originalFileName: string;
|
||||||
pageUrl: string;
|
pageUrl: string;
|
||||||
|
dateNote: string;
|
||||||
|
|
||||||
// Search
|
// Search
|
||||||
searchString: string;
|
searchString: string;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user