Remove old files

This commit is contained in:
Joshua Coles 2023-09-29 07:57:28 +01:00
parent b1e9e2ec7d
commit 3e44846e22
6 changed files with 164 additions and 380 deletions

View File

@ -1,44 +0,0 @@
#root {
max-width: 1280px;
margin: 0 auto;
padding: 2rem;
text-align: center;
}
.logo {
height: 6em;
padding: 1.5em;
will-change: filter;
transition: filter 300ms;
}
.logo:hover {
filter: drop-shadow(0 0 2em #646cffaa);
}
.logo.react:hover {
filter: drop-shadow(0 0 2em #61dafbaa);
}
@keyframes logo-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
@media (prefers-reduced-motion: no-preference) {
a:nth-of-type(2) .logo {
animation: logo-spin infinite 20s linear;
}
}
.card {
padding: 2em;
}
.read-the-docs {
color: #888;
}

View File

@ -1,35 +1,169 @@
import {useState} from 'react'
import reactLogo from './assets/react.svg'
import viteLogo from '/vite.svg'
import './App.css'
import {ChangeEventHandler, KeyboardEventHandler, ReactNode, 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';
function App() {
const [count, setCount] = useState(0)
import {useQuery} from "@tanstack/react-query";
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}
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: [],
queryFn: async () => {
const response = await fetch("http://100.115.154.44: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 [selected, setSelected] = useState<Option | null>(null);
const onChange = useCallback((value: Option) => {
setSelected(value);
navigator.clipboard.writeText(`[[${value.label}]]`)
}, []);
return (
<>
<div>
<a href="https://vitejs.dev" target="_blank">
<img src={viteLogo} className="logo" alt="Vite logo"/>
</a>
<a href="https://react.dev" target="_blank">
<img src={reactLogo} className="logo react" alt="React logo"/>
</a>
</div>
<h1>Vite + React</h1>
<div className="card">
<button onClick={() => setCount((count) => count + 1)}>
count is {count}
</button>
<p>
Edit <code>src/App.tsx</code> and save to test HMR
</p>
</div>
<p className="read-the-docs">
Click on the Vite and React logos to learn more
</p>
</>
<div className={"m-5 text-lg"}>
<Select
onChange={onChange as any}
components={{MenuList}}
isLoading={isLoading}
options={options}
filterOption={createFilter({ignoreAccents: false})}
/>
{selected && <div className={"mt-2"}>
{selected.data.aliases?.map(alias => (
<div className="py-1">
<Alias original={selected.label} alias={alias}/>
</div>
))}
<div className="py-1">
<span 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 selected={selected}/>
</span>
<span className={"text-slate-300 p-0.5"}>]]</span>
</span>
</div>
</div>}
</div>
)
}
export default App
function CustomAliasField({selected}: {
selected: Option
}) {
const [content, setContent] = useState('');
const [width, setWidth] = useState<any>(0);
const span = useRef<HTMLSpanElement>(null);
// Reset when selection changes
useEffect(() => {
setContent('');
}, [selected.value]);
// 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(() => {
navigator.clipboard.writeText(`[[${original}|${alias}]]`)
}, [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>
<span className={"text-slate-300 p-0.5"}>|</span>
<span>{alias}</span>
<span className={"text-slate-300 p-0.5"}>]]</span>
</span>
);
}

View File

@ -1,110 +0,0 @@
/*
This example requires some changes to your config:
```
// tailwind.config.js
module.exports = {
// ...
plugins: [
// ...
require('@tailwindcss/forms'),
],
}
```
*/
import {useMemo, useState} from 'react'
import {CheckIcon, ChevronUpDownIcon} from '@heroicons/react/20/solid'
import {Combobox} from '@headlessui/react'
import {useQuery} from "@tanstack/react-query";
function classNames(...classes: any[]) {
return classes.filter(Boolean).join(' ')
}
export default function Example() {
const {data: options} = useQuery({
queryKey: ['obsidian-metadata'],
initialData: [],
queryFn: async () => {
const response = await fetch("http://100.115.154.44:9002/metadata")
const fullData: any[] = await response.json();
return fullData.map(md => ({
id: md.relativePath,
name: md.fileName
}));
},
});
const [query, setQuery] = useState('')
const [selectedPerson, setSelectedPerson] = useState(null)
const filteredOptions =
useMemo(() => {
return query === ''
? options
: options.filter((option) => {
return option.name.toLowerCase().includes(query.toLowerCase())
})
}, [query, options])
return (
<Combobox as="div" value={selectedPerson} onChange={setSelectedPerson}>
<Combobox.Label className="block text-sm font-medium leading-6 text-gray-900">Assigned to</Combobox.Label>
<div className="relative mt-2">
<Combobox.Input
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: (typeof filteredOptions)[number]) => person?.name}
/>
<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>
{filteredOptions.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">
{filteredOptions.map((person) => (
<Combobox.Option
key={person.id}
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.name}</span>
<span
className={classNames(
'ml-2 truncate text-gray-500',
active ? 'text-indigo-200' : 'text-gray-500'
)}
>
{person.id}
</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>
)
}

View File

@ -1,26 +0,0 @@
import {useQuery} from "@tanstack/react-query";
import Select, {createFilter} from "react-select";
export default function Example() {
const {data: options, isLoading} = useQuery({
queryKey: ['obsidian-metadata'],
initialData: [],
queryFn: async () => {
const response = await fetch("http://100.115.154.44:9002/metadata")
const fullData: any[] = await response.json();
return fullData.map(md => ({
value: md.relativePath as string,
label: md.fileName as string
}));
},
});
return <Select
options={options}
isLoading={isLoading}
isSearchable={true}
isClearable={true}
filterOption={createFilter({ ignoreAccents: false })}
/>;
}

View File

@ -1,170 +0,0 @@
import {ChangeEventHandler, KeyboardEventHandler, ReactNode, useCallback, useEffect, useRef, useState} from "react";
import AsyncSelect from "react-select/async";
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";
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}
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: [],
queryFn: async () => {
const response = await fetch("http://100.115.154.44: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 [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"}>
<Select
onChange={onChange as any}
components={{MenuList}}
isLoading={isLoading}
options={options}
filterOption={createFilter({ignoreAccents: false})}
/>
{selected && <div className={"mt-2"}>
{selected.data.aliases?.map(alias => (
<div className="py-1">
<Alias original={selected.label} alias={alias}/>
</div>
))}
<div className="py-1">
<span 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 selected={selected}/>
</span>
<span className={"text-slate-300 p-0.5"}>]]</span>
</span>
</div>
</div>}
</div>
)
}
function CustomAliasField({selected}: {
selected: Option
}) {
const [content, setContent] = useState('');
const [width, setWidth] = useState<any>(0);
const span = useRef<HTMLSpanElement>(null);
// Reset when selection changes
useEffect(() => {
setContent('');
}, [selected.value]);
// 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(() => {
navigator.clipboard.writeText(`[[${original}|${alias}]]`)
}, [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>
<span className={"text-slate-300 p-0.5"}>|</span>
<span>{alias}</span>
<span className={"text-slate-300 p-0.5"}>]]</span>
</span>
);
}

View File

@ -2,7 +2,7 @@ import React from 'react'
import ReactDOM from 'react-dom/client'
import './index.css'
import {QueryClient, QueryClientProvider} from "@tanstack/react-query";
import {LargeSelect} from "./TA.tsx";
import {LargeSelect} from "./App.tsx";
const queryClient = new QueryClient()