diff --git a/src/api/dashboard.ts b/src/api/dashboard.ts
index f6f840b2..f2761ba7 100644
--- a/src/api/dashboard.ts
+++ b/src/api/dashboard.ts
@@ -28,7 +28,7 @@ export const putDashboard = (dashboardId: string, dashboard: UpdateDashboardType
};
export const postDashboard = (dashboard: CreateDashboardType | ImportDashboardType) => {
- return Axios().post(CREATE_DASHBOARDS_URL, { ...dashboard});
+ return Axios().post(CREATE_DASHBOARDS_URL, { ...dashboard });
};
export const removeDashboard = (dashboardId: string) => {
diff --git a/src/hooks/useDashboards.tsx b/src/hooks/useDashboards.tsx
index d24bda84..3b6a5426 100644
--- a/src/hooks/useDashboards.tsx
+++ b/src/hooks/useDashboards.tsx
@@ -4,12 +4,10 @@ import { AxiosError, isAxiosError } from 'axios';
import _ from 'lodash';
import { useDashboardsStore, dashboardsStoreReducers } from '@/pages/Dashboards/providers/DashboardsProvider';
import { getDashboards, getQueryData, postDashboard, putDashboard, removeDashboard } from '@/api/dashboard';
-import { useCallback, useState } from 'react';
import {
CreateDashboardType,
Dashboard,
ImportDashboardType,
- TileQuery,
TileQueryResponse,
UpdateDashboardType,
} from '@/@types/parseable/api/dashboards';
@@ -145,34 +143,48 @@ export const useDashboardsQuery = (opts: { updateTimeRange?: (dashboard: Dashboa
};
};
-export const useTileQuery = (opts?: { tileId?: string; onSuccess?: (data: TileQueryResponse) => void }) => {
+export const useTileQuery = (opts: {
+ tileId?: string;
+ query: string;
+ startTime: Date;
+ endTime: Date;
+ onSuccess?: (data: TileQueryResponse) => void;
+ enabled?: boolean;
+}) => {
const [, setDashboardsStore] = useDashboardsStore((_store) => null);
- const { onSuccess } = opts || {};
- const [fetchState, setFetchState] = useState<{
- isLoading: boolean;
- isError: null | boolean;
- isSuccess: null | boolean;
- }>({ isLoading: false, isError: null, isSuccess: null });
-
- const fetchTileData = useCallback(
- async (queryOpts: TileQuery) => {
- try {
- setFetchState({ isLoading: true, isError: null, isSuccess: null });
- const res = await getQueryData(queryOpts);
+ const { query, startTime, endTime, tileId, enabled = true } = opts;
+ const { isLoading, isFetching, isError, refetch } = useQuery(
+ [tileId, query, startTime, endTime],
+ () =>
+ getQueryData({
+ query,
+ startTime,
+ endTime,
+ }),
+ {
+ onSuccess: (res) => {
const tileData = _.isEmpty(res) ? { records: [], fields: [] } : res.data;
- opts?.tileId && setDashboardsStore((store) => setTileData(store, opts.tileId || '', tileData));
- opts?.onSuccess && opts.onSuccess(tileData);
- setFetchState({ isLoading: false, isError: false, isSuccess: true });
- } catch (e: any) {
- setFetchState({ isLoading: false, isError: true, isSuccess: false });
- notifyError({ message: _.isString(e.response.data) ? e.response.data : 'Unable to fetch tile data' });
- }
+ if (tileId) {
+ setDashboardsStore((store) => setTileData(store, tileId, tileData));
+ }
+ },
+ onError: (error: AxiosError) => {
+ if (isAxiosError(error) && error.response) {
+ notifyError({
+ message: _.isString(error.response.data) ? error.response.data : 'Unable to fetch tile data',
+ });
+ }
+ },
+ refetchOnWindowFocus: false,
+ enabled,
},
- [onSuccess],
);
+ const isLoadingState = isLoading || isFetching;
+
return {
- ...fetchState,
- fetchTileData,
+ isLoading: isLoadingState,
+ isError,
+ refetch,
};
};
diff --git a/src/pages/Dashboards/CreateTileForm.tsx b/src/pages/Dashboards/CreateTileForm.tsx
index f834543d..a77b3ea0 100644
--- a/src/pages/Dashboards/CreateTileForm.tsx
+++ b/src/pages/Dashboards/CreateTileForm.tsx
@@ -326,7 +326,13 @@ const Query = (props: { form: TileFormType; onChangeValue: (key: string, value:
props.form.validate();
}, []);
- const { fetchTileData, isLoading } = useTileQuery({ onSuccess: onFetchTileSuccess });
+ const { refetch, isLoading } = useTileQuery({
+ onSuccess: onFetchTileSuccess,
+ query: '', // Initial query (will be updated in refetch)
+ startTime: timeRange.startTime,
+ endTime: timeRange.endTime,
+ enabled: false,
+ });
const validateQuery = useCallback(() => {
if (_.isEmpty(dashboardId)) return;
@@ -337,7 +343,9 @@ const Query = (props: { form: TileFormType; onChangeValue: (key: string, value:
const santizedQuery = sanitiseSqlString(query, true, 100);
onChangeValue('query', santizedQuery);
const { from, to } = selectedDashboard.time_filter || { from: timeRange.startTime, to: timeRange.endTime };
- fetchTileData({ query: santizedQuery, startTime: dayjs(from).toDate(), endTime: dayjs(to).toDate() });
+ refetch({
+ queryKey: [santizedQuery, dayjs(from).toDate(), dayjs(to).toDate()],
+ });
}, [query, dashboardId, dashboards, timeRange]);
const onStreamSelect = useCallback((val: string | null) => {
diff --git a/src/pages/Dashboards/Tile.tsx b/src/pages/Dashboards/Tile.tsx
index 2b3f6953..6c4fd90f 100644
--- a/src/pages/Dashboards/Tile.tsx
+++ b/src/pages/Dashboards/Tile.tsx
@@ -23,7 +23,7 @@ import handleCapture, { makeExportClassName } from '@/utils/exportImage';
import { useDashboardsStore, dashboardsStoreReducers } from './providers/DashboardsProvider';
import _ from 'lodash';
import { useTileQuery } from '@/hooks/useDashboards';
-import { useCallback, useEffect } from 'react';
+import { useCallback } from 'react';
import { Tile as TileType, TileQueryResponse } from '@/@types/parseable/api/dashboards';
import { sanitiseSqlString } from '@/utils/sanitiseSqlString';
import Table from './Table';
@@ -115,13 +115,23 @@ const Graph = (props: { tile: TileType; data: TileQueryResponse }) => {
const y_keys = _.get(graph_config, 'y_keys', []);
const xUnit = getUnitTypeByKey(x_key, tick_config);
const yUnit = getUnitTypeByKey(_.head(y_keys) || '', tick_config);
- const orientation = _.get(graph_config, 'orientation', 'horizontal');
- const graphBasicType = _.get(graph_config, 'graph_type', 'default')
- const color_config = _.get(props.tile.visualization, 'color_config', [])
+ const orientation = _.get(graph_config, 'orientation', 'horizontal');
+ const graphBasicType = _.get(graph_config, 'graph_type', 'default');
+ const color_config = _.get(props.tile.visualization, 'color_config', []);
return (
- {renderGraph({ queryResponse: data, x_key, y_keys, chart: visualization_type, yUnit, xUnit, orientation, graphBasicType, color_config })}
+ {renderGraph({
+ queryResponse: data,
+ x_key,
+ y_keys,
+ chart: visualization_type,
+ yUnit,
+ xUnit,
+ orientation,
+ graphBasicType,
+ color_config,
+ })}
);
};
@@ -247,23 +257,24 @@ function TileControls(props: { tile: TileType; data: TileQueryResponse }) {
}
const Tile = (props: { id: string }) => {
- // const [showJson, setShowJson] = useState(false);
const [timeRange] = useLogsStore((store) => store.timeRange);
- const [activeDashboard] = useDashboardsStore((store) => store.activeDashboard);
const [tilesData] = useDashboardsStore((store) => store.tilesData);
const tileData = _.get(tilesData, props.id, { records: [], fields: [] });
+ const [activeDashboard] = useDashboardsStore((store) => store.activeDashboard);
const tile = _.chain(activeDashboard)
.get('tiles', [])
.find((tile) => tile.tile_id === props.id)
.value();
- const { fetchTileData, isLoading } = useTileQuery({ tileId: props.id });
+ const shouldNotify = false;
+ const santizedQuery = sanitiseSqlString(tile.query, shouldNotify, 100);
- useEffect(() => {
- const shouldNotify = false;
- const santizedQuery = sanitiseSqlString(tile.query, shouldNotify, 100);
- fetchTileData({ query: santizedQuery, startTime: timeRange.startTime, endTime: timeRange.endTime });
- }, [timeRange.startTime, timeRange.endTime]);
+ const { isLoading } = useTileQuery({
+ tileId: props.id,
+ query: santizedQuery,
+ startTime: timeRange.startTime,
+ endTime: timeRange.endTime,
+ });
// const toggleJsonView = useCallback(() => {
// return setShowJson((prev) => !prev);