mirror of
https://github.com/zadam/trilium.git
synced 2025-12-16 21:29:56 +01:00
feat(layout/inline-title): dropdown for collections
This commit is contained in:
@@ -1756,7 +1756,8 @@
|
|||||||
"last_modified": "Last modified on <Value />",
|
"last_modified": "Last modified on <Value />",
|
||||||
"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"
|
||||||
},
|
},
|
||||||
"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.",
|
||||||
|
|||||||
@@ -144,7 +144,7 @@ function NoteTypeSwitcher() {
|
|||||||
const pinnedNoteTypes: NoteTypeMapping[] = [];
|
const pinnedNoteTypes: NoteTypeMapping[] = [];
|
||||||
const restNoteTypes: NoteTypeMapping[] = [];
|
const restNoteTypes: NoteTypeMapping[] = [];
|
||||||
for (const noteType of NOTE_TYPES) {
|
for (const noteType of NOTE_TYPES) {
|
||||||
if (noteType.reserved || noteType.static) continue;
|
if (noteType.reserved || noteType.static || noteType.type === "book") continue;
|
||||||
if (SWITCHER_PINNED_NOTE_TYPES.has(noteType.type)) {
|
if (SWITCHER_PINNED_NOTE_TYPES.has(noteType.type)) {
|
||||||
pinnedNoteTypes.push(noteType);
|
pinnedNoteTypes.push(noteType);
|
||||||
} else {
|
} else {
|
||||||
@@ -154,6 +154,7 @@ function NoteTypeSwitcher() {
|
|||||||
return { pinnedNoteTypes, restNoteTypes };
|
return { pinnedNoteTypes, restNoteTypes };
|
||||||
}, []);
|
}, []);
|
||||||
const currentNoteTypeData = useMemo(() => NOTE_TYPES.find(t => t.type === currentNoteType), [ currentNoteType ]);
|
const currentNoteTypeData = useMemo(() => NOTE_TYPES.find(t => t.type === currentNoteType), [ currentNoteType ]);
|
||||||
|
const { builtinTemplates, collectionTemplates } = useBuiltinTemplates();
|
||||||
|
|
||||||
return (note?.type === "text" &&
|
return (note?.type === "text" &&
|
||||||
<div
|
<div
|
||||||
@@ -171,8 +172,9 @@ function NoteTypeSwitcher() {
|
|||||||
onClick={() => switchNoteType(note.noteId, noteType)}
|
onClick={() => switchNoteType(note.noteId, noteType)}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
|
<CollectionNoteTypes noteId={note.noteId} collectionTemplates={collectionTemplates} />
|
||||||
|
<TemplateNoteTypes noteId={note.noteId} builtinTemplates={builtinTemplates} />
|
||||||
<MoreNoteTypes noteId={note.noteId} restNoteTypes={restNoteTypes} />
|
<MoreNoteTypes noteId={note.noteId} restNoteTypes={restNoteTypes} />
|
||||||
<TemplateNoteTypes noteId={note.noteId} />
|
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@@ -196,9 +198,25 @@ function MoreNoteTypes({ noteId, restNoteTypes }: { noteId: string, restNoteType
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function TemplateNoteTypes({ noteId }: { noteId: string }) {
|
function CollectionNoteTypes({ noteId, collectionTemplates }: { noteId: string, collectionTemplates: FNote[] }) {
|
||||||
|
return (
|
||||||
|
<BadgeWithDropdown
|
||||||
|
text={t("note_title.note_type_switcher_collection")}
|
||||||
|
icon="bx bx-book"
|
||||||
|
>
|
||||||
|
{collectionTemplates.map(collectionTemplate => (
|
||||||
|
<FormListItem
|
||||||
|
key={collectionTemplate.noteId}
|
||||||
|
icon={collectionTemplate.getIcon()}
|
||||||
|
onClick={() => setTemplate(noteId, collectionTemplate.noteId)}
|
||||||
|
>{collectionTemplate.title}</FormListItem>
|
||||||
|
))}
|
||||||
|
</BadgeWithDropdown>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function TemplateNoteTypes({ noteId, builtinTemplates }: { noteId: string, builtinTemplates: FNote[] }) {
|
||||||
const [ userTemplates, setUserTemplates ] = useState<FNote[]>([]);
|
const [ userTemplates, setUserTemplates ] = useState<FNote[]>([]);
|
||||||
const [ builtinTemplates, setBuiltinTemplates ] = useState<FNote[]>([]);
|
|
||||||
|
|
||||||
async function refreshTemplates() {
|
async function refreshTemplates() {
|
||||||
const templateNoteIds = await server.get<string[]>("search-templates");
|
const templateNoteIds = await server.get<string[]>("search-templates");
|
||||||
@@ -206,22 +224,9 @@ function TemplateNoteTypes({ noteId }: { noteId: string }) {
|
|||||||
setUserTemplates(templateNotes);
|
setUserTemplates(templateNotes);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function loadBuiltinTemplates() {
|
|
||||||
const templatesRoot = await froca.getNote("_templates");
|
|
||||||
if (!templatesRoot) return;
|
|
||||||
const childNotes = await templatesRoot.getChildNotes();
|
|
||||||
const builtinTemplates: FNote[] = [];
|
|
||||||
for (const childNote of childNotes) {
|
|
||||||
if (childNote.hasLabel("collection") || !childNote.hasLabel("template")) continue;
|
|
||||||
builtinTemplates.push(childNote);
|
|
||||||
}
|
|
||||||
setBuiltinTemplates(builtinTemplates);
|
|
||||||
}
|
|
||||||
|
|
||||||
// First load.
|
// First load.
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
refreshTemplates();
|
refreshTemplates();
|
||||||
loadBuiltinTemplates();
|
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
// React to external changes.
|
// React to external changes.
|
||||||
@@ -247,7 +252,7 @@ function TemplateItem({ noteId, template }: { noteId: string, template: FNote })
|
|||||||
return (
|
return (
|
||||||
<FormListItem
|
<FormListItem
|
||||||
icon={template.getIcon()}
|
icon={template.getIcon()}
|
||||||
onClick={() => attributes.setRelation(noteId, "template", template.noteId)}
|
onClick={() => setTemplate(noteId, template.noteId)}
|
||||||
>{template.title}</FormListItem>
|
>{template.title}</FormListItem>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -255,4 +260,41 @@ function TemplateItem({ noteId, template }: { noteId: string, template: FNote })
|
|||||||
function switchNoteType(noteId: string, { type, mime }: NoteTypeMapping) {
|
function switchNoteType(noteId: string, { type, mime }: NoteTypeMapping) {
|
||||||
return server.put(`notes/${noteId}/type`, { type, mime });
|
return server.put(`notes/${noteId}/type`, { type, mime });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setTemplate(noteId: string, templateId: string) {
|
||||||
|
return attributes.setRelation(noteId, "template", templateId);
|
||||||
|
}
|
||||||
|
|
||||||
|
function useBuiltinTemplates() {
|
||||||
|
const [ templates, setTemplates ] = useState<{
|
||||||
|
builtinTemplates: FNote[];
|
||||||
|
collectionTemplates: FNote[];
|
||||||
|
}>({
|
||||||
|
builtinTemplates: [],
|
||||||
|
collectionTemplates: []
|
||||||
|
});
|
||||||
|
|
||||||
|
async function loadBuiltinTemplates() {
|
||||||
|
const templatesRoot = await froca.getNote("_templates");
|
||||||
|
if (!templatesRoot) return;
|
||||||
|
const childNotes = await templatesRoot.getChildNotes();
|
||||||
|
const builtinTemplates: FNote[] = [];
|
||||||
|
const collectionTemplates: FNote[] = [];
|
||||||
|
for (const childNote of childNotes) {
|
||||||
|
if (!childNote.hasLabel("template")) continue;
|
||||||
|
if (childNote.hasLabel("collection")) {
|
||||||
|
collectionTemplates.push(childNote);
|
||||||
|
} else {
|
||||||
|
builtinTemplates.push(childNote);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setTemplates({ builtinTemplates, collectionTemplates });
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
loadBuiltinTemplates();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return templates;
|
||||||
|
}
|
||||||
//#endregion
|
//#endregion
|
||||||
|
|||||||
Reference in New Issue
Block a user