mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 19:49:01 +01:00 
			
		
		
		
	chore(react/ribbon): add search script
This commit is contained in:
		
							parent
							
								
									04fbc82d7c
								
							
						
					
					
						commit
						ac3a8edf2b
					
				| @ -345,6 +345,30 @@ export function useNoteProperty<T extends keyof FNote>(note: FNote | null | unde | |||||||
|     return note[property]; |     return note[property]; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | export function useNoteRelation(note: FNote | undefined | null, relationName: string): [string | null | undefined, (newValue: string) => void] { | ||||||
|  |     const [ relationValue, setRelationValue ] = useState<string | null | undefined>(note?.getRelationValue(relationName)); | ||||||
|  | 
 | ||||||
|  |     useEffect(() => setRelationValue(note?.getRelationValue(relationName) ?? null), [ note ]); | ||||||
|  |     useTriliumEventBeta("entitiesReloaded", ({ loadResults }) => { | ||||||
|  |         for (const attr of loadResults.getAttributeRows()) { | ||||||
|  |             if (attr.type === "relation" && attr.name === relationName && attributes.isAffecting(attr, note)) { | ||||||
|  |                 setRelationValue(attr.value ?? null); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     const setter = useCallback((value: string | undefined) => { | ||||||
|  |         if (note) { | ||||||
|  |             attributes.setAttribute(note, "relation", relationName, value) | ||||||
|  |         } | ||||||
|  |     }, [note]); | ||||||
|  | 
 | ||||||
|  |     return [ | ||||||
|  |         relationValue, | ||||||
|  |         setter | ||||||
|  |     ] as const; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| export function useNoteLabel(note: FNote | undefined | null, labelName: string): [string | null | undefined, (newValue: string) => void] { | export function useNoteLabel(note: FNote | undefined | null, labelName: string): [string | null | undefined, (newValue: string) => void] { | ||||||
|     const [ labelValue, setLabelValue ] = useState<string | null | undefined>(note?.getLabelValue(labelName)); |     const [ labelValue, setLabelValue ] = useState<string | null | undefined>(note?.getLabelValue(labelName)); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -5,20 +5,19 @@ import { TabContext } from "./ribbon-interface"; | |||||||
| import Dropdown from "../react/Dropdown"; | import Dropdown from "../react/Dropdown"; | ||||||
| import ActionButton from "../react/ActionButton"; | import ActionButton from "../react/ActionButton"; | ||||||
| import FormTextArea from "../react/FormTextArea"; | import FormTextArea from "../react/FormTextArea"; | ||||||
| import { AttributeType, OptionNames, SaveSearchNoteResponse } from "@triliumnext/commons"; | import { AttributeType, SaveSearchNoteResponse } from "@triliumnext/commons"; | ||||||
| import attributes, { removeOwnedAttributesByNameOrType } from "../../services/attributes"; | import attributes, { removeOwnedAttributesByNameOrType } from "../../services/attributes"; | ||||||
| import { note } from "mermaid/dist/rendering-util/rendering-elements/shapes/note.js"; |  | ||||||
| import FNote from "../../entities/fnote"; | import FNote from "../../entities/fnote"; | ||||||
| import toast from "../../services/toast"; | import toast from "../../services/toast"; | ||||||
| import froca from "../../services/froca"; | import froca from "../../services/froca"; | ||||||
| import { useContext, useEffect, useRef, useState } from "preact/hooks"; | import { useContext, useEffect, useRef, useState } from "preact/hooks"; | ||||||
| import { ParentComponent } from "../react/react_utils"; | import { ParentComponent } from "../react/react_utils"; | ||||||
| import { useNoteLabel, useSpacedUpdate, useTooltip, useTriliumEventBeta } from "../react/hooks"; | import { useNoteLabel, useNoteRelation, useSpacedUpdate, useTooltip, useTriliumEventBeta } from "../react/hooks"; | ||||||
| import appContext from "../../components/app_context"; | import appContext from "../../components/app_context"; | ||||||
| import server from "../../services/server"; | import server from "../../services/server"; | ||||||
| import { tooltip } from "leaflet"; |  | ||||||
| import ws from "../../services/ws"; | import ws from "../../services/ws"; | ||||||
| import tree from "../../services/tree"; | import tree from "../../services/tree"; | ||||||
|  | import NoteAutocomplete from "../react/NoteAutocomplete"; | ||||||
| 
 | 
 | ||||||
| interface SearchOption { | interface SearchOption { | ||||||
|   attributeName: string; |   attributeName: string; | ||||||
| @ -50,7 +49,8 @@ const SEARCH_OPTIONS: SearchOption[] = [ | |||||||
|     attributeName: "searchScript", |     attributeName: "searchScript", | ||||||
|     attributeType: "relation", |     attributeType: "relation", | ||||||
|     icon: "bx bx-code", |     icon: "bx bx-code", | ||||||
|     label: t("search_definition.search_script") |     label: t("search_definition.search_script"), | ||||||
|  |     component: SearchScriptOption | ||||||
|   }, |   }, | ||||||
|   { |   { | ||||||
|     attributeName: "ancestor", |     attributeName: "ancestor", | ||||||
| @ -158,7 +158,10 @@ export default function SearchDefinitionTab({ note, ntxId }: TabContext) { | |||||||
|                     icon={icon} |                     icon={icon} | ||||||
|                     text={label} |                     text={label} | ||||||
|                     title={tooltip} |                     title={tooltip} | ||||||
|                     onClick={() => attributes.setAttribute(note, attributeType, attributeName, "")} |                     onClick={() => { | ||||||
|  |                       const defaultValue = (attributeType === "relation" ? "root" : ""); | ||||||
|  |                       attributes.setAttribute(note, attributeType, attributeName, defaultValue); | ||||||
|  |                     }} | ||||||
|                   /> |                   /> | ||||||
|                 ))} |                 ))} | ||||||
|               </td> |               </td> | ||||||
| @ -325,3 +328,26 @@ function SearchStringOption({ note, refreshResults, error, ...restProps }: Searc | |||||||
|     /> |     /> | ||||||
|   </SearchOption> |   </SearchOption> | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | function SearchScriptOption({ note, ...restProps }: SearchOptionProps) { | ||||||
|  |   const [ searchScript, setSearchScript ] = useNoteRelation(note, "searchScript"); | ||||||
|  | 
 | ||||||
|  |   return <SearchOption | ||||||
|  |     title={t("search_script.title")} | ||||||
|  |     help={<> | ||||||
|  |       <p>{t("search_script.description1")}</p> | ||||||
|  |       <p>{t("search_script.description2")}</p> | ||||||
|  |       <p>{t("search_script.example_title")}</p> | ||||||
|  |       <pre>{t("search_script.example_code")}</pre> | ||||||
|  |       {t("search_script.note")} | ||||||
|  |     </>} | ||||||
|  |     note={note} | ||||||
|  |     {...restProps} | ||||||
|  |   > | ||||||
|  |     <NoteAutocomplete | ||||||
|  |       noteId={searchScript !== "root" ? searchScript ?? undefined : undefined} | ||||||
|  |       noteIdChanged={noteId => setSearchScript(noteId ?? "root")} | ||||||
|  |       placeholder={t("search_script.placeholder")} | ||||||
|  |     /> | ||||||
|  |   </SearchOption> | ||||||
|  | } | ||||||
| @ -1,62 +0,0 @@ | |||||||
| import AbstractSearchOption from "./abstract_search_option.js"; |  | ||||||
| import noteAutocompleteService from "../../services/note_autocomplete.js"; |  | ||||||
| import { t } from "../../services/i18n.js"; |  | ||||||
| 
 |  | ||||||
| const TPL = /*html*/` |  | ||||||
| <tr> |  | ||||||
|     <td class="title-column"> |  | ||||||
|         ${t("search_script.title")} |  | ||||||
|     </td> |  | ||||||
|     <td> |  | ||||||
|         <div class="input-group"> |  | ||||||
|             <input class="search-script form-control" placeholder="${t("search_script.placeholder")}"> |  | ||||||
|         </div> |  | ||||||
|     </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"> |  | ||||||
|             <p>${t("search_script.description1")}</p> |  | ||||||
| 
 |  | ||||||
|             <p>${t("search_script.description2")}</p> |  | ||||||
| 
 |  | ||||||
|             <p>${t("search_script.example_title")}</p> |  | ||||||
| 
 |  | ||||||
|             <pre>${t("search_script.example_code")}</pre> |  | ||||||
| 
 |  | ||||||
|             ${t("search_script.note")} |  | ||||||
|           </div> |  | ||||||
|         </div> |  | ||||||
| 
 |  | ||||||
|         <span class="bx bx-x icon-action search-option-del"></span> |  | ||||||
|     </td> |  | ||||||
| </tr>`;
 |  | ||||||
| 
 |  | ||||||
| export default class SearchScript extends AbstractSearchOption { |  | ||||||
| 
 |  | ||||||
|     static async create(noteId: string) { |  | ||||||
|         await AbstractSearchOption.setAttribute(noteId, "relation", "searchScript", "root"); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     doRender() { |  | ||||||
|         const $option = $(TPL); |  | ||||||
|         const $searchScript = $option.find(".search-script"); |  | ||||||
|         noteAutocompleteService.initNoteAutocomplete($searchScript, { allowCreatingNotes: true }); |  | ||||||
| 
 |  | ||||||
|         $searchScript.on("autocomplete:closed", async () => { |  | ||||||
|             const searchScriptNoteId = $searchScript.getSelectedNoteId(); |  | ||||||
| 
 |  | ||||||
|             if (searchScriptNoteId) { |  | ||||||
|                 await this.setAttribute("relation", "searchScript", searchScriptNoteId); |  | ||||||
|             } |  | ||||||
|         }); |  | ||||||
| 
 |  | ||||||
|         const searchScriptNoteId = this.note.getRelationValue("searchScript"); |  | ||||||
| 
 |  | ||||||
|         if (searchScriptNoteId && searchScriptNoteId !== "root") { |  | ||||||
|             $searchScript.setNote(searchScriptNoteId); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         return $option; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Elian Doran
						Elian Doran