diff --git a/apps/client/src/services/attributes.ts b/apps/client/src/services/attributes.ts index 370fd1ce1..91ebbff5c 100644 --- a/apps/client/src/services/attributes.ts +++ b/apps/client/src/services/attributes.ts @@ -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. diff --git a/apps/client/src/widgets/react/FormTextArea.tsx b/apps/client/src/widgets/react/FormTextArea.tsx index 85945cbe1..801244c8c 100644 --- a/apps/client/src/widgets/react/FormTextArea.tsx +++ b/apps/client/src/widgets/react/FormTextArea.tsx @@ -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 ( ) } diff --git a/apps/client/src/widgets/ribbon/SearchDefinitionTab.tsx b/apps/client/src/widgets/ribbon/SearchDefinitionTab.tsx index 074ac3560..932892dc8 100644 --- a/apps/client/src/widgets/ribbon/SearchDefinitionTab.tsx +++ b/apps/client/src/widgets/ribbon/SearchDefinitionTab.tsx @@ -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) { ))} + + + ) +} + +function SearchOption({ note, title, children, help, attributeName, attributeType }: { + note: FNote; + title: string, + children: ComponentChildren, + help: ComponentChildren, + attributeName: string, + attributeType: AttributeType +}) { + return ( + + {title} + {children} + + {help && {help}} + removeOwnedAttributesByNameOrType(note, attributeType, attributeName)} + /> + + + ) +} + +function SearchStringOption() { + return + {t("search_string.search_syntax")} - {t("search_string.also_see")} {t("search_string.complete_help")} +
    +
  • {t("search_string.full_text_search")}
  • +
  • #abc - {t("search_string.label_abc")}
  • +
  • #year = 2019 - {t("search_string.label_year")}
  • +
  • #rock #pop - {t("search_string.label_rock_pop")}
  • +
  • #rock or #pop - {t("search_string.label_rock_or_pop")}
  • +
  • #year <= 2000 - {t("search_string.label_year_comparison")}
  • +
  • note.dateCreated >= MONTH-1 - {t("search_string.label_date_created")}
  • +
+ } + > + +
} \ No newline at end of file diff --git a/apps/client/src/widgets/ribbon_widgets/search_definition.ts b/apps/client/src/widgets/ribbon_widgets/search_definition.ts index 073cf31da..24e59c473 100644 --- a/apps/client/src/widgets/ribbon_widgets/search_definition.ts +++ b/apps/client/src/widgets/ribbon_widgets/search_definition.ts @@ -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; diff --git a/apps/client/src/widgets/search_options/abstract_search_option.ts b/apps/client/src/widgets/search_options/abstract_search_option.ts index 42632b24b..51d2da108 100644 --- a/apps/client/src/widgets/search_options/abstract_search_option.ts +++ b/apps/client/src/widgets/search_options/abstract_search_option.ts @@ -49,21 +49,4 @@ export default abstract class AbstractSearchOption extends Component { } abstract doRender(): JQuery; - - 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}`); - } - } - } } diff --git a/apps/client/src/widgets/search_options/search_string.ts b/apps/client/src/widgets/search_options/search_string.ts index b3a6aaa39..be71e5bc0 100644 --- a/apps/client/src/widgets/search_options/search_string.ts +++ b/apps/client/src/widgets/search_options/search_string.ts @@ -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*/` - - ${t("search_string.title_column")} - - - - - - - - -`; - export default class SearchString extends AbstractSearchOption { private $searchString!: JQuery;