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,