Skip to content

Commit

Permalink
EES-5542 implement useDataBlock
Browse files Browse the repository at this point in the history
  • Loading branch information
bennettstuart committed Jan 28, 2025
1 parent 8283f09 commit 9f7d803
Show file tree
Hide file tree
Showing 17 changed files with 314 additions and 406 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ describe('ReleaseDataBlockEditPage', () => {

tableBuilderService.getSubjectMeta.mockResolvedValue(testSubjectMeta);
tableBuilderService.getTableData.mockResolvedValue(testTableData);
tableBuilderService.getDataBlockTableData.mockResolvedValue(testTableData);

dataBlockService.getDataBlock.mockResolvedValue(testDataBlock);
dataBlockService.listDataBlocks.mockResolvedValue(testDataBlockSummaries);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,15 @@
import useGetChartFile from '@admin/hooks/useGetChartFile';
import TableTabSection from '@admin/pages/release/datablocks/components/TableTabSection';
import { ReleaseDataBlock } from '@admin/services/dataBlockService';
import ErrorBoundary from '@common/components/ErrorBoundary';
import LoadingSpinner from '@common/components/LoadingSpinner';
import Tabs from '@common/components/Tabs';
import TabsSection from '@common/components/TabsSection';
import WarningMessage from '@common/components/WarningMessage';
import useAsyncRetry from '@common/hooks/useAsyncRetry';
import ChartRenderer, {
ChartRendererProps,
} from '@common/modules/charts/components/ChartRenderer';
import getMapInitialBoundaryLevel from '@common/modules/charts/components/utils/getMapInitialBoundaryLevel';
import mapFullTable from '@common/modules/table-tool/utils/mapFullTable';
import ChartRenderer from '@common/modules/charts/components/ChartRenderer';
import useDataBlock from '@common/modules/find-statistics/hooks/useDataBlock';
import mapTableHeadersConfig from '@common/modules/table-tool/utils/mapTableHeadersConfig';
import tableBuilderQueries from '@common/queries/tableBuilderQueries';
import tableBuilderService from '@common/services/tableBuilderService';
import { MapChart } from '@common/services/types/blocks';
import { useQuery, useQueryClient } from '@tanstack/react-query';
import React, { useMemo, useState } from 'react';
import React, { useMemo } from 'react';

interface Props {
releaseId: string;
Expand All @@ -26,162 +20,78 @@ const testId = (dataBlock: ReleaseDataBlock) =>
`Data block - ${dataBlock.name}`;

const DataBlockPageReadOnlyTabs = ({ releaseId, dataBlock }: Props) => {
const isMapChart = dataBlock.charts[0]?.type === 'map';
const queryClient = useQueryClient();
const [selectedBoundaryLevel, setSelectedBoundaryLevel] = useState(
isMapChart
? getMapInitialBoundaryLevel(dataBlock.charts[0] as MapChart)
: undefined,
);

const getDataBlockGeoJsonQuery = tableBuilderQueries.getDataBlockGeoJson(
releaseId,
dataBlock.dataBlockParentId,
selectedBoundaryLevel ?? -1,
);

const getChartFile = useGetChartFile(releaseId);
const {
data: locationGeoJson,
error: geoJsonError,
isFetching,
} = useQuery({
queryKey: getDataBlockGeoJsonQuery.queryKey,
queryFn: selectedBoundaryLevel
? getDataBlockGeoJsonQuery.queryFn
: () => Promise.resolve({}),
staleTime: Infinity,
cacheTime: Infinity,
keepPreviousData: true,
refetchOnWindowFocus: false,
refetchOnMount: false,
chart,
isTableDataLoading,
isTableDataError,
fullTable,
isGeoJsonError,
isGeoJsonInitialLoading,
} = useDataBlock({
dataBlock,
releaseId,
getInfographic: getChartFile,
});

const { value: tableData, isLoading } = useAsyncRetry(
async () =>
tableBuilderService.getTableData(
dataBlock.query,
releaseId,
isMapChart
? (dataBlock.charts[0] as MapChart).boundaryLevel
: undefined,
),
[releaseId, dataBlock],
);

const { fullTable, tableHeaders } = useMemo(() => {
if (!tableData || isFetching) {
return {};
}

const table = mapFullTable({
...tableData,
subjectMeta: {
...tableData.subjectMeta,
locations:
selectedBoundaryLevel && locationGeoJson
? locationGeoJson
: tableData.subjectMeta.locations,
},
});
const tableHeaders = useMemo(() => {
if (!fullTable) return undefined;
return mapTableHeadersConfig(dataBlock.table.tableHeaders, fullTable);
}, [dataBlock, fullTable]);

return {
fullTable: table,
tableHeaders: mapTableHeadersConfig(dataBlock.table.tableHeaders, table),
};
}, [
tableData,
locationGeoJson,
isFetching,
dataBlock.table.tableHeaders,
selectedBoundaryLevel,
]);
if (isTableDataError)
return (
<WarningMessage>
There was a problem loading the data block
</WarningMessage>
);

return (
<LoadingSpinner text="Loading data block" loading={isLoading || isFetching}>
{!!geoJsonError && (
<WarningMessage>Could not load content</WarningMessage>
)}

{fullTable && !geoJsonError ? (
<Tabs id="dataBlockTabs">
<TabsSection title="Table" key="table" id="dataBlockTabs-table">
<TableTabSection
dataBlock={dataBlock}
table={fullTable}
tableHeaders={tableHeaders}
/>
</TabsSection>
{dataBlock.charts.length > 0 && [
<TabsSection
title="Chart"
key="chart"
id="dataBlockTabs-chart"
testId={`${testId(dataBlock)}-chart-tab`}
>
<LoadingSpinner
text="Loading data block"
loading={isTableDataLoading || isGeoJsonInitialLoading}
>
<Tabs id="dataBlockTabs">
{fullTable &&
tableHeaders && [
<TabsSection title="Table" key="table" id="dataBlockTabs-table">
<TableTabSection
dataBlock={dataBlock}
table={fullTable}
tableHeaders={tableHeaders}
/>
</TabsSection>,
]}
{!!dataBlock.charts.length && [
<TabsSection
title="Chart"
key="chart"
id="dataBlockTabs-chart"
testId={`${testId(dataBlock)}-chart-tab`}
>
{fullTable && (
<div className="govuk-width-container">
{dataBlock.charts.map((chart, index) => {
const key = index;

const rendererProps: Omit<ChartRendererProps, 'chart'> = {
id: `dataBlockTabs-chart-${index}`,
source: dataBlock?.source,
};

if (chart.type === 'map') {
return (
<ChartRenderer
{...rendererProps}
key={key}
chart={{
...chart,
data: fullTable.results,
meta: fullTable.subjectMeta,
onBoundaryLevelChange: async boundaryLevel => {
const { queryKey, queryFn } =
tableBuilderQueries.getDataBlockGeoJson(
releaseId,
dataBlock.dataBlockParentId,
boundaryLevel,
);
const existingGeoJson =
queryClient.getQueryData(queryKey);

if (!existingGeoJson) {
await queryClient.fetchQuery({
queryKey,
queryFn,
staleTime: Infinity,
cacheTime: Infinity,
});
}
setSelectedBoundaryLevel(boundaryLevel);
},
}}
/>
);
{!!isGeoJsonError && (
<WarningMessage>Could not load chart</WarningMessage>
)}
<ErrorBoundary
fallback={
<WarningMessage>Could not load chart</WarningMessage>
}

return (
>
{chart && (
<ChartRenderer
{...rendererProps}
chart={{
...chart,
data: fullTable.results,
meta: fullTable.subjectMeta,
}}
key={key}
id="dataBlockTabs-chart"
source={dataBlock.source}
chart={chart}
/>
);
})}
)}
</ErrorBoundary>
</div>
</TabsSection>,
]}
</Tabs>
) : (
<WarningMessage>
There was a problem loading the data block
</WarningMessage>
)}
)}
</TabsSection>,
]}
</Tabs>
</LoadingSpinner>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import Tabs from '@common/components/Tabs';
import TabsSection from '@common/components/TabsSection';
import useDebouncedCallback from '@common/hooks/useDebouncedCallback';
import useToggle from '@common/hooks/useToggle';
import { RenderrableChart } from '@common/modules/charts/components/ChartRenderer';
import { RenderableChart } from '@common/modules/charts/components/ChartRenderer';
import {
horizontalBarBlockDefinition,
HorizontalBarProps,
Expand Down Expand Up @@ -60,7 +60,7 @@ const chartDefinitions: ChartDefinition[] = [
mapBlockDefinition,
];

type ChartBuilderChartProps = RenderrableChart & {
type ChartBuilderChartProps = RenderableChart & {
file?: File;
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@ import styles from '@admin/pages/release/datablocks/components/chart/ChartBuilde
import Details from '@common/components/Details';
import LoadingSpinner from '@common/components/LoadingSpinner';
import ChartRenderer, {
RenderrableChart,
RenderableChart,
} from '@common/modules/charts/components/ChartRenderer';
import isChartRenderable, {
getChartPreviewText,
} from '@common/modules/charts/util/isChartRenderable';
import React, { useRef } from 'react';

interface Props {
chart?: RenderrableChart;
chart?: RenderableChart;
loading: boolean;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import ChartBuilderPreview from '@admin/pages/release/datablocks/components/chart/ChartBuilderPreview';
import { testChartTableData } from '@common/modules/charts/components/__tests__/__data__/testChartData';
import { RenderrableChart } from '@common/modules/charts/components/ChartRenderer';
import { RenderableChart } from '@common/modules/charts/components/ChartRenderer';
import { AxisConfiguration } from '@common/modules/charts/types/chart';
import { DataSet } from '@common/modules/charts/types/dataSet';
import mapFullTable from '@common/modules/table-tool/utils/mapFullTable';
Expand Down Expand Up @@ -37,7 +37,7 @@ describe('ChartBuilderPreview', () => {

const testFullTableMeta = mapFullTable(testChartTableData);

const testInfographicChart: RenderrableChart = {
const testInfographicChart: RenderableChart = {
type: 'infographic',
fileId: '1',
data: [],
Expand All @@ -47,7 +47,7 @@ describe('ChartBuilderPreview', () => {
axes: {},
};

const testLineChart: RenderrableChart = {
const testLineChart: RenderableChart = {
type: 'line',
data: [],
meta: testFullTableMeta.subjectMeta,
Expand All @@ -62,7 +62,7 @@ describe('ChartBuilderPreview', () => {
},
};

const testVerticalBarChart: RenderrableChart = {
const testVerticalBarChart: RenderableChart = {
type: 'verticalbar',
data: [],
meta: testFullTableMeta.subjectMeta,
Expand All @@ -77,7 +77,7 @@ describe('ChartBuilderPreview', () => {
},
};

const testHorizontalBarChart: RenderrableChart = {
const testHorizontalBarChart: RenderableChart = {
type: 'horizontalbar',
data: [],
meta: testFullTableMeta.subjectMeta,
Expand All @@ -92,7 +92,7 @@ describe('ChartBuilderPreview', () => {
},
};

const testMapChart: RenderrableChart = {
const testMapChart: RenderableChart = {
type: 'map',
onBoundaryLevelChange: async () => {},
data: [],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {
} from '@common/modules/charts/types/chart';
import { DataSet } from '@common/modules/charts/types/dataSet';
import { LegendConfiguration } from '@common/modules/charts/types/legend';
import { Chart } from '@common/services/types/blocks';
import { Chart, LineChart } from '@common/services/types/blocks';
import { renderHook } from '@testing-library/react';
import { produce } from 'immer';
import { testFullTable } from '../../__tests__/__data__/testTableData';
Expand Down Expand Up @@ -958,8 +958,6 @@ describe('chartBuilderReducer', () => {
});

test('has default `axes.minor` state if initial configuration is missing it', () => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
const initialConfiguration: Chart = {
type: 'line',
legend: {
Expand All @@ -979,7 +977,7 @@ describe('chartBuilderReducer', () => {
referenceLines: [],
visible: true,
},
},
} as never as LineChart['axes'],
height: 300,
title: '',
alt: '',
Expand Down Expand Up @@ -1165,7 +1163,6 @@ describe('chartBuilderReducer', () => {
referenceLines: [],
},
},

height: 300,
title: 'Chart title',
alt: '',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,9 +170,7 @@ const getInitialState = ({
(axisDefinition: ChartDefinitionAxis, axisType: AxisType) =>
updateAxis(
axisDefinition,
(initialAxes as { [key in AxisType]?: AxisConfiguration })?.[
axisType
] ?? {},
(initialAxes as AxesConfiguration)?.[axisType] ?? {},
),
);

Expand Down
Loading

0 comments on commit 9f7d803

Please sign in to comment.