admin/logs: quicker display of logs

Massimo Melina committed Aug 9, 2022 at 16:44 UTC e5b7e0d9d8b52d53802a928417a0b78336b413cb
2 files changed +13 -14
admin/src/LogsPage.ts
+2 -2
@@ -17,11 +17,11 @@ export default function LogsPage() {
17 }
18
19 function LogFile({ file }: { file: string }) {
20 - const { list, error } = useApiList('get_log', { file }, { addId: true })
20 + const { list, error, initializing } = useApiList('get_log', { file }, { addId: true })
21 if (error)
22 return error
23 return h(DataGrid, {
24 - loading: !list,
24 + loading: initializing,
25 rows: list as any,
26 componentsProps: {
27 pagination: {
admin/src/api.ts
+11 -12
@@ -153,18 +153,19 @@ export function useApiList<T=any>(cmd:string|Falsy, params: Dict={}, { addId=fal
153 useEffect(() => {
154 if (!cmd) return
155 const buffer: T[] = []
156 - const flush = () => {
156 + const apply = _.debounce(() => {
157 const chunk = buffer.splice(0, Infinity)
158 if (chunk.length)
159 setList(list => [ ...list, ...chunk ])
160 - }
160 + }, 1000, { maxWait: 1000 })
161 setError(undefined)
162 setLoading(true)
163 setInitializing(true)
164 setList([])
165 - const timer = setInterval(flush, 1000)
165 const src = apiEvents(cmd, params, (type, data) => {
166 switch (type) {
167 + case 'connected':
168 + return setTimeout(() => apply.flush()) // this trick we'll cause first entries to be rendered almost immediately, while the rest will be subject to normal debouncing
169 case 'error':
170 setError("Connection error")
171 return stop()
@@ -174,7 +175,7 @@ export function useApiList<T=any>(cmd:string|Falsy, params: Dict={}, { addId=fal
175 if (src?.readyState === src?.CLOSED)
176 return stop()
177 if (data === 'ready') {
177 - flush()
178 + apply.flush()
179 setInitializing(false)
180 return
181 }
@@ -184,7 +185,9 @@ export function useApiList<T=any>(cmd:string|Falsy, params: Dict={}, { addId=fal
185 const rec = map(data.add)
186 if (addId)
187 rec.id = ++idRef.current
187 - return buffer.push(rec)
188 + buffer.push(rec)
189 + apply()
190 + return
191 }
192 if (data.remove) {
193 const matchOnList: ReturnType<typeof _.matches>[] = []
@@ -204,7 +207,7 @@ export function useApiList<T=any>(cmd:string|Falsy, params: Dict={}, { addId=fal
207 return
208 }
209 if (data.update) {
207 - flush() // avoid treating buffer
210 + apply.flush() // avoid treating buffer
211 setList(list => {
212 const modified = [...list]
213 for (const { search, change } of data.update) {
@@ -220,16 +223,12 @@ export function useApiList<T=any>(cmd:string|Falsy, params: Dict={}, { addId=fal
223 }
224 })
225
223 - return () => {
224 - src.close()
225 - stop()
226 - }
226 + return () => src.close()
227
228 function stop() {
229 setInitializing(false)
230 setLoading(false)
231 - clearInterval(timer)
232 - flush()
231 + apply.flush()
232 }
233 }, [cmd, JSON.stringify(params)]) //eslint-disable-line
234 return { list, loading, error, initializing, setList, updateList }