better code: typing

Massimo Melina committed Jul 13, 2023 at 15:41 UTC dee2f180ea4d52fa7d499d916351c52d4d9f5c05
3 files changed +19 -10
frontend/src/components.ts
+10 -6
@@ -11,6 +11,7 @@ import {
11 InputHTMLAttributes,
12 isValidElement, MouseEventHandler,
13 ReactNode,
14 + SelectHTMLAttributes,
15 useMemo
16 } from 'react'
17
@@ -51,15 +52,18 @@ export function Checkbox({ onChange, value, children, ...props }: CheckboxProps)
52 return !children ? ret : h('label', {}, ret, children)
53 }
54
54 -type Options = { label:string, value:string }[]
55 -interface SelectProps { value:any, onChange?:(v:string)=>void, options:Options }
56 -export function Select({ onChange, value, options, ...props }:SelectProps) {
55 +interface SelectProps extends Omit<SelectHTMLAttributes<HTMLSelectElement>, 'value' | 'onChange'> {
56 + value: string, // just string for the time being
57 + onChange?: (v: string) => void,
58 + options: { label: string, value: string }[]
59 +}
60 +export function Select({ onChange, value, options, ...props }: SelectProps) {
61 return h('select', {
58 - onChange: ev => // @ts-ignore
59 - onChange?.(ev.target.value),
62 + onChange: ev =>
63 + onChange?.((ev.target as any).value),
64 value,
65 ...props,
62 - }, options.map(({ value, label }) => h('option', { key:value, value }, label)))
66 + }, options.map(({ value, label }) => h('option', { key: value, value }, label)))
67 }
68
69 export function Html({ code, ...rest }: { code:string } & HTMLAttributes<any>) {
frontend/src/useFetchList.ts
+4 -4
@@ -38,14 +38,14 @@ export default function useFetchList() {
38 return
39 }
40
41 - const baseParams = {
41 + const params = {
42 uri: desiredPath,
43 search,
44 sse: true,
45 [RELOADER_PROP]: snap.listReloader, // symbol, so it won't be serialized, but will force reloading
46 }
47 - if (_.isEqual(baseParams, lastReq.current)) return
48 - lastReq.current = baseParams
47 + if (_.isEqual(params, lastReq.current)) return
48 + lastReq.current = params
49
50 state.list = []
51 state.filteredList = undefined
@@ -62,7 +62,7 @@ export default function useFetchList() {
62 state.list = sort([...state.list, ...chunk])
63 }
64 const timer = setInterval(flush, 1000)
65 - const src = apiEvents('file_list', baseParams, (type, data) => {
65 + const src = apiEvents('file_list', params, (type, data) => {
66 if (!isMounted()) return
67 switch (type) {
68 case 'error':
shared/react.ts
+5
@@ -32,6 +32,11 @@ export function dontBotherWithKeys(elements: ReactNode[]): (ReactNode|string)[]
32 : h(Fragment, { key:i, children:e }) )
33 }
34
35 +/* the idea is that you need a job done by a worker, but the worker will execute only after it collected jobs for some time
36 + by other "users" of the same worker, like other instances of the same component, but potentially also different components.
37 + User of this hook will just be returned with the single result of its own job.
38 + As an additional feature, results are cached. You can clear the cache by calling cache.clear()
39 +*/
40 export function useBatch<Job=unknown,Result=unknown>(
41 worker: ((jobs: Job[]) => Promise<Result[]>),
42 job: undefined | Job,