Compare commits
	
		
			No commits in common. "5d146aaf3fe095a0fe522f5dbd48fa9885250f04" and "a7568c1bb2c6c454923af43e44b9e4ab92b060dc" have entirely different histories.
		
	
	
		
			5d146aaf3f
			...
			a7568c1bb2
		
	
		
| @ -14,7 +14,6 @@ | ||||
|     "@heroicons/react": "^2.0.18", | ||||
|     "@tailwindcss/forms": "^0.5.6", | ||||
|     "@tanstack/react-query": "^4.35.3", | ||||
|     "classnames": "^2.3.2", | ||||
|     "ramda": "^0.29.0", | ||||
|     "react": "^18.2.0", | ||||
|     "react-dom": "^18.2.0", | ||||
|  | ||||
							
								
								
									
										322
									
								
								src/App.tsx
									
									
									
									
									
								
							
							
						
						
									
										322
									
								
								src/App.tsx
									
									
									
									
									
								
							| @ -1,154 +1,212 @@ | ||||
| import {useEffect, useState} from "react"; | ||||
| import classNames from "classnames"; | ||||
| import { | ||||
|     ChangeEventHandler, Dispatch, | ||||
|     KeyboardEventHandler, | ||||
|     MouseEventHandler, | ||||
|     ReactNode, SetStateAction, | ||||
|     useCallback, | ||||
|     useEffect, | ||||
|     useRef, | ||||
|     useState | ||||
| } from "react"; | ||||
| import {FixedSizeList as List} from "react-window"; | ||||
| import Select, {createFilter, MenuListProps} from "react-select"; | ||||
| import * as R from 'ramda'; | ||||
| 
 | ||||
| import {useQuery} from "@tanstack/react-query"; | ||||
| import {LinkCollection, type Option} from "./aliases"; | ||||
| 
 | ||||
| import {CheckIcon, ChevronUpDownIcon} from '@heroicons/react/20/solid' | ||||
| import {Combobox} from '@headlessui/react' | ||||
| // TODO: Fix this for wrapping items, esp on phones
 | ||||
| const height = 35; | ||||
| 
 | ||||
| type ResultNoteApi = { | ||||
|     score: number | ||||
|     vault: string | ||||
|     path: string | ||||
|     basename: string | ||||
|     foundWords: string[] | ||||
|     matches: SearchMatchApi[] | ||||
|     excerpt: string | ||||
| } | ||||
| 
 | ||||
| type SearchMatchApi = { | ||||
|     match: string | ||||
|     offset: number | ||||
| } | ||||
| 
 | ||||
| export function OmnisearchSelect({setSelected}: { | ||||
|     setSelected: (value: Option) => void | ||||
| }) { | ||||
| function MenuList(props: MenuListProps) { | ||||
|     const { | ||||
|         data: metadata, | ||||
|         options, | ||||
|         children, | ||||
|         maxHeight, | ||||
|         getValue | ||||
|     } = props as Omit<MenuListProps, 'children'> & { | ||||
|         children: ReactNode[] | ||||
|     }; | ||||
| 
 | ||||
|     const [value] = getValue(); | ||||
|     const initialOffset = options.indexOf(value) * height; | ||||
| 
 | ||||
|     return (<List | ||||
|         width={'100%'} | ||||
|         height={maxHeight} | ||||
|         itemCount={children?.length ?? 0} | ||||
|         itemSize={height} | ||||
|         initialScrollOffset={initialOffset} | ||||
|     > | ||||
|         {({ | ||||
|               index, | ||||
|               style | ||||
|           }) => <div style={style}>{children[index]}</div>} | ||||
|     </List>); | ||||
| } | ||||
| 
 | ||||
| interface Option { | ||||
|     label: string, | ||||
|     value: string, | ||||
|     data: { | ||||
|         backlinks: unknown[] | ||||
|         aliases?: string[] | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| export function LargeSelect() { | ||||
|     const { | ||||
|         data: options, | ||||
|         isLoading, | ||||
|     } = useQuery({ | ||||
|         queryKey: ['obsidian-metadata'], | ||||
|         initialData: [], | ||||
|         refetchInterval: false, | ||||
|         queryFn: async () => { | ||||
|             const response = await fetch("http://localhost:9002/metadata") | ||||
|             const response = await fetch("/metadata") | ||||
|             const fullData: any[] = await response.json(); | ||||
|             return fullData; | ||||
| 
 | ||||
|             return R.sortBy(v => -(v.data.backlinks?.length ?? 0), fullData.map(md => ({ | ||||
|                 value: md.relativePath, | ||||
|                 label: md.fileName, | ||||
|                 data: md, | ||||
|             }) as Option)); | ||||
|         }, | ||||
|     }); | ||||
| 
 | ||||
|     const [query, setQuery] = useState('') | ||||
|     const [selectedPerson, setSelectedPerson] = useState<ResultNoteApi | null>(null); | ||||
| 
 | ||||
|     const {data: filteredPeople} = useQuery({ | ||||
|         queryKey: ['obsidian-omnisearch', query], | ||||
|         initialData: [], | ||||
|         queryFn: async () => { | ||||
|             if (query === '') { | ||||
|                 return []; | ||||
|             } else { | ||||
|                 const response = await fetch(`http://localhost:9002/search?q=${query}`) | ||||
|                 const fullData: ResultNoteApi[] = await response.json(); | ||||
| 
 | ||||
|                 return fullData; | ||||
|             } | ||||
|         } | ||||
|     }); | ||||
| 
 | ||||
|     useEffect(() => { | ||||
|         if (selectedPerson != undefined && metadata.length > 0) { | ||||
|             console.log(selectedPerson); | ||||
|             const data = metadata.find(md => md.relativePath === selectedPerson.path); | ||||
|             if (!data) { | ||||
|                 debugger | ||||
|             } | ||||
| 
 | ||||
|             setSelected({ | ||||
|                 value: selectedPerson.path, | ||||
|                 label: selectedPerson.basename, | ||||
|                 data, | ||||
|             }); | ||||
|         } | ||||
|     }, [selectedPerson, metadata]); | ||||
| 
 | ||||
|     return (<Combobox as="div" value={selectedPerson} onChange={setSelectedPerson}> | ||||
|         <Combobox.Label className="block text-sm font-medium leading-6 text-gray-900">Search for note</Combobox.Label> | ||||
|         <div className="relative mt-2"> | ||||
|             <Combobox.Input | ||||
|                 aria-disabled={isLoading} | ||||
|                 className="w-full rounded-md border-0 bg-white py-1.5 pl-3 pr-12 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6" | ||||
|                 onChange={(event) => setQuery(event.target.value)} | ||||
|                 displayValue={(person: ResultNoteApi) => person?.basename} | ||||
|             /> | ||||
| 
 | ||||
|             <Combobox.Button | ||||
|                 className="absolute inset-y-0 right-0 flex items-center rounded-r-md px-2 focus:outline-none"> | ||||
|                 <ChevronUpDownIcon className="h-5 w-5 text-gray-400" aria-hidden="true"/> | ||||
|             </Combobox.Button> | ||||
| 
 | ||||
|             {filteredPeople.length > 0 && ( | ||||
|                 <Combobox.Options | ||||
|                     className="absolute z-10 mt-1 max-h-60 w-full overflow-auto rounded-md bg-white py-1 text-base shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none sm:text-sm"> | ||||
|                     {filteredPeople.map((person) => ( | ||||
|                         <Combobox.Option | ||||
|                             key={person.path} | ||||
|                             value={person} | ||||
|                             className={({active}) => | ||||
|                                 classNames( | ||||
|                                     'relative cursor-default select-none py-2 pl-3 pr-9', | ||||
|                                     active ? 'bg-indigo-600 text-white' : 'text-gray-900' | ||||
|                                 ) | ||||
|                             } | ||||
|                         > | ||||
|                             {({ | ||||
|                                   active, | ||||
|                                   selected | ||||
|                               }) => ( | ||||
|                                 <> | ||||
|                                     <div className="flex"> | ||||
|                                         <span | ||||
|                                             className={classNames('truncate', selected && 'font-semibold')}>{person?.basename}</span> | ||||
|                                         <span | ||||
|                                             className={classNames( | ||||
|                                                 'ml-2 truncate text-gray-500', | ||||
|                                                 active ? 'text-indigo-200' : 'text-gray-500' | ||||
|                                             )} | ||||
|                                         > | ||||
|                         {person?.path} | ||||
|                       </span> | ||||
|                                     </div> | ||||
| 
 | ||||
|                                     {selected && ( | ||||
|                                         <span | ||||
|                                             className={classNames( | ||||
|                                                 'absolute inset-y-0 right-0 flex items-center pr-4', | ||||
|                                                 active ? 'text-white' : 'text-indigo-600' | ||||
|                                             )} | ||||
|                                         > | ||||
|                         <CheckIcon className="h-5 w-5" aria-hidden="true"/> | ||||
|                       </span> | ||||
|                                     )} | ||||
|                                 </> | ||||
|                             )} | ||||
|                         </Combobox.Option> | ||||
|                     ))} | ||||
|                 </Combobox.Options> | ||||
|             )} | ||||
|         </div> | ||||
|     </Combobox>); | ||||
| } | ||||
| 
 | ||||
| export function App() { | ||||
|     const [selected, setSelected] = useState<Option | null>(null); | ||||
| 
 | ||||
|     const onChange = useCallback((value: Option) => { | ||||
|         setSelected(value); | ||||
|         navigator.clipboard.writeText(`[[${value.label}]]`) | ||||
|     }, []); | ||||
| 
 | ||||
|     return ( | ||||
|         <div className={"m-5 text-lg"}> | ||||
|             {/*<NaiveSelect setSelected={setSelected}/>*/} | ||||
|             <OmnisearchSelect setSelected={setSelected}/> | ||||
|             <Select | ||||
|                 classNames={{input: () => 'select-input-wrapper'}} | ||||
|                 onChange={onChange as any} | ||||
|                 components={{MenuList}} | ||||
|                 isDisabled={isLoading} | ||||
|                 isLoading={isLoading} | ||||
|                 isClearable={true} | ||||
|                 options={options} | ||||
|                 filterOption={createFilter({ignoreAccents: false})} | ||||
|             /> | ||||
| 
 | ||||
|             {selected && <LinkCollection selected={selected}/>} | ||||
|             {selected && <div className={"mt-2"}> | ||||
|                 <div className="py-1"> | ||||
|                     <Alias original={selected.label}/> | ||||
|                 </div> | ||||
| 
 | ||||
|                 {selected.data.aliases?.map(alias => ( | ||||
|                     <div className="py-1"> | ||||
|                         <Alias original={selected.label} alias={alias}/> | ||||
|                     </div> | ||||
|                 ))} | ||||
| 
 | ||||
|                 <div className="py-1"> | ||||
|                     <CustomAlias selected={selected}/> | ||||
|                 </div> | ||||
|             </div>} | ||||
|         </div> | ||||
|     ) | ||||
| } | ||||
| 
 | ||||
| function CustomAlias({selected}: { | ||||
|     selected: Option | ||||
| }) { | ||||
|     const [alias, setAlias] = useState(''); | ||||
| 
 | ||||
|     // Reset when selection changes
 | ||||
|     useEffect(() => { | ||||
|         setAlias(''); | ||||
|     }, [selected.value]); | ||||
| 
 | ||||
|     const onClick: MouseEventHandler = useCallback((e) => { | ||||
|         if ((e.target as HTMLElement).tagName == 'SPAN' && alias.length > 0) { | ||||
|             navigator.clipboard.writeText(`[[${selected!.label}|${alias}]]`); | ||||
|         } | ||||
|     }, [selected.value, selected.label, alias]); | ||||
| 
 | ||||
|     return ( | ||||
|         <span onClick={onClick} className={"rounded-md p-1 hover:bg-slate-100"}> | ||||
|             <span className={"text-slate-300 p-0.5"}>[[</span> | ||||
|             <span>{selected.label}</span> | ||||
|             <span className={"text-slate-300 p-0.5"}>|</span> | ||||
|             <span> | ||||
|                 <CustomAliasField content={alias} setContent={setAlias} selected={selected}/> | ||||
|             </span> | ||||
|             <span className={"text-slate-300 p-0.5"}>]]</span> | ||||
|         </span> | ||||
|     ) | ||||
| } | ||||
| 
 | ||||
| function CustomAliasField({ | ||||
|                               selected, | ||||
|                               content, | ||||
|                               setContent | ||||
|                           }: { | ||||
|     selected: Option, | ||||
|     content: string, | ||||
|     setContent: Dispatch<SetStateAction<string>>, | ||||
| }) { | ||||
|     const [width, setWidth] = useState<any>(0); | ||||
|     const span = useRef<HTMLSpanElement>(null); | ||||
| 
 | ||||
|     // Resize on change of content
 | ||||
|     useEffect(() => { | ||||
|         setWidth(span.current!.offsetWidth); | ||||
|         // setWidth(content.length + 'ch');
 | ||||
|     }, [content]); | ||||
| 
 | ||||
|     const changeHandler: ChangeEventHandler<HTMLInputElement> = useCallback(evt => { | ||||
|         setContent(evt.target.value); | ||||
|     }, []); | ||||
| 
 | ||||
|     const onCustomElementKeyDown: KeyboardEventHandler<HTMLInputElement> = useCallback((e) => { | ||||
|         if (e.key == 'Enter') { | ||||
|             navigator.clipboard.writeText(`[[${selected!.label}|${content}]]`); | ||||
|             (e.target as HTMLInputElement).blur() | ||||
|         } | ||||
|     }, [selected.value, selected.label, content]); | ||||
| 
 | ||||
|     return ( | ||||
|         <span> | ||||
|             <span style={{ | ||||
|                 position: 'absolute', | ||||
|                 opacity: 0, | ||||
|                 zIndex: -100, | ||||
|                 whiteSpace: 'pre', | ||||
|             }} ref={span}>{content}</span> | ||||
|             <input | ||||
|                 className={"border-none p-0 px-1"} | ||||
|                 type="text" style={{width: `calc(${width}px + 0.25rem)`}} autoFocus onChange={changeHandler} | ||||
|                 onKeyDown={onCustomElementKeyDown}/> | ||||
|         </span> | ||||
|     ); | ||||
| } | ||||
| 
 | ||||
| function Alias({ | ||||
|                    original, | ||||
|                    alias | ||||
|                }: { | ||||
|     original: string, | ||||
|     alias?: string | ||||
| }) { | ||||
|     const onClick = useCallback(() => { | ||||
|         if (alias) { | ||||
|             navigator.clipboard.writeText(`[[${original}|${alias}]]`) | ||||
|         } else { | ||||
|             navigator.clipboard.writeText(`[[${original}]]`) | ||||
|         } | ||||
|     }, [original, alias]); | ||||
| 
 | ||||
|     return ( | ||||
|         <span className={"rounded-md p-1 hover:bg-slate-100"} onClick={onClick}> | ||||
|             <span className={"text-slate-300 p-0.5"}>[[</span> | ||||
|             <span>{original}</span> | ||||
|             {alias && <><span className={"text-slate-300 p-0.5"}>|</span> | ||||
|                 <span>{alias}</span></>} | ||||
|             <span className={"text-slate-300 p-0.5"}>]]</span> | ||||
|         </span> | ||||
|     ); | ||||
| } | ||||
|  | ||||
| @ -1,74 +0,0 @@ | ||||
| // TODO: Fix this for wrapping items, esp on phones
 | ||||
| import Select, {createFilter, MenuListProps} from "react-select"; | ||||
| import {ReactNode, useCallback} from "react"; | ||||
| import {FixedSizeList as List} from "react-window"; | ||||
| import type {Option} from "./aliases.tsx"; | ||||
| import {useQuery} from "@tanstack/react-query"; | ||||
| import * as R from "ramda"; | ||||
| 
 | ||||
| const height = 35; | ||||
| 
 | ||||
| function MenuList(props: MenuListProps) { | ||||
|     const { | ||||
|         options, | ||||
|         children, | ||||
|         maxHeight, | ||||
|         getValue | ||||
|     } = props as Omit<MenuListProps, 'children'> & { | ||||
|         children: ReactNode[] | ||||
|     }; | ||||
| 
 | ||||
|     const [value] = getValue(); | ||||
|     const initialOffset = options.indexOf(value) * height; | ||||
| 
 | ||||
|     return (<List | ||||
|         width={'100%'} | ||||
|         height={maxHeight} | ||||
|         itemCount={children?.length ?? 0} | ||||
|         itemSize={height} | ||||
|         initialScrollOffset={initialOffset} | ||||
|     > | ||||
|         {({ | ||||
|               index, | ||||
|               style | ||||
|           }) => <div style={style}>{children[index]}</div>} | ||||
|     </List>); | ||||
| } | ||||
| 
 | ||||
| export function NaiveSelect({setSelected}: { | ||||
|     setSelected: (value: Option) => void | ||||
| }) { | ||||
|     const { | ||||
|         data: options, | ||||
|         isLoading, | ||||
|     } = useQuery({ | ||||
|         queryKey: ['obsidian-metadata'], | ||||
|         initialData: [], | ||||
|         queryFn: async () => { | ||||
|             const response = await fetch("http://localhost:9002/metadata") | ||||
|             const fullData: any[] = await response.json(); | ||||
| 
 | ||||
|             return R.sortBy(v => -(v.data.backlinks?.length ?? 0), fullData.map(md => ({ | ||||
|                 value: md.relativePath, | ||||
|                 label: md.fileName, | ||||
|                 data: md, | ||||
|             }) as Option)); | ||||
|         }, | ||||
|     }); | ||||
| 
 | ||||
|     const onChange = useCallback((value: Option) => { | ||||
|         setSelected(value); | ||||
|         navigator.clipboard.writeText(`[[${value.label}]]`) | ||||
|     }, []); | ||||
| 
 | ||||
|     return (<Select | ||||
|         classNames={{input: () => 'select-input-wrapper'}} | ||||
|         onChange={onChange as any} | ||||
|         components={{MenuList}} | ||||
|         isDisabled={isLoading} | ||||
|         isLoading={isLoading} | ||||
|         isClearable={true} | ||||
|         options={options} | ||||
|         filterOption={createFilter({ignoreAccents: false})} | ||||
|     />) | ||||
| } | ||||
							
								
								
									
										140
									
								
								src/aliases.tsx
									
									
									
									
									
								
							
							
						
						
									
										140
									
								
								src/aliases.tsx
									
									
									
									
									
								
							| @ -1,140 +0,0 @@ | ||||
| import { | ||||
|     ChangeEventHandler, | ||||
|     Dispatch, | ||||
|     KeyboardEventHandler, | ||||
|     MouseEventHandler, | ||||
|     SetStateAction, | ||||
|     useCallback, | ||||
|     useEffect, | ||||
|     useRef, | ||||
|     useState | ||||
| } from "react"; | ||||
| 
 | ||||
| export interface Option { | ||||
|     label: string, | ||||
|     value: string, | ||||
|     data: { | ||||
|         backlinks: unknown[] | ||||
|         aliases?: string[] | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| export function LinkCollection({ selected }: { selected: Option }) { | ||||
|     return ( | ||||
|         <div className={"mt-2"}> | ||||
|             <div className="py-1"> | ||||
|                 <Alias original={selected.label}/> | ||||
|             </div> | ||||
| 
 | ||||
|             {selected.data.aliases?.map(alias => ( | ||||
|                 <div className="py-1"> | ||||
|                     <Alias original={selected.label} alias={alias}/> | ||||
|                 </div> | ||||
|             ))} | ||||
| 
 | ||||
|             <div className="py-1"> | ||||
|                 <CustomAlias selected={selected}/> | ||||
|             </div> | ||||
|         </div> | ||||
|     ); | ||||
| } | ||||
| 
 | ||||
| export function CustomAlias({selected}: { | ||||
|     selected: Option | ||||
| }) { | ||||
|     const [alias, setAlias] = useState(''); | ||||
| 
 | ||||
|     // Reset when selection changes
 | ||||
|     useEffect(() => { | ||||
|         setAlias(''); | ||||
|     }, [selected.value]); | ||||
| 
 | ||||
|     const onClick: MouseEventHandler = useCallback((e) => { | ||||
|         if ((e.target as HTMLElement).tagName == 'SPAN' && alias.length > 0) { | ||||
|             navigator.clipboard.writeText(`[[${selected!.label}|${alias}]]`); | ||||
|         } | ||||
|     }, [selected.value, selected.label, alias]); | ||||
| 
 | ||||
|     return ( | ||||
|         <span onClick={onClick} className={"rounded-md p-1 hover:bg-slate-100"}> | ||||
|             <span className={"text-slate-300 p-0.5"}>[[</span> | ||||
|             <span>{selected.label}</span> | ||||
|             <span className={"text-slate-300 p-0.5"}>|</span> | ||||
|             <span> | ||||
|                 <CustomAliasField content={alias} setContent={setAlias} selected={selected}/> | ||||
|             </span> | ||||
|             <span className={"text-slate-300 p-0.5"}>]]</span> | ||||
|         </span> | ||||
|     ) | ||||
| } | ||||
| 
 | ||||
| function CustomAliasField({ | ||||
|                               selected, | ||||
|                               content, | ||||
|                               setContent | ||||
|                           }: { | ||||
|     selected: Option, | ||||
|     content: string, | ||||
|     setContent: Dispatch<SetStateAction<string>>, | ||||
| }) { | ||||
|     const [width, setWidth] = useState<any>(0); | ||||
|     const span = useRef<HTMLSpanElement>(null); | ||||
| 
 | ||||
|     // Resize on change of content
 | ||||
|     useEffect(() => { | ||||
|         setWidth(span.current!.offsetWidth); | ||||
|         // setWidth(content.length + 'ch');
 | ||||
|     }, [content]); | ||||
| 
 | ||||
|     const changeHandler: ChangeEventHandler<HTMLInputElement> = useCallback(evt => { | ||||
|         setContent(evt.target.value); | ||||
|     }, []); | ||||
| 
 | ||||
|     const onCustomElementKeyDown: KeyboardEventHandler<HTMLInputElement> = useCallback((e) => { | ||||
|         if (e.key == 'Enter') { | ||||
|             navigator.clipboard.writeText(`[[${selected!.label}|${content}]]`); | ||||
|             (e.target as HTMLInputElement).blur() | ||||
|         } | ||||
|     }, [selected.value, selected.label, content]); | ||||
| 
 | ||||
|     return ( | ||||
|         <span> | ||||
|             <span style={{ | ||||
|                 position: 'absolute', | ||||
|                 opacity: 0, | ||||
|                 zIndex: -100, | ||||
|                 whiteSpace: 'pre', | ||||
|             }} ref={span}>{content}</span> | ||||
|             <input | ||||
|                 className={"border-none p-0 px-1"} | ||||
|                 type="text" style={{width: `calc(${width}px + 0.25rem)`}} autoFocus onChange={changeHandler} | ||||
|                 onKeyDown={onCustomElementKeyDown}/> | ||||
|         </span> | ||||
|     ); | ||||
| } | ||||
| 
 | ||||
| export function Alias({ | ||||
|                           original, | ||||
|                           alias | ||||
|                       }: { | ||||
|     original: string, | ||||
|     alias?: string | ||||
| }) { | ||||
|     const onClick = useCallback(() => { | ||||
|         if (alias) { | ||||
|             navigator.clipboard.writeText(`[[${original}|${alias}]]`) | ||||
|         } else { | ||||
|             navigator.clipboard.writeText(`[[${original}]]`) | ||||
|         } | ||||
|     }, [original, alias]); | ||||
| 
 | ||||
|     return ( | ||||
|         <span className={"rounded-md p-1 hover:bg-slate-100"} onClick={onClick}> | ||||
|             <span className={"text-slate-300 p-0.5"}>[[</span> | ||||
|             <span>{original}</span> | ||||
|             {alias && <><span className={"text-slate-300 p-0.5"}>|</span> | ||||
|                 <span>{alias}</span></>} | ||||
|             <span className={"text-slate-300 p-0.5"}>]]</span> | ||||
|         </span> | ||||
|     ); | ||||
| } | ||||
| @ -2,14 +2,14 @@ import React from 'react' | ||||
| import ReactDOM from 'react-dom/client' | ||||
| import './index.css' | ||||
| import {QueryClient, QueryClientProvider} from "@tanstack/react-query"; | ||||
| import {App} from "./App.tsx"; | ||||
| import {LargeSelect} from "./App.tsx"; | ||||
| 
 | ||||
| const queryClient = new QueryClient() | ||||
| 
 | ||||
| ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render( | ||||
|     <React.StrictMode> | ||||
|         <QueryClientProvider client={queryClient}> | ||||
|             <App/> | ||||
|             <LargeSelect/> | ||||
|         </QueryClientProvider> | ||||
|     </React.StrictMode>, | ||||
| ) | ||||
|  | ||||
| @ -14,9 +14,6 @@ export default defineConfig(({ command, mode }) => { | ||||
|             proxy: { | ||||
|                 '/metadata': { | ||||
|                     target: env['OBSIDIAN_BEACHHEAD_SERVER'] | ||||
|                 }, | ||||
|                 '/search': { | ||||
|                     target: env['OBSIDIAN_BEACHHEAD_SERVER'] | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user