mirror of
https://github.com/zadam/trilium.git
synced 2025-11-10 15:25:51 +01:00
chore(react/type_widget): port empty search
This commit is contained in:
@@ -4,6 +4,8 @@ import FNote from "../entities/fnote";
|
||||
import protected_session_holder from "../services/protected_session_holder";
|
||||
import { useEffect, useState } from "preact/hooks";
|
||||
import NoteContext from "../components/note_context";
|
||||
import Empty from "./type_widgets/Empty";
|
||||
import { VNode } from "preact";
|
||||
|
||||
/**
|
||||
* A `NoteType` altered by the note detail widget, taking into consideration whether the note is editable or not and adding special note types such as an empty one,
|
||||
@@ -16,8 +18,15 @@ type ExtendedNoteType = Exclude<NoteType, "launcher" | "text" | "code"> | "empty
|
||||
*/
|
||||
export default function NoteDetail() {
|
||||
const { note, type } = useNoteInfo();
|
||||
const [ correspondingWidget, setCorrespondingWidget ] = useState<VNode>();
|
||||
|
||||
return <p>Note detail goes here! {note?.title} of {type}</p>
|
||||
useEffect(() => setCorrespondingWidget(getCorrespondingWidget(type)), [ type ]);
|
||||
|
||||
return (
|
||||
<div>
|
||||
{correspondingWidget || <p>Note detail goes here! {note?.title} of {type}</p>}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
/** Manages both note changes and changes to the widget type, which are asynchronous. */
|
||||
@@ -36,6 +45,15 @@ function useNoteInfo() {
|
||||
return { note, type };
|
||||
}
|
||||
|
||||
function getCorrespondingWidget(noteType: ExtendedNoteType | undefined) {
|
||||
switch (noteType) {
|
||||
case "empty":
|
||||
return <Empty />
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
async function getWidgetType(note: FNote | null | undefined, noteContext: NoteContext | undefined): Promise<ExtendedNoteType> {
|
||||
if (!note) {
|
||||
return "empty";
|
||||
|
||||
38
apps/client/src/widgets/type_widgets/Empty.css
Normal file
38
apps/client/src/widgets/type_widgets/Empty.css
Normal file
@@ -0,0 +1,38 @@
|
||||
.workspace-notes {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-evenly;
|
||||
}
|
||||
|
||||
.workspace-notes .workspace-note {
|
||||
width: 130px;
|
||||
text-align: center;
|
||||
margin: 10px;
|
||||
border: 1px transparent solid;
|
||||
}
|
||||
|
||||
.workspace-notes .workspace-note:hover {
|
||||
cursor: pointer;
|
||||
border: 1px solid var(--main-border-color);
|
||||
}
|
||||
|
||||
.note-detail-empty-results .aa-dropdown-menu {
|
||||
max-height: 50vh;
|
||||
overflow: scroll;
|
||||
border: var(--bs-border-width) solid var(--bs-border-color);
|
||||
border-top: 0;
|
||||
}
|
||||
|
||||
.empty-tab-search .note-autocomplete-input {
|
||||
border-bottom-left-radius: 0;
|
||||
}
|
||||
|
||||
.empty-tab-search .input-clearer-button {
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
|
||||
.workspace-icon {
|
||||
text-align: center;
|
||||
font-size: 500%;
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
import { useEffect, useRef } from "preact/hooks";
|
||||
import { t } from "../../services/i18n";
|
||||
import FormGroup from "../react/FormGroup";
|
||||
import NoteAutocomplete from "../react/NoteAutocomplete";
|
||||
import "./Empty.css";
|
||||
import { refToJQuerySelector } from "../react/react_utils";
|
||||
import note_autocomplete from "../../services/note_autocomplete";
|
||||
import appContext from "../../components/app_context";
|
||||
|
||||
export default function Empty() {
|
||||
return (
|
||||
<div class="note-detail-empty note-detail-printable">
|
||||
<div class="workspace-notes"></div>
|
||||
|
||||
<NoteSearch />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function NoteSearch() {
|
||||
const resultsContainerRef = useRef<HTMLDivElement>(null);
|
||||
const autocompleteRef = useRef<HTMLInputElement>(null);
|
||||
|
||||
// Show recent notes.
|
||||
useEffect(() => {
|
||||
const $autoComplete = refToJQuerySelector(autocompleteRef);
|
||||
note_autocomplete.showRecentNotes($autoComplete);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<>
|
||||
<FormGroup name="empty-tab-search" label={t("empty.open_note_instruction")} className="empty-tab-search">
|
||||
<NoteAutocomplete
|
||||
placeholder={t("empty.search_placeholder")}
|
||||
container={resultsContainerRef}
|
||||
inputRef={autocompleteRef}
|
||||
opts={{
|
||||
hideGoToSelectedNoteButton: true,
|
||||
allowCreatingNotes: true,
|
||||
allowJumpToSearchNotes: true,
|
||||
}}
|
||||
onChange={suggestion => {
|
||||
if (!suggestion?.notePath) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const activeContext = appContext.tabManager.getActiveContext();
|
||||
if (activeContext) {
|
||||
activeContext.setNote(suggestion.notePath);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</FormGroup>
|
||||
<div ref={resultsContainerRef} className="note-detail-empty-results" />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -5,57 +5,7 @@ import searchService from "../../services/search.js";
|
||||
import { t } from "../../services/i18n.js";
|
||||
|
||||
const TPL = /*html*/`
|
||||
<div class="note-detail-empty note-detail-printable">
|
||||
<style>
|
||||
.workspace-notes {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-evenly;
|
||||
}
|
||||
|
||||
.workspace-notes .workspace-note {
|
||||
width: 130px;
|
||||
text-align: center;
|
||||
margin: 10px;
|
||||
border: 1px transparent solid;
|
||||
}
|
||||
|
||||
.workspace-notes .workspace-note:hover {
|
||||
cursor: pointer;
|
||||
border: 1px solid var(--main-border-color);
|
||||
}
|
||||
|
||||
.note-detail-empty-results .aa-dropdown-menu {
|
||||
max-height: 50vh;
|
||||
overflow: scroll;
|
||||
border: var(--bs-border-width) solid var(--bs-border-color);
|
||||
border-top: 0;
|
||||
}
|
||||
|
||||
.empty-tab-search .note-autocomplete-input {
|
||||
border-bottom-left-radius: 0;
|
||||
}
|
||||
|
||||
.empty-tab-search .input-clearer-button {
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
|
||||
.workspace-icon {
|
||||
text-align: center;
|
||||
font-size: 500%;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="workspace-notes"></div>
|
||||
<div class="form-group empty-tab-search">
|
||||
<label>${t("empty.open_note_instruction")}</label>
|
||||
<div class="input-group mt-1">
|
||||
<input class="form-control note-autocomplete" placeholder="${t("empty.search_placeholder")}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="note-detail-empty-results"></div>
|
||||
</div>`;
|
||||
`;
|
||||
|
||||
export default class EmptyTypeWidget extends TypeWidget {
|
||||
|
||||
@@ -73,28 +23,8 @@ export default class EmptyTypeWidget extends TypeWidget {
|
||||
this.$widget = $(TPL);
|
||||
this.$autoComplete = this.$widget.find(".note-autocomplete");
|
||||
this.$results = this.$widget.find(".note-detail-empty-results");
|
||||
|
||||
noteAutocompleteService
|
||||
.initNoteAutocomplete(this.$autoComplete, {
|
||||
hideGoToSelectedNoteButton: true,
|
||||
allowCreatingNotes: true,
|
||||
allowJumpToSearchNotes: true,
|
||||
container: this.$results[0]
|
||||
})
|
||||
.on("autocomplete:noteselected", function (event, suggestion, dataset) {
|
||||
if (!suggestion.notePath) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const activeContext = appContext.tabManager.getActiveContext();
|
||||
if (activeContext) {
|
||||
activeContext.setNote(suggestion.notePath);
|
||||
}
|
||||
});
|
||||
|
||||
this.$workspaceNotes = this.$widget.find(".workspace-notes");
|
||||
|
||||
noteAutocompleteService.showRecentNotes(this.$autoComplete);
|
||||
super.doRender();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user