diff --git a/packages/dashboard/src/components/csvDownloadButton/emptyDownload.test.tsx b/packages/dashboard/src/components/csvDownloadButton/emptyDownload.test.tsx index cebd3f122..e9f9bc736 100644 --- a/packages/dashboard/src/components/csvDownloadButton/emptyDownload.test.tsx +++ b/packages/dashboard/src/components/csvDownloadButton/emptyDownload.test.tsx @@ -1,22 +1,25 @@ +import { QueryClient } from '@tanstack/react-query'; + +vi.mock('../../data/query-client', () => ({ + queryClient: new QueryClient({ + defaultOptions: { + queries: { + retry: false, + }, + }, + }), +})); + import { fireEvent, render, screen, waitFor } from '@testing-library/react'; import { createMockSiteWiseSDK } from '@iot-app-kit/testing-util'; import { type IoTSiteWiseClient } from '@aws-sdk/client-iotsitewise'; import { CSVDownloadButton } from './index'; -import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { type StyledAssetQuery, type StyledSiteWiseQueryConfig, } from '~/customization/widgets/types'; -const testQueryClient = new QueryClient({ - defaultOptions: { - queries: { - retry: false, - }, - }, -}); - const assetId1 = 'some-asset-id-1'; const propertyId1 = 'some-property-id-1'; const alias1 = 'some-asset-alias-1'; @@ -40,17 +43,15 @@ vi.mock('~/data/listAssetPropertiesMap/fetchListAssetPropertiesMap', () => ({ it('does not render button if query has no content', function () { render( - - - + ); expect(screen.queryByTestId(/csv-download-button/)).toBeNull(); @@ -66,14 +67,12 @@ it('creates a file for download if data is empty', async function () { }, } as StyledSiteWiseQueryConfig; render( - - - + ); const downloadButton = screen.queryByTestId(/csv-download-button/); diff --git a/packages/dashboard/src/components/csvDownloadButton/errorDownload.test.tsx b/packages/dashboard/src/components/csvDownloadButton/errorDownload.test.tsx index 510daf8d5..971d70a13 100644 --- a/packages/dashboard/src/components/csvDownloadButton/errorDownload.test.tsx +++ b/packages/dashboard/src/components/csvDownloadButton/errorDownload.test.tsx @@ -1,21 +1,24 @@ +import { QueryClient } from '@tanstack/react-query'; + +vi.mock('../../data/query-client', () => ({ + queryClient: new QueryClient({ + defaultOptions: { + queries: { + retry: false, + }, + }, + }), +})); + import { fireEvent, render, screen, waitFor } from '@testing-library/react'; import { createMockSiteWiseSDK } from '@iot-app-kit/testing-util'; import { type IoTSiteWiseClient } from '@aws-sdk/client-iotsitewise'; import { CSVDownloadButton } from './index'; -import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { useFetchTimeSeriesData } from '../dashboard/queryContext'; import { type StyledAssetQuery } from '~/customization/widgets/types'; import { type DataStream } from '@iot-app-kit/core'; -const testQueryClient = new QueryClient({ - defaultOptions: { - queries: { - retry: false, - }, - }, -}); - const assetId1 = 'some-asset-id-1'; const propertyId1 = 'some-property-id-1'; const alias1 = 'some-asset-alias-1'; @@ -47,19 +50,17 @@ vi.mock('~/data/listAssetPropertiesMap/fetchListAssetPropertiesMap', () => ({ it('console an errors if data has errors', async function () { render( - - - + ); const consoleErrorSpy = vi.spyOn(console, 'error'); @@ -72,19 +73,17 @@ it('console an errors if data has errors', async function () { it('does not create a file for download if data has errors', async function () { render( - - - + ); const downloadButton = screen.queryByTestId(/csv-download-button/); diff --git a/packages/dashboard/src/components/csvDownloadButton/index.tsx b/packages/dashboard/src/components/csvDownloadButton/index.tsx index c463ed1ad..ecb2778ae 100644 --- a/packages/dashboard/src/components/csvDownloadButton/index.tsx +++ b/packages/dashboard/src/components/csvDownloadButton/index.tsx @@ -9,7 +9,6 @@ import { useFetchTimeSeriesData } from '../dashboard/queryContext'; import { useViewport } from '@iot-app-kit/react-components'; import { assetModelQueryToSiteWiseAssetQuery } from '~/customization/widgets/utils/assetModelQueryToAssetQuery'; import { convertToCSVObject } from './convertToCSVObject'; -import { useQueryClient } from '@tanstack/react-query'; import { fetchListAssetPropertiesMap } from '~/data/listAssetPropertiesMap/fetchListAssetPropertiesMap'; import { BAR_CHART_RESOLUTIONS, @@ -17,6 +16,7 @@ import { EMPTY_DATA, } from './constants'; import { convertViewportToHistoricalViewport } from '../util/dateTimeUtil'; +import { queryClient } from '~/data/query-client'; export const canOnlyDownloadLiveMode: readonly string[] = [ 'table', @@ -48,7 +48,6 @@ export const CSVDownloadButton = ({ fileName?: string; } & ButtonProps) => { const [isDownloading, setIsDownloading] = useState(false); - const queryClient = useQueryClient(); const fetchTimeSeriesData = useFetchTimeSeriesData(); const { viewport: injectedViewport } = useViewport(); diff --git a/packages/dashboard/src/components/csvDownloadButton/succesfulDownload.test.tsx b/packages/dashboard/src/components/csvDownloadButton/succesfulDownload.test.tsx index 531e5c382..a7140d574 100644 --- a/packages/dashboard/src/components/csvDownloadButton/succesfulDownload.test.tsx +++ b/packages/dashboard/src/components/csvDownloadButton/succesfulDownload.test.tsx @@ -1,17 +1,26 @@ +import { QueryClient } from '@tanstack/react-query'; + +vi.mock('../../data/query-client', () => ({ + queryClient: new QueryClient({ + defaultOptions: { + queries: { + retry: false, + }, + }, + }), +})); + import { fireEvent, render, screen, waitFor } from '@testing-library/react'; import { createMockSiteWiseSDK } from '@iot-app-kit/testing-util'; import { type IoTSiteWiseClient } from '@aws-sdk/client-iotsitewise'; import { CSVDownloadButton } from './index'; -import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { type StyledAssetQuery, type StyledSiteWiseQueryConfig, } from '~/customization/widgets/types'; import { type DataStream, type DataType } from '@iot-app-kit/core'; -const testQueryClient = new QueryClient({}); - const assetId1 = 'some-asset-id-1'; const propertyId1 = 'some-property-id-1'; const alias1 = 'some-asset-alias-1'; @@ -44,19 +53,17 @@ vi.mock('~/data/listAssetPropertiesMap/fetchListAssetPropertiesMap', () => ({ it('renders a working download button if query has content', function () { render( - - - + ); const downloadButton = screen.queryByTestId(/csv-download-button/); @@ -74,14 +81,12 @@ it('creates a file for download if query has content', async function () { }, } as StyledSiteWiseQueryConfig; render( - - - + ); const downloadButton = screen.queryByTestId(/csv-download-button/); diff --git a/packages/dashboard/src/components/dashboard/index.tsx b/packages/dashboard/src/components/dashboard/index.tsx index 869fa497f..4d84b8b04 100644 --- a/packages/dashboard/src/components/dashboard/index.tsx +++ b/packages/dashboard/src/components/dashboard/index.tsx @@ -2,7 +2,6 @@ import '@cloudscape-design/global-styles/index.css'; import type { EdgeMode, Viewport } from '@iot-app-kit/core'; import { isEdgeModeEnabled } from '@iot-app-kit/core'; import { TimeSync } from '@iot-app-kit/react-components'; -import { QueryClientProvider } from '@tanstack/react-query'; import { ReactQueryDevtools } from '@tanstack/react-query-devtools'; import debounce from 'lodash-es/debounce'; import { memo, useMemo } from 'react'; @@ -102,42 +101,41 @@ const Dashboard: React.FC = ({ {showFPSMonitor && } - - - + + - } + defaultViewport={dashboardConfiguration.defaultViewport} + currentViewport={currentViewport} + onDashboardConfigurationChange={ + onDashboardConfigurationChange } - group='dashboard-timesync' - onViewportChange={debounceOnViewportChange} - > - } - defaultViewport={dashboardConfiguration.defaultViewport} - currentViewport={currentViewport} - onDashboardConfigurationChange={ - onDashboardConfigurationChange - } - /> - - - - - + /> + + + + diff --git a/packages/dashboard/src/components/dashboard/view.tsx b/packages/dashboard/src/components/dashboard/view.tsx index 4269fcd49..52897ec7d 100644 --- a/packages/dashboard/src/components/dashboard/view.tsx +++ b/packages/dashboard/src/components/dashboard/view.tsx @@ -2,14 +2,12 @@ import '@cloudscape-design/global-styles/index.css'; import type { EdgeMode, Viewport } from '@iot-app-kit/core'; import { isEdgeModeEnabled } from '@iot-app-kit/core'; import { TimeSync } from '@iot-app-kit/react-components'; -import { QueryClientProvider } from '@tanstack/react-query'; import debounce from 'lodash-es/debounce'; import { useMemo } from 'react'; import { DndProvider } from 'react-dnd'; import { TouchBackend } from 'react-dnd-touch-backend'; import { Provider } from 'react-redux'; import { useDashboardPlugins } from '~/customization/api'; -import { queryClient } from '~/data/query-client'; import { configureDashboardStore, toDashboardState } from '~/store'; import type { AssistantConfiguration, @@ -72,35 +70,33 @@ const DashboardView: React.FC = ({ - - + - - - - - + + + diff --git a/packages/dashboard/src/components/queryEditor/iotSiteWiseQueryEditor/assetModelDataStreamExplorer/assetsForAssetModelSelect/useAssetsForAssetModel/useAssetsForAssetModel.ts b/packages/dashboard/src/components/queryEditor/iotSiteWiseQueryEditor/assetModelDataStreamExplorer/assetsForAssetModelSelect/useAssetsForAssetModel/useAssetsForAssetModel.ts index 64eeeda02..59b63a5b1 100644 --- a/packages/dashboard/src/components/queryEditor/iotSiteWiseQueryEditor/assetModelDataStreamExplorer/assetsForAssetModelSelect/useAssetsForAssetModel/useAssetsForAssetModel.ts +++ b/packages/dashboard/src/components/queryEditor/iotSiteWiseQueryEditor/assetModelDataStreamExplorer/assetsForAssetModelSelect/useAssetsForAssetModel/useAssetsForAssetModel.ts @@ -7,6 +7,7 @@ import { createNonNullableList } from '~/helpers/lists/createNonNullableList'; import { AssetsForAssetModelCacheKeyFactory } from './assetsForAssetModelQueryKeyFactory'; import invariant from 'tiny-invariant'; import { GetAssetsForAssetModelRequest } from './getAssetsForAssetModelRequest'; +import { queryClient } from '~/data/query-client'; export interface UseAssetModelsOptions { iotSiteWiseClient: IoTSiteWiseClient; @@ -33,13 +34,16 @@ export function useAssetsForAssetModel({ isError, error, isLoading, - } = useInfiniteQuery({ - enabled: isEnabled(assetModelId), - queryKey: cacheKeyFactory.create(), - queryFn: createQueryFn(iotSiteWiseClient), - getNextPageParam: ({ nextToken }) => nextToken, - initialPageParam: undefined, - }); + } = useInfiniteQuery( + { + enabled: isEnabled(assetModelId), + queryKey: cacheKeyFactory.create(), + queryFn: createQueryFn(iotSiteWiseClient), + getNextPageParam: ({ nextToken }) => nextToken, + initialPageParam: undefined, + }, + queryClient + ); if (fetchAll && hasNextPage) fetchNextPage(); diff --git a/packages/dashboard/src/customization/propertiesSections/propertiesPanel/panel.spec.tsx b/packages/dashboard/src/customization/propertiesSections/propertiesPanel/panel.spec.tsx index 4d31efaff..036c7eeb7 100644 --- a/packages/dashboard/src/customization/propertiesSections/propertiesPanel/panel.spec.tsx +++ b/packages/dashboard/src/customization/propertiesSections/propertiesPanel/panel.spec.tsx @@ -1,3 +1,15 @@ +import { QueryClient } from '@tanstack/react-query'; + +vi.mock('../../data/query-client', () => ({ + queryClient: new QueryClient({ + defaultOptions: { + queries: { + retry: false, + }, + }, + }), +})); + import { IoTSiteWise, type IoTSiteWiseClient, @@ -25,7 +37,6 @@ import { import { mockAssetDescription } from '../../../../testing/mocks/siteWiseSDK'; import { type SiteWiseAssetQuery } from '@iot-app-kit/source-iotsitewise'; import { type QueryWidget } from '~/customization/widgets/types'; -import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { type DashboardIotSiteWiseClients } from '~/types'; import { createMockIoTEventsSDK, @@ -63,14 +74,6 @@ const MockWidget: QueryWidget = { }, }; -const testQueryClient = new QueryClient({ - defaultOptions: { - queries: { - retry: false, - }, - }, -}); - type SetupStoreOptions = { widgets?: DashboardState['dashboardConfiguration']['widgets']; selectedWidgets?: DashboardState['selectedWidgets']; @@ -112,11 +115,9 @@ const renderTestComponentAsync = async ( const element = await waitFor(async () => render( - - - - - + + + ) ); diff --git a/packages/dashboard/src/customization/widgets/table/useTableItems.ts b/packages/dashboard/src/customization/widgets/table/useTableItems.ts index 606788fd9..5da1dc429 100644 --- a/packages/dashboard/src/customization/widgets/table/useTableItems.ts +++ b/packages/dashboard/src/customization/widgets/table/useTableItems.ts @@ -8,6 +8,7 @@ import { useQueries, type QueryFunctionContext } from '@tanstack/react-query'; import invariant from 'tiny-invariant'; import { useClients } from '~/components/dashboard/clientContext'; import { type SiteWiseQueryConfig } from '../types'; +import { queryClient } from '~/data/query-client'; export const useTableItems = ( query: SiteWiseQueryConfig['query'], @@ -18,15 +19,18 @@ export const useTableItems = ( const assets = query?.assets ?? []; const assetIds = assets.map(({ assetId }) => assetId); - const queries = useQueries({ - queries: iotSiteWiseClient - ? assetIds.map((assetId) => ({ - enabled: Boolean(assetId), - queryKey: new AssetCacheKeyFactory(assetId).create(), - queryFn: createQueryFn(iotSiteWiseClient), - })) - : [], - }); + const queries = useQueries( + { + queries: iotSiteWiseClient + ? assetIds.map((assetId) => ({ + enabled: Boolean(assetId), + queryKey: new AssetCacheKeyFactory(assetId).create(), + queryFn: createQueryFn(iotSiteWiseClient), + })) + : [], + }, + queryClient + ); const assetItems = assets.flatMap(({ assetId, properties }) => properties diff --git a/packages/dashboard/src/hooks/useAssetDescriptionQueries.ts b/packages/dashboard/src/hooks/useAssetDescriptionQueries.ts index dbd916f91..e3e3374fb 100644 --- a/packages/dashboard/src/hooks/useAssetDescriptionQueries.ts +++ b/packages/dashboard/src/hooks/useAssetDescriptionQueries.ts @@ -19,6 +19,7 @@ import { createListAssetPropertiesMapCacheKey, } from '~/data/listAssetPropertiesMap/query'; import { selectListAssetPropertiesMap } from '~/data/listAssetPropertiesMap/selectData'; +import { queryClient } from '~/data/query-client'; import { type DashboardState } from '~/store/state'; export type PropertySummary = { @@ -161,7 +162,7 @@ export const useAssetDescriptionMapQuery = ( siteWiseQuery ); - return useQuery(query); + return useQuery(query, queryClient); }; const createListAssetPropertiesMapQuery = ( diff --git a/packages/dashboard/src/hooks/useAssetModel/useAssetModel.ts b/packages/dashboard/src/hooks/useAssetModel/useAssetModel.ts index 564a5265a..938f983eb 100644 --- a/packages/dashboard/src/hooks/useAssetModel/useAssetModel.ts +++ b/packages/dashboard/src/hooks/useAssetModel/useAssetModel.ts @@ -7,6 +7,7 @@ import { listAssetModelPropertiesRequest } from './listAssetModelPropertiesReque import { DescribeAssetModelRequest } from './describeAssetModelRequest'; import { useSelector } from 'react-redux'; import { type DashboardState } from '~/store/state'; +import { queryClient } from '~/data/query-client'; type SingleAssetRequest = { assetModelId?: string; @@ -37,16 +38,19 @@ export function useAssetModel({ assetModelId !== undefined ? [assetModelId] : assetModelIds ?? []; const queries = - useQueries({ - queries: requestIds.map((id) => ({ - // we need assetId and hierarchyId to make a successful request - enabled: isEnabled(id), - queryKey: cacheKeyFactory.create(id), - queryFn: isEdgeModeEnabled - ? createQueryFn(iotSiteWiseClient) - : createModelPropertyQueryFn(iotSiteWiseClient), - })), - }) ?? []; + useQueries( + { + queries: requestIds.map((id) => ({ + // we need assetId and hierarchyId to make a successful request + enabled: isEnabled(id), + queryKey: cacheKeyFactory.create(id), + queryFn: isEdgeModeEnabled + ? createQueryFn(iotSiteWiseClient) + : createModelPropertyQueryFn(iotSiteWiseClient), + })), + }, + queryClient + ) ?? []; const assetModelResponses = createNonNullableList( queries.map(({ data }) => data)