mirror of
https://github.com/zadam/trilium.git
synced 2025-10-20 15:19:01 +02:00
chore(react/ribbon): port search string
This commit is contained in:
parent
0c8bfc39ef
commit
c1b30db3d1
@ -2,6 +2,7 @@ import server from "./server.js";
|
||||
import froca from "./froca.js";
|
||||
import type FNote from "../entities/fnote.js";
|
||||
import type { AttributeRow } from "./load_results.js";
|
||||
import { AttributeType } from "@triliumnext/commons";
|
||||
|
||||
async function addLabel(noteId: string, name: string, value: string = "", isInheritable = false) {
|
||||
await server.put(`notes/${noteId}/attribute`, {
|
||||
@ -25,6 +26,14 @@ async function removeAttributeById(noteId: string, attributeId: string) {
|
||||
await server.remove(`notes/${noteId}/attributes/${attributeId}`);
|
||||
}
|
||||
|
||||
export async function removeOwnedAttributesByNameOrType(note: FNote, type: AttributeType, name: string) {
|
||||
for (const attr of note.getOwnedAttributes()) {
|
||||
if (attr.type === type && attr.name === name) {
|
||||
await server.remove(`notes/${note.noteId}/attributes/${attr.attributeId}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a label identified by its name from the given note, if it exists. Note that the label must be owned, i.e.
|
||||
* it will not remove inherited attributes.
|
||||
|
@ -3,16 +3,20 @@ interface FormTextAreaProps {
|
||||
currentValue: string;
|
||||
onBlur?(newValue: string): void;
|
||||
rows: number;
|
||||
className?: string;
|
||||
placeholder?: string;
|
||||
}
|
||||
export default function FormTextArea({ id, onBlur, rows, currentValue }: FormTextAreaProps) {
|
||||
export default function FormTextArea({ id, onBlur, rows, currentValue, className, placeholder }: FormTextAreaProps) {
|
||||
return (
|
||||
<textarea
|
||||
id={id}
|
||||
rows={rows}
|
||||
className={`form-control ${className ?? ""}`}
|
||||
onBlur={(e) => {
|
||||
onBlur?.(e.currentTarget.value);
|
||||
}}
|
||||
style={{ width: "100%" }}
|
||||
placeholder={placeholder}
|
||||
>{currentValue}</textarea>
|
||||
)
|
||||
}
|
||||
|
@ -1,6 +1,14 @@
|
||||
import { ComponentChildren } from "preact";
|
||||
import { t } from "../../services/i18n";
|
||||
import Button from "../react/Button";
|
||||
import { TabContext } from "./ribbon-interface";
|
||||
import Dropdown from "../react/Dropdown";
|
||||
import ActionButton from "../react/ActionButton";
|
||||
import FormTextArea from "../react/FormTextArea";
|
||||
import { AttributeType, OptionNames } from "@triliumnext/commons";
|
||||
import { removeOwnedAttributesByNameOrType } from "../../services/attributes";
|
||||
import { note } from "mermaid/dist/rendering-util/rendering-elements/shapes/note.js";
|
||||
import FNote from "../../entities/fnote";
|
||||
|
||||
interface SearchOption {
|
||||
searchOption: string;
|
||||
@ -73,8 +81,58 @@ export default function SearchDefinitionTab({ note }: TabContext) {
|
||||
))}
|
||||
</td>
|
||||
</tr>
|
||||
<tbody className="search-options">
|
||||
<SearchStringOption />
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function SearchOption({ note, title, children, help, attributeName, attributeType }: {
|
||||
note: FNote;
|
||||
title: string,
|
||||
children: ComponentChildren,
|
||||
help: ComponentChildren,
|
||||
attributeName: string,
|
||||
attributeType: AttributeType
|
||||
}) {
|
||||
return (
|
||||
<tr>
|
||||
<td className="title-column">{title}</td>
|
||||
<td>{children}</td>
|
||||
<td className="button-column">
|
||||
{help && <Dropdown buttonClassName="bx bx-help-circle icon-action" hideToggleArrow>{help}</Dropdown>}
|
||||
<ActionButton
|
||||
icon="bx bx-x"
|
||||
className="search-option-del"
|
||||
onClick={() => removeOwnedAttributesByNameOrType(note, attributeType, attributeName)}
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
)
|
||||
}
|
||||
|
||||
function SearchStringOption() {
|
||||
return <SearchOption
|
||||
title={t("search_string.title_column")}
|
||||
help={<>
|
||||
<strong>{t("search_string.search_syntax")}</strong> - {t("search_string.also_see")} <a href="#" data-help-page="search.html">{t("search_string.complete_help")}</a>
|
||||
<ul style="marigin-bottom: 0;">
|
||||
<li>{t("search_string.full_text_search")}</li>
|
||||
<li><code>#abc</code> - {t("search_string.label_abc")}</li>
|
||||
<li><code>#year = 2019</code> - {t("search_string.label_year")}</li>
|
||||
<li><code>#rock #pop</code> - {t("search_string.label_rock_pop")}</li>
|
||||
<li><code>#rock or #pop</code> - {t("search_string.label_rock_or_pop")}</li>
|
||||
<li><code>#year <= 2000</code> - {t("search_string.label_year_comparison")}</li>
|
||||
<li><code>note.dateCreated >= MONTH-1</code> - {t("search_string.label_date_created")}</li>
|
||||
</ul>
|
||||
</>}
|
||||
>
|
||||
<FormTextArea
|
||||
className="search-string"
|
||||
placeholder={t("search_string.placeholder")}
|
||||
/>
|
||||
</SearchOption>
|
||||
}
|
@ -163,10 +163,6 @@ export default class SearchDefinitionWidget extends NoteContextAwareWidget {
|
||||
this.triggerEvent("searchRefreshed", { ntxId: this.noteContext?.ntxId });
|
||||
}
|
||||
|
||||
async refreshSearchDefinitionCommand() {
|
||||
await this.refresh();
|
||||
}
|
||||
|
||||
async refreshWithNote(note: FNote) {
|
||||
if (!this.note) {
|
||||
return;
|
||||
|
@ -49,21 +49,4 @@ export default abstract class AbstractSearchOption extends Component {
|
||||
}
|
||||
|
||||
abstract doRender(): JQuery<HTMLElement>;
|
||||
|
||||
async deleteOption() {
|
||||
// TODO: Find a better pattern.
|
||||
await this.deleteAttribute((this.constructor as any).attributeType, (this.constructor as any).optionName);
|
||||
|
||||
await ws.waitForMaxKnownEntityChangeId();
|
||||
|
||||
await this.triggerCommand("refreshSearchDefinition");
|
||||
}
|
||||
|
||||
async deleteAttribute(type: AttributeType, name: string) {
|
||||
for (const attr of this.note.getOwnedAttributes()) {
|
||||
if (attr.type === type && attr.name === name) {
|
||||
await server.remove(`notes/${this.note.noteId}/attributes/${attr.attributeId}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,34 +6,6 @@ import appContext, { type EventData } from "../../components/app_context.js";
|
||||
import { t } from "../../services/i18n.js";
|
||||
import { Tooltip } from "bootstrap";
|
||||
|
||||
const TPL = /*html*/`
|
||||
<tr>
|
||||
<td class="title-column">${t("search_string.title_column")}</td>
|
||||
<td>
|
||||
<textarea class="form-control search-string" placeholder="${t("search_string.placeholder")}" autofocus></textarea>
|
||||
</td>
|
||||
<td class="button-column">
|
||||
<div class="dropdown help-dropdown">
|
||||
<span class="bx bx-help-circle icon-action" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false"></span>
|
||||
<div class="dropdown-menu dropdown-menu-right p-4">
|
||||
<strong>${t("search_string.search_syntax")}</strong> - ${t("search_string.also_see")} <a href="#" data-help-page="search.html">${t("search_string.complete_help")}</a>
|
||||
|
||||
<ul style="marigin-bottom: 0;">
|
||||
<li>${t("search_string.full_text_search")}</li>
|
||||
<li><code>#abc</code> - ${t("search_string.label_abc")}</li>
|
||||
<li><code>#year = 2019</code> - ${t("search_string.label_year")}</li>
|
||||
<li><code>#rock #pop</code> - ${t("search_string.label_rock_pop")}</li>
|
||||
<li><code>#rock or #pop</code> - ${t("search_string.label_rock_or_pop")}</li>
|
||||
<li><code>#year <= 2000</code> - ${t("search_string.label_year_comparison")}</li>
|
||||
<li><code>note.dateCreated >= MONTH-1</code> - ${t("search_string.label_date_created")}</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<span class="bx bx-x icon-action search-option-del"></span>
|
||||
</td>
|
||||
</tr>`;
|
||||
|
||||
export default class SearchString extends AbstractSearchOption {
|
||||
|
||||
private $searchString!: JQuery<HTMLElement>;
|
||||
|
Loading…
x
Reference in New Issue
Block a user