From 0fddf4d852124664ffee7128152b9ab6fbae8ebb Mon Sep 17 00:00:00 2001 From: Jan Potoms <2109932+Janpot@users.noreply.github.com> Date: Wed, 14 Dec 2022 18:10:50 +0100 Subject: [PATCH] Add feedback when query is running --- .../src/toolpadDataSources/QueryPreview.tsx | 19 ++++++++++++ .../toolpadDataSources/function/client.tsx | 30 ++++++++----------- .../googleSheets/client.tsx | 24 ++++++++------- .../toolpadDataSources/postgres/client.tsx | 24 ++++++++------- .../src/toolpadDataSources/rest/client.tsx | 29 ++++++++---------- .../src/toolpadDataSources/useQueryPreview.ts | 5 +++- 6 files changed, 75 insertions(+), 56 deletions(-) create mode 100644 packages/toolpad-app/src/toolpadDataSources/QueryPreview.tsx diff --git a/packages/toolpad-app/src/toolpadDataSources/QueryPreview.tsx b/packages/toolpad-app/src/toolpadDataSources/QueryPreview.tsx new file mode 100644 index 00000000000..0e182b38102 --- /dev/null +++ b/packages/toolpad-app/src/toolpadDataSources/QueryPreview.tsx @@ -0,0 +1,19 @@ +import { LinearProgress } from '@mui/material'; +import { Box } from '@mui/system'; +import * as React from 'react'; +import ErrorAlert from '../toolpad/AppEditor/PageEditor/ErrorAlert'; + +export interface QueryPreviewProps { + children?: React.ReactNode; + error?: unknown; + isLoading?: boolean; +} + +export default function QueryPreview({ children, error, isLoading }: QueryPreviewProps) { + return ( + + {isLoading ? : null} + {error ? : children} + + ); +} diff --git a/packages/toolpad-app/src/toolpadDataSources/function/client.tsx b/packages/toolpad-app/src/toolpadDataSources/function/client.tsx index 27031086e55..66311e89df7 100644 --- a/packages/toolpad-app/src/toolpadDataSources/function/client.tsx +++ b/packages/toolpad-app/src/toolpadDataSources/function/client.tsx @@ -28,8 +28,6 @@ import lazyComponent from '../../utils/lazyComponent'; import ParametersEditor from '../../toolpad/AppEditor/PageEditor/ParametersEditor'; import SplitPane from '../../components/SplitPane'; import { usePrivateQuery } from '../context'; -import JsonView from '../../components/JsonView'; -import ErrorAlert from '../../toolpad/AppEditor/PageEditor/ErrorAlert'; import { LogEntry } from '../../components/Console'; import MapEntriesEditor from '../../components/MapEntriesEditor'; import { Maybe } from '../../utils/types'; @@ -46,6 +44,8 @@ import { MOVIES_API_DEMO_URL } from '../demo'; import * as appDom from '../../appDom'; import { clientExec } from './runtime'; import config from '../../config'; +import QueryPreview from '../QueryPreview'; +import JsonView from '../../components/JsonView'; const EVENT_INTERFACE_IDENTIFIER = 'ToolpadFunctionEvent'; @@ -163,17 +163,16 @@ function QueryEditor({ const [previewLogs, setPreviewLogs] = React.useState([]); const [previewHar, setPreviewHar] = React.useState(() => createHarLog()); - const { preview, runPreview: handleRunPreview } = useQueryPreview( - fetchPreview, - input.attributes.query.value, - previewParams, - { - onPreview(result) { - setPreviewLogs((existing) => [...existing, ...result.logs]); - setPreviewHar((existing) => mergeHar(createHarLog(), existing, result.har)); - }, + const { + preview, + runPreview: handleRunPreview, + isLoading: previewIsLoading, + } = useQueryPreview(fetchPreview, input.attributes.query.value, previewParams, { + onPreview(result) { + setPreviewLogs((existing) => [...existing, ...result.logs]); + setPreviewHar((existing) => mergeHar(createHarLog(), existing, result.har)); }, - ); + }); const { data: secretsKeys = [] } = usePrivateQuery({ kind: 'secretsKeys', @@ -254,12 +253,9 @@ function QueryEditor({ - {preview?.error ? ( - - ) : ( + - )} - + parseColumns(inferColumns(rawRows)), [rawRows]); @@ -201,11 +200,14 @@ function QueryEditor({ - {preview?.error ? ( - - ) : ( - - )} + ); } diff --git a/packages/toolpad-app/src/toolpadDataSources/postgres/client.tsx b/packages/toolpad-app/src/toolpadDataSources/postgres/client.tsx index 8cd3838b0e2..9400e629a7f 100644 --- a/packages/toolpad-app/src/toolpadDataSources/postgres/client.tsx +++ b/packages/toolpad-app/src/toolpadDataSources/postgres/client.tsx @@ -10,7 +10,6 @@ import SyncIcon from '@mui/icons-material/Sync'; import { getObjectKey } from '@mui/toolpad-core/objectKey'; import { BindableAttrEntries, BindableAttrValue } from '@mui/toolpad-core'; import SplitPane from '../../components/SplitPane'; -import ErrorAlert from '../../toolpad/AppEditor/PageEditor/ErrorAlert'; import ParametersEditor from '../../toolpad/AppEditor/PageEditor/ParametersEditor'; import { useEvaluateLiveBindingEntries } from '../../toolpad/AppEditor/useEvaluateLiveBinding'; import { ClientDataSource, ConnectionEditorProps, QueryEditorProps } from '../../types'; @@ -190,11 +189,11 @@ function QueryEditor({ [fetchPrivate], ); - const { preview, runPreview: handleRunPreview } = useQueryPreview( - fetchServerPreview, - input.attributes.query.value, - previewParams, - ); + const { + preview, + runPreview: handleRunPreview, + isLoading: previewIsLoading, + } = useQueryPreview(fetchServerPreview, input.attributes.query.value, previewParams); const rawRows: any[] = preview?.data || EMPTY_ROWS; const columns: GridColDef[] = React.useMemo(() => parseColumns(inferColumns(rawRows)), [rawRows]); @@ -227,11 +226,14 @@ function QueryEditor({ - {preview?.error ? ( - - ) : ( - - )} + ); } diff --git a/packages/toolpad-app/src/toolpadDataSources/rest/client.tsx b/packages/toolpad-app/src/toolpadDataSources/rest/client.tsx index 68e34c88ffb..f4627f83db2 100644 --- a/packages/toolpad-app/src/toolpadDataSources/rest/client.tsx +++ b/packages/toolpad-app/src/toolpadDataSources/rest/client.tsx @@ -50,7 +50,6 @@ import ParametersEditor from '../../toolpad/AppEditor/PageEditor/ParametersEdito import BodyEditor from './BodyEditor'; import TabPanel from '../../components/TabPanel'; import SplitPane from '../../components/SplitPane'; -import ErrorAlert from '../../toolpad/AppEditor/PageEditor/ErrorAlert'; import JsonView from '../../components/JsonView'; import useQueryPreview from '../useQueryPreview'; import TransformInput from '../TranformInput'; @@ -60,6 +59,7 @@ import config from '../../config'; import QueryInputPanel from '../QueryInputPanel'; import useFetchPrivate from '../useFetchPrivate'; import { clientExec } from './runtime'; +import QueryPreview from '../QueryPreview'; const HTTP_METHODS = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD']; @@ -392,18 +392,17 @@ function QueryEditor({ clientExec(query, params, fetchServerPreview); const [previewHar, setPreviewHar] = React.useState(() => createHarLog()); - const { preview, runPreview: handleRunPreview } = useQueryPreview( - fetchPreview, - input.attributes.query.value, - previewParams, - { - onPreview(result) { - setPreviewHar((existing) => - result.har ? mergeHar(createHarLog(), existing, result.har) : existing, - ); - }, + const { + preview, + runPreview: handleRunPreview, + isLoading: previewIsLoading, + } = useQueryPreview(fetchPreview, input.attributes.query.value, previewParams, { + onPreview(result) { + setPreviewHar((existing) => + result.har ? mergeHar(createHarLog(), existing, result.har) : existing, + ); }, - ); + }); const handleHarClear = React.useCallback(() => setPreviewHar(createHarLog()), []); @@ -546,11 +545,9 @@ function QueryEditor({ allowResize pane1Style={{ overflow: 'auto' }} > - {preview?.error ? ( - - ) : ( + setActiveTab('transform')} /> - )} + & P { onPreview = () => {} }: UseQueryPreviewOptions = {}, ) { const [preview, setPreview] = React.useState(null); + const [isLoading, setIsloading] = React.useState(false); const cancelRunPreview = React.useRef<(() => void) | null>(null); const runPreview = React.useCallback(() => { @@ -23,6 +24,7 @@ export default function useQueryPreview & P canceled = true; }; + setIsloading(true); dofetch(query, params) .then( (result) => { @@ -36,9 +38,10 @@ export default function useQueryPreview & P }, ) .finally(() => { + setIsloading(false); cancelRunPreview.current = null; }); }, [dofetch, query, params, onPreview]); - return { preview, runPreview }; + return { preview, runPreview, isLoading }; }