/* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ import React, { useState, useEffect, useRef } from 'react'; import { EuiProgress } from '@elastic/eui'; /** * Executes the specified load function any time loadDeps changes. Ensures the load * function is never run in parallel. Shows a loading indicator while loading. */ export function Loader(props: { load: () => Promise; loadDeps: unknown[] }) { const [isProcessing, setIsProcessing] = useState(false); const prevRequest = useRef | undefined>(undefined); const nextRequest = useRef<(() => void) | undefined>(undefined); useEffect( function performLoad() { if (prevRequest.current) { nextRequest.current = performLoad; return; } setIsProcessing(true); prevRequest.current = props .load() .catch(() => {}) .then(() => { const reload = nextRequest.current; prevRequest.current = undefined; nextRequest.current = undefined; if (reload) { reload(); } else { setIsProcessing(false); } }); }, // eslint-disable-next-line react-hooks/exhaustive-deps props.loadDeps ); if (!isProcessing) { return null; } return ; }