From ab3d205f6d5410bd1d67f436258a0551d4de9d6a Mon Sep 17 00:00:00 2001 From: Nate Kelley Date: Fri, 10 Jan 2025 11:03:14 -0700 Subject: [PATCH] add loading indicator for fetching temp data --- .../api/busterv2/datasets/queryRequests.ts | 3 +- .../busterv2/datasets/responseInterfaces.ts | 5 +- .../[datasetId]/_DatasetPageContext.tsx | 6 +- .../[datasetId]/editor/DataContainer.tsx | 10 +++- .../[datasetId]/editor/EditorContent.tsx | 57 ++++++++++++------- .../[datasetId]/editor/SQLContainer.tsx | 7 ++- .../loaders/IndeterminateLinearLoader.tsx | 12 +++- web/src/routes/busterRoutes/busterRoutes.ts | 2 +- 8 files changed, 74 insertions(+), 28 deletions(-) diff --git a/web/src/api/busterv2/datasets/queryRequests.ts b/web/src/api/busterv2/datasets/queryRequests.ts index 73e0e5f37..a7ae90e25 100644 --- a/web/src/api/busterv2/datasets/queryRequests.ts +++ b/web/src/api/busterv2/datasets/queryRequests.ts @@ -54,11 +54,12 @@ export const useGetDatasetData = (datasetId: string) => { export const useGetDatasetMetadata = (datasetId: string) => { const queryFn = useMemoizedFn(() => getDatasetMetadata(datasetId)); - return useCreateReactQuery({ + const res = useCreateReactQuery({ queryKey: ['datasetMetadata', datasetId], queryFn, enabled: !!datasetId }); + return res; }; export const prefetchGetDatasetMetadata = async ( diff --git a/web/src/api/busterv2/datasets/responseInterfaces.ts b/web/src/api/busterv2/datasets/responseInterfaces.ts index d8d930352..f2791f8ac 100644 --- a/web/src/api/busterv2/datasets/responseInterfaces.ts +++ b/web/src/api/busterv2/datasets/responseInterfaces.ts @@ -1,4 +1,4 @@ -import { DataSource } from '../datasources'; +import { DataSource, DataSourceTypes } from '../datasources'; export interface BusterDatasetListItem { id: string; @@ -28,6 +28,9 @@ export type BusterDataset = { name: string; sql: string; yml_file: string; + data_source_id: string; + data_source_name: string; + data_source_type: DataSourceTypes; }; export interface BusterDatasetColumn { diff --git a/web/src/app/app/datasets/[datasetId]/_DatasetPageContext.tsx b/web/src/app/app/datasets/[datasetId]/_DatasetPageContext.tsx index df2fac465..437acacdd 100644 --- a/web/src/app/app/datasets/[datasetId]/_DatasetPageContext.tsx +++ b/web/src/app/app/datasets/[datasetId]/_DatasetPageContext.tsx @@ -2,7 +2,7 @@ import { useIndividualDataset } from '@/context/Datasets'; import { useSelectedLayoutSegment } from 'next/navigation'; -import React, { PropsWithChildren, useEffect, useLayoutEffect, useState } from 'react'; +import React, { PropsWithChildren, useEffect, useState } from 'react'; import { DatasetApps } from './_config'; import { createContext, @@ -13,8 +13,8 @@ import { export const useDatasetPageContext = ({ datasetId }: { datasetId: string }) => { const segments = useSelectedLayoutSegment() as DatasetApps; const { dataset, datasetData } = useIndividualDataset({ datasetId }); - const originalDatasetSQL = dataset.data?.sql; - const datasetYmlFile = dataset.data?.yml_file; + const originalDatasetSQL = dataset?.data?.sql; + const datasetYmlFile = dataset?.data?.yml_file; const [sql, setSQL] = useState(originalDatasetSQL || ''); const [ymlFile, setYmlFile] = useState(datasetYmlFile || ''); diff --git a/web/src/app/app/datasets/[datasetId]/editor/DataContainer.tsx b/web/src/app/app/datasets/[datasetId]/editor/DataContainer.tsx index 21af3f108..9c3f9fe59 100644 --- a/web/src/app/app/datasets/[datasetId]/editor/DataContainer.tsx +++ b/web/src/app/app/datasets/[datasetId]/editor/DataContainer.tsx @@ -3,6 +3,7 @@ import { createStyles } from 'antd-style'; import React from 'react'; import isEmpty from 'lodash/isEmpty'; import AppDataGrid from '@/components/table/AppDataGrid'; +import { IndeterminateLinearLoader } from '@/components/loaders'; export const DataContainer: React.FC<{ data: BusterDatasetData; @@ -13,7 +14,14 @@ export const DataContainer: React.FC<{ const hasData = !isEmpty(data); return ( -
+
+ + {hasData ? ( ) : ( diff --git a/web/src/app/app/datasets/[datasetId]/editor/EditorContent.tsx b/web/src/app/app/datasets/[datasetId]/editor/EditorContent.tsx index cc111f814..f2193f78c 100644 --- a/web/src/app/app/datasets/[datasetId]/editor/EditorContent.tsx +++ b/web/src/app/app/datasets/[datasetId]/editor/EditorContent.tsx @@ -1,6 +1,6 @@ 'use client'; -import React, { useRef, useState } from 'react'; +import React, { useMemo, useRef, useState } from 'react'; import { useDatasetPageContextSelector } from '../_DatasetPageContext'; import { AppSplitter, AppSplitterRef } from '@/components'; import { SQLContainer } from './SQLContainer'; @@ -12,6 +12,9 @@ import { EditorApps, EditorContainerSubHeader } from './EditorContainerSubHeader import { createStyles } from 'antd-style'; import { MetadataContainer } from './MetadataContainer'; import { runSQL } from '@/api/busterv2'; +import { RustApiError } from '@/api/buster/errors'; +import isEmpty from 'lodash/isEmpty'; + export const EditorContent: React.FC<{ defaultLayout: [string, string]; }> = ({ defaultLayout }) => { @@ -20,35 +23,51 @@ export const EditorContent: React.FC<{ const splitterRef = useRef(null); const [selectedApp, setSelectedApp] = useState(EditorApps.PREVIEW); const datasetData = useDatasetPageContextSelector((state) => state.datasetData); + const { data: dataset } = useDatasetPageContextSelector((state) => state.dataset); const sql = useDatasetPageContextSelector((state) => state.sql); const setSQL = useDatasetPageContextSelector((state) => state.setSQL); const ymlFile = useDatasetPageContextSelector((state) => state.ymlFile); const setYmlFile = useDatasetPageContextSelector((state) => state.setYmlFile); const [tempData, setTempData] = useState(datasetData.data || []); - const [fetchingTempData, setFetchingTempData] = useState(false); + const [runSQLError, setRunSQLError] = useState(''); - const { runAsync: runQuery } = useRequest( + const shownData = useMemo(() => { + return isEmpty(tempData) ? datasetData.data || [] : tempData; + }, [tempData, datasetData.data]); + + const { runAsync: runQuery, loading: fetchingTempData } = useRequest( async () => { - await timeout(1000); - const res = await runSQL({ data_source_id: '123', sql }); - console.log(res); + try { + console.log('dataset', sql); + const res = await runSQL({ data_source_id: dataset?.data_source_id!, sql }); + const data = res.data.data; + setTempData(data); + return data; + } catch (error) { + setRunSQLError((error as unknown as RustApiError)?.message || 'Something went wrong'); + } }, { manual: true } ); - const fetchingData = fetchingTempData || datasetData.isFetching; - - const error = ''; + const fetchingInitialData = datasetData.isFetching; const onRunQuery = useMemoizedFn(async () => { - await runQuery(); - const heightOfRow = 36; - const heightOfDataContainer = heightOfRow * (datasetData.data?.length || 0); - const containerHeight = ref.current?.clientHeight || 0; - const maxHeight = Math.floor(containerHeight * 0.6); - const finalHeight = Math.min(heightOfDataContainer, maxHeight); - splitterRef.current?.setSplitSizes(['auto', `${finalHeight}px`]); + try { + const result = await runQuery(); + if (result && result.length > 0) { + const headerHeight = 50; + const heightOfRow = 36; + const heightOfDataContainer = headerHeight + heightOfRow * (result.length || 0); + const containerHeight = ref.current?.clientHeight || 0; + const maxHeight = Math.floor(containerHeight * 0.6); + const finalHeight = Math.min(heightOfDataContainer, maxHeight); + splitterRef.current?.setSplitSizes(['auto', `${finalHeight}px`]); + } + } catch (error) { + // + } }); return ( @@ -63,15 +82,15 @@ export const EditorContent: React.FC<{ className="mb-3" datasetSQL={sql} setDatasetSQL={setSQL} - error={error} + error={runSQLError} onRunQuery={onRunQuery} /> } rightChildren={ } split="horizontal" diff --git a/web/src/app/app/datasets/[datasetId]/editor/SQLContainer.tsx b/web/src/app/app/datasets/[datasetId]/editor/SQLContainer.tsx index e6da80c28..1916e785e 100644 --- a/web/src/app/app/datasets/[datasetId]/editor/SQLContainer.tsx +++ b/web/src/app/app/datasets/[datasetId]/editor/SQLContainer.tsx @@ -36,7 +36,12 @@ export const SQLContainer: React.FC<{ return (
- +