diff --git a/src/explore-education-statistics-admin/src/pages/release/datablocks/components/chart/ChartBoundaryLevelsConfiguration.tsx b/src/explore-education-statistics-admin/src/pages/release/datablocks/components/chart/ChartBoundaryLevelsConfiguration.tsx index 38bb1e42e6b..21b943d54ea 100644 --- a/src/explore-education-statistics-admin/src/pages/release/datablocks/components/chart/ChartBoundaryLevelsConfiguration.tsx +++ b/src/explore-education-statistics-admin/src/pages/release/datablocks/components/chart/ChartBoundaryLevelsConfiguration.tsx @@ -1,34 +1,22 @@ -import ChartBuilderSaveActions from '@admin/pages/release/datablocks/components/chart/ChartBuilderSaveActions'; -import { useChartBuilderFormsContext } from '@admin/pages/release/datablocks/components/chart/contexts/ChartBuilderFormsContext'; import { ChartOptions } from '@admin/pages/release/datablocks/components/chart/reducers/chartBuilderReducer'; -import Effect from '@common/components/Effect'; -import Form from '@common/components/form/Form'; -import FormFieldSelect from '@common/components/form/FormFieldSelect'; -import FormProvider from '@common/components/form/FormProvider'; import { AxisConfiguration, MapConfig, - MapDataSetConfig, } from '@common/modules/charts/types/chart'; import { LegendConfiguration } from '@common/modules/charts/types/legend'; import createDataSetCategories from '@common/modules/charts/util/createDataSetCategories'; +import expandDataSet from '@common/modules/charts/util/expandDataSet'; +import generateDataSetKey from '@common/modules/charts/util/generateDataSetKey'; import getDataSetCategoryConfigs from '@common/modules/charts/util/getDataSetCategoryConfigs'; import { FullTableMeta } from '@common/modules/table-tool/types/fullTable'; import { TableDataResult } from '@common/services/tableBuilderService'; import parseNumber from '@common/utils/number/parseNumber'; -import Yup from '@common/validation/yup'; import { isEqual } from 'lodash'; -import merge from 'lodash/merge'; import React, { ReactNode, useCallback, useMemo } from 'react'; -import { AnyObject, NumberSchema, ObjectSchema } from 'yup'; -import ChartBoundaryLevelsDataSetConfiguration from './ChartBoundaryLevelsDataSetConfiguration'; - -const formId = 'chartBoundaryLevelsConfigurationForm'; - -export interface ChartBoundaryLevelsFormValues { - boundaryLevel?: number; - dataSetConfigs: Omit[]; -} +import ChartBoundaryLevelsForm, { + ChartBoundaryLevelsFormValues, +} from './ChartBoundaryLevelsForm'; +import generateDataSetLabel from './utils/generateDataSetLabel'; interface Props { buttons?: ReactNode; @@ -38,7 +26,7 @@ interface Props { map?: MapConfig; meta: FullTableMeta; options: ChartOptions; - onChange: (values: ChartBoundaryLevelsFormValues) => void; + onChange: (values: Partial) => void; onSubmit: (values: ChartBoundaryLevelsFormValues) => void; } @@ -53,145 +41,93 @@ export default function ChartBoundaryLevelsConfiguration({ onChange, onSubmit, }: Props) { - const { updateForm, submitForms } = useChartBuilderFormsContext(); - const normalizeValues = useCallback( - (values: ChartBoundaryLevelsFormValues): ChartBoundaryLevelsFormValues => { + ( + values: Partial, + ): ChartBoundaryLevelsFormValues => { // Use `merge` as we want to avoid potential undefined // values from overwriting existing values return { boundaryLevel: values.boundaryLevel ? parseNumber(values.boundaryLevel) : undefined, - dataSetConfigs: values.dataSetConfigs.map( - ({ boundaryLevel, dataSet }) => ({ + dataSetConfigs: + values.dataSetConfigs?.map(({ boundaryLevel, dataSet }) => ({ boundaryLevel: parseNumber(boundaryLevel), dataSet, - }), - ), + })) ?? [], }; }, [], ); - const handleChange = useCallback( + const handleSubmit = useCallback( (values: ChartBoundaryLevelsFormValues) => { + onSubmit(normalizeValues(values)); + }, + [onSubmit, normalizeValues], + ); + const handleChange = useCallback( + (values: Partial) => { onChange(normalizeValues(values)); }, - [normalizeValues, onChange], + [onChange, normalizeValues], ); - const validationSchema = useMemo< - ObjectSchema - >(() => { - return Yup.object({ - boundaryLevel: Yup.number() - .transform(value => (Number.isNaN(value) ? undefined : value)) - .nullable() - .oneOf(meta.boundaryLevels.map(level => level.id)) - .required('Choose a boundary level'), - dataSetConfigs: Yup.array() - .of( - Yup.object({ - boundaryLevel: Yup.mixed().test( - 'dataset-boundary-is-number-or-empty', - 'Must be a number or an empty string', - value => !Number.isNaN(value) || value === '', - ) as NumberSchema, - dataSet: Yup.object({ - filters: Yup.array().required(), - }).required(), - }), - ) - .required(), - }); - }, [meta.boundaryLevels]); + const { dataSetConfigs, boundaryLevel } = + useMemo(() => { + const dataSetCategories = createDataSetCategories({ + axisConfiguration: { + ...axisMajor, + groupBy: 'locations', + }, + data, + meta, + }); - const initialValues = useMemo(() => { - const dataSetCategories = createDataSetCategories({ - axisConfiguration: { - ...axisMajor, - groupBy: 'locations', - }, - data, - meta, - }); + const dataSetCategoryConfigs = getDataSetCategoryConfigs({ + dataSetCategories, + legendItems: legend.items, + meta, + deprecatedDataClassification: options.dataClassification, + deprecatedDataGroups: options.dataGroups, + }); - const dataSetCategoryConfigs = getDataSetCategoryConfigs({ - dataSetCategories, - legendItems: legend.items, - meta, - deprecatedDataClassification: options.dataClassification, - deprecatedDataGroups: options.dataGroups, - }); - - return { - boundaryLevel: options.boundaryLevel, - dataSetConfigs: dataSetCategoryConfigs.map(({ rawDataSet }) => ({ - dataSet: rawDataSet, - boundaryLevel: map?.dataSetConfigs.find(config => - isEqual(config.dataSet, rawDataSet), - )?.boundaryLevel, - })), - }; - }, [axisMajor, data, meta, legend.items, map, options]); + return { + boundaryLevel: options.boundaryLevel, + dataSetConfigs: dataSetCategoryConfigs.map(({ rawDataSet }) => ({ + dataSet: rawDataSet, + boundaryLevel: map?.dataSetConfigs.find(config => + isEqual(config.dataSet, rawDataSet), + )?.boundaryLevel, + })), + }; + }, [axisMajor, data, meta, legend.items, map, options]); - return ( - - enableReinitialize - initialValues={initialValues} - validationSchema={validationSchema} - > - {({ formState, watch }) => { - const values = watch(); - return ( -
- - - - label="Default Boundary level" - hint="Select a version of geographical data to use across any data sets that don't have a specific one set" - name="boundaryLevel" - order={[]} - options={[ - { - label: 'Please select', - value: '', - }, - ...meta.boundaryLevels.map(({ id, label }) => ({ - value: id, - label, - })), - ]} - /> + const mappedDataSetConfigs = useMemo(() => { + return Object.values(dataSetConfigs).map(dataSetConfig => { + const expandedDataSet = expandDataSet(dataSetConfig.dataSet, meta); + const label = generateDataSetLabel(expandedDataSet); + const key = generateDataSetKey(dataSetConfig.dataSet); - + return { + label, + key, + }; + }); + }, [meta, dataSetConfigs]); - { - onSubmit(values); - await submitForms(); - }} - > - {buttons} - - - ); - }} - + return ( + ({ + label, + value: id, + }))} + dataSetRows={mappedDataSetConfigs} + initialValues={{ boundaryLevel, dataSetConfigs }} + onChange={handleChange} + onSubmit={handleSubmit} + /> ); } diff --git a/src/explore-education-statistics-admin/src/pages/release/datablocks/components/chart/ChartBoundaryLevelsDataSetConfiguration.tsx b/src/explore-education-statistics-admin/src/pages/release/datablocks/components/chart/ChartBoundaryLevelsDataSetConfiguration.tsx deleted file mode 100644 index fec347f2a18..00000000000 --- a/src/explore-education-statistics-admin/src/pages/release/datablocks/components/chart/ChartBoundaryLevelsDataSetConfiguration.tsx +++ /dev/null @@ -1,70 +0,0 @@ -import { FormFieldSelect } from '@common/components/form'; -import { MapDataSetConfig } from '@common/modules/charts/types/chart'; -import expandDataSet from '@common/modules/charts/util/expandDataSet'; -import generateDataSetKey from '@common/modules/charts/util/generateDataSetKey'; -import { FullTableMeta } from '@common/modules/table-tool/types/fullTable'; -import React, { useMemo } from 'react'; -import generateDataSetLabel from './utils/generateDataSetLabel'; - -export default function ChartBoundaryLevelsDataSetConfiguration({ - dataSetConfigs, - meta, -}: { - dataSetConfigs: Omit[]; - meta: FullTableMeta; -}) { - const mappedDataSetConfigs = useMemo(() => { - return dataSetConfigs.map(dataSetConfig => { - const expandedDataSet = expandDataSet(dataSetConfig.dataSet, meta); - const dataSetLabel = generateDataSetLabel(expandedDataSet); - const key = generateDataSetKey(dataSetConfig.dataSet); - - return { - dataSetLabel, - key, - }; - }); - }, [meta, dataSetConfigs]); - return ( - <> -

Set boundary levels per data set

- {!!dataSetConfigs && dataSetConfigs.length > 1 && ( - - - - - - - - - {mappedDataSetConfigs.map(({ dataSetLabel, key }, index) => { - return ( - - - - - ); - })} - -
Data setBoundary
{dataSetLabel} - ({ - value: Number(id), - label, - })), - ]} - /> -
- )} - - ); -} diff --git a/src/explore-education-statistics-admin/src/pages/release/datablocks/components/chart/ChartBoundaryLevelsForm.tsx b/src/explore-education-statistics-admin/src/pages/release/datablocks/components/chart/ChartBoundaryLevelsForm.tsx new file mode 100644 index 00000000000..f5e49aa6d3b --- /dev/null +++ b/src/explore-education-statistics-admin/src/pages/release/datablocks/components/chart/ChartBoundaryLevelsForm.tsx @@ -0,0 +1,153 @@ +import ChartBuilderSaveActions from '@admin/pages/release/datablocks/components/chart/ChartBuilderSaveActions'; +import { useChartBuilderFormsContext } from '@admin/pages/release/datablocks/components/chart/contexts/ChartBuilderFormsContext'; +import Effect from '@common/components/Effect'; +import Form from '@common/components/form/Form'; +import FormFieldSelect from '@common/components/form/FormFieldSelect'; +import FormProvider from '@common/components/form/FormProvider'; +import { MapDataSetConfig } from '@common/modules/charts/types/chart'; +import Yup from '@common/validation/yup'; +import React, { ReactNode, useMemo } from 'react'; +import { AnyObject, NumberSchema, ObjectSchema } from 'yup'; + +const formId = 'chartBoundaryLevelsConfigurationForm'; + +export interface ChartBoundaryLevelsFormValues { + boundaryLevel?: number; + dataSetConfigs: Omit[]; +} + +interface Props { + buttons?: ReactNode; + boundaryLevelOptions: { label: string; value: number }[]; + initialValues?: ChartBoundaryLevelsFormValues; + dataSetRows: { key: string; label: string }[]; + onChange: (values: Partial) => void; + onSubmit: (values: ChartBoundaryLevelsFormValues) => void; +} + +export default function ChartBoundaryLevelsForm({ + buttons, + boundaryLevelOptions, + dataSetRows, + initialValues, + onChange, + onSubmit, +}: Props) { + const { updateForm, submitForms } = useChartBuilderFormsContext(); + + const validationSchema = useMemo< + ObjectSchema + >(() => { + return Yup.object({ + boundaryLevel: Yup.number() + .transform(value => (Number.isNaN(value) ? undefined : value)) + .nullable() + .oneOf(boundaryLevelOptions.map(({ value }) => value)) + .required('Choose a boundary level'), + dataSetConfigs: Yup.array() + .of( + Yup.object({ + boundaryLevel: Yup.mixed().test( + 'dataset-boundary-is-number-or-empty', + 'Must be a number or an empty string', + value => !Number.isNaN(value) || value === '', + ) as NumberSchema, + dataSet: Yup.object({ + filters: Yup.array().required(), + }).required(), + }), + ) + .required(), + }); + }, [boundaryLevelOptions]); + + return ( + + {({ formState, watch }) => { + const values = watch(); + return ( + + id={formId} + onSubmit={onSubmit} + onChange={onChange} + > + + + label="Default boundary level" + hint="Select a version of geographical data to use across any data sets that don't have a specific one set" + name="boundaryLevel" + order={[]} + options={[ + { + label: 'Please select', + value: '', + }, + ...boundaryLevelOptions, + ]} + /> + {dataSetRows.length > 1 && ( + <> +

Set boundary levels per data set

+ + + + + + + + + {dataSetRows.map(({ key, label }, index) => { + return ( + + + + + ); + })} + +
Data setBoundary
{label} + +
+ + )} + + { + onSubmit(values); + await submitForms(); + }} + > + {buttons} + + + ); + }} +
+ ); +} diff --git a/src/explore-education-statistics-admin/src/pages/release/datablocks/components/chart/__tests__/ChartBoundaryLevelsConfiguration.test.tsx b/src/explore-education-statistics-admin/src/pages/release/datablocks/components/chart/__tests__/ChartBoundaryLevelsConfiguration.test.tsx index d53b67f6cd9..c4f51aab1d1 100644 --- a/src/explore-education-statistics-admin/src/pages/release/datablocks/components/chart/__tests__/ChartBoundaryLevelsConfiguration.test.tsx +++ b/src/explore-education-statistics-admin/src/pages/release/datablocks/components/chart/__tests__/ChartBoundaryLevelsConfiguration.test.tsx @@ -10,6 +10,8 @@ import baseRender from '@common-test/render'; import { screen, waitFor, within } from '@testing-library/react'; import noop from 'lodash/noop'; import React, { ReactElement } from 'react'; +import { DataSet } from '@common/modules/charts/types/dataSet'; +import { ChartBoundaryLevelsFormValues } from '../ChartBoundaryLevelsForm'; describe('ChartBoundaryLevelsConfiguration', () => { const testTable = testFullTable; @@ -51,6 +53,18 @@ describe('ChartBoundaryLevelsConfiguration', () => { title: 'Boundary levels configuration', }, }; + const testDataSets: DataSet[] = [ + { + filters: ['ethnicity-major-chinese', 'state-funded-primary'], + indicator: 'authorised-absence-sessions', + timePeriod: '2014_AY', + }, + { + filters: ['ethnicity-major-chinese', 'state-funded-primary'], + indicator: 'authorised-absence-sessions', + timePeriod: '2015_AY', + }, + ]; function render(element: ReactElement) { return baseRender( @@ -64,13 +78,39 @@ describe('ChartBoundaryLevelsConfiguration', () => { ); } + test('renders without table one or less dataset is included', () => { + render( + , + ); + expect( + screen.queryByText('Set boundary levels per data set'), + ).not.toBeInTheDocument(); + }); + test('renders correctly without initial values', () => { render( { />, ); - expect(screen.getByLabelText('Boundary level')).not.toHaveValue(); + expect(screen.getByLabelText('Default boundary level')).not.toHaveValue(); const boundaryLevels = within( - screen.getByLabelText('Boundary level'), + screen.getByLabelText('Default boundary level'), ).getAllByRole('option'); expect(boundaryLevels).toHaveLength(4); @@ -100,6 +140,19 @@ describe('ChartBoundaryLevelsConfiguration', () => { expect(boundaryLevels[2]).toHaveValue('2'); expect(boundaryLevels[3]).toHaveTextContent('Boundary level 3'); expect(boundaryLevels[3]).toHaveValue('3'); + + expect( + screen.getByText('Set boundary levels per data set'), + ).toBeInTheDocument(); + + const rows = screen.getAllByRole('row'); + expect(rows).toHaveLength(3); + + const row1Cells = within(rows[1]).getAllByRole('cell'); + expect(row1Cells[0]).toHaveTextContent( + 'Number of authorised absence sessions (Ethnicity Major Chinese, State-funded primary, All locations, 2014/15)', + ); + expect(row1Cells[1]).toHaveTextContent('Use default'); }); test('renders correctly with initial values', () => { @@ -108,7 +161,7 @@ describe('ChartBoundaryLevelsConfiguration', () => { data={testTable.results} meta={testMeta} axisMajor={{ - dataSets: [], + dataSets: testDataSets, groupBy: 'locations', referenceLines: [], type: 'major', @@ -122,12 +175,24 @@ describe('ChartBoundaryLevelsConfiguration', () => { ...testDefaultChartOptions, boundaryLevel: 2, }} + map={{ + dataSetConfigs: testDataSets.map(dataSet => ({ + dataSet, + dataGrouping: { type: 'Custom', customGroups: [] }, + boundaryLevel: 3, + })), + }} onChange={noop} onSubmit={noop} />, ); - expect(screen.getByLabelText('Boundary level')).toHaveValue('2'); + expect(screen.getByLabelText('Default boundary level')).toHaveValue('2'); + const rows = screen.getAllByRole('row'); + expect(rows).toHaveLength(3); + + expect(within(rows[1]).getByRole('combobox')).toHaveValue('3'); + expect(within(rows[2]).getByRole('combobox')).toHaveValue('3'); }); test('calls `onChange` handler when form values change', async () => { @@ -138,7 +203,7 @@ describe('ChartBoundaryLevelsConfiguration', () => { data={testTable.results} meta={testMeta} axisMajor={{ - dataSets: [], + dataSets: testDataSets, groupBy: 'locations', referenceLines: [], type: 'major', @@ -154,11 +219,24 @@ describe('ChartBoundaryLevelsConfiguration', () => { />, ); - await user.selectOptions(screen.getByLabelText('Boundary level'), ['2']); + await user.selectOptions(screen.getByLabelText('Default boundary level'), [ + '2', + ]); + + expect(handleChange).toHaveBeenCalledWith<[ChartBoundaryLevelsFormValues]>({ + boundaryLevel: 2, + dataSetConfigs: testDataSets.map(dataSet => ({ dataSet })), + }); + + const rows = screen.getAllByRole('row'); + await user.selectOptions(within(rows[1]).getByRole('combobox'), ['2']); - expect(handleChange).toHaveBeenCalledWith<[ChartOptions]>({ - ...testDefaultChartOptions, + expect(handleChange).toHaveBeenCalledWith<[ChartBoundaryLevelsFormValues]>({ boundaryLevel: 2, + dataSetConfigs: [ + { dataSet: testDataSets[0], boundaryLevel: 2 }, + { dataSet: testDataSets[1] }, + ], }); }); @@ -168,7 +246,7 @@ describe('ChartBoundaryLevelsConfiguration', () => { data={testTable.results} meta={testMeta} axisMajor={{ - dataSets: [], + dataSets: testDataSets, groupBy: 'locations', referenceLines: [], type: 'major', @@ -208,7 +286,7 @@ describe('ChartBoundaryLevelsConfiguration', () => { data={testTable.results} meta={testMeta} axisMajor={{ - dataSets: [], + dataSets: testDataSets, groupBy: 'locations', referenceLines: [], type: 'major', @@ -224,7 +302,9 @@ describe('ChartBoundaryLevelsConfiguration', () => { />, ); - await user.selectOptions(screen.getByLabelText('Boundary level'), ['2']); + await user.selectOptions(screen.getByLabelText('Default boundary level'), [ + '2', + ]); expect(handleSubmit).not.toHaveBeenCalled(); @@ -233,9 +313,11 @@ describe('ChartBoundaryLevelsConfiguration', () => { ); await waitFor(() => { - expect(handleSubmit).toHaveBeenCalledWith<[ChartOptions]>({ - ...testDefaultChartOptions, + expect(handleSubmit).toHaveBeenCalledWith< + [ChartBoundaryLevelsFormValues] + >({ boundaryLevel: 2, + dataSetConfigs: testDataSets.map(dataSet => ({ dataSet })), }); }); }); @@ -248,7 +330,7 @@ describe('ChartBoundaryLevelsConfiguration', () => { data={testTable.results} meta={testMeta} axisMajor={{ - dataSets: [], + dataSets: testDataSets, groupBy: 'locations', referenceLines: [], type: 'major', @@ -274,9 +356,11 @@ describe('ChartBoundaryLevelsConfiguration', () => { ); await waitFor(() => { - expect(handleSubmit).toHaveBeenCalledWith<[ChartOptions]>({ - ...testDefaultChartOptions, + expect(handleSubmit).toHaveBeenCalledWith< + [ChartBoundaryLevelsFormValues] + >({ boundaryLevel: 3, + dataSetConfigs: testDataSets.map(dataSet => ({ dataSet })), }); }); }); diff --git a/src/explore-education-statistics-admin/src/pages/release/datablocks/components/chart/reducers/chartBuilderReducer.ts b/src/explore-education-statistics-admin/src/pages/release/datablocks/components/chart/reducers/chartBuilderReducer.ts index 48d8786b6a3..d87ac4a4b1d 100644 --- a/src/explore-education-statistics-admin/src/pages/release/datablocks/components/chart/reducers/chartBuilderReducer.ts +++ b/src/explore-education-statistics-admin/src/pages/release/datablocks/components/chart/reducers/chartBuilderReducer.ts @@ -246,7 +246,6 @@ export const chartBuilderReducer: Reducer< isEqual(existingDataSet, dataSet), )! ?? {}; - if (boundaryLevel) console.log({ boundaryLevel }); return { dataSet, boundaryLevel, dataGrouping }; }, ); diff --git a/src/explore-education-statistics-common/src/components/form/Form.tsx b/src/explore-education-statistics-common/src/components/form/Form.tsx index 83124b5294e..07aa9424a8e 100644 --- a/src/explore-education-statistics-common/src/components/form/Form.tsx +++ b/src/explore-education-statistics-common/src/components/form/Form.tsx @@ -5,6 +5,7 @@ import { FormIdContextProvider } from '@common/components/form/contexts/FormIdCo import createErrorHelper from '@common/components/form/validation/createErrorHelper'; import useMountedRef from '@common/hooks/useMountedRef'; import useToggle from '@common/hooks/useToggle'; +import { isEqual } from 'lodash'; import camelCase from 'lodash/camelCase'; import React, { FormEvent, @@ -24,6 +25,7 @@ interface Props { submitId?: string; showErrorSummary?: boolean; visuallyHiddenErrorSummary?: boolean; + onChange?: (values: Partial) => Promise | void; onSubmit: (values: TFormValues) => Promise | void; } @@ -52,6 +54,7 @@ export default function Form({ submitId = `${id}-submit`, showErrorSummary = true, visuallyHiddenErrorSummary = false, + onChange, onSubmit, }: Props) { const isMounted = useMountedRef(); @@ -67,10 +70,16 @@ export default function Form({ handleSubmit: submit, } = useFormContext(); - const values = useWatch(); + const values = useWatch(); const previousValues = useRef(values); const previousSubmitCount = useRef(submitCount); + useEffect(() => { + if (!isEqual(previousValues.current, values)) { + onChange?.(values); + } + }, [previousValues, values, onChange]); + const { getAllErrors } = createErrorHelper({ errors, initialTouched, diff --git a/src/explore-education-statistics-common/src/modules/charts/components/MapBlock.tsx b/src/explore-education-statistics-common/src/modules/charts/components/MapBlock.tsx index c35985fa1fe..da74756a818 100644 --- a/src/explore-education-statistics-common/src/modules/charts/components/MapBlock.tsx +++ b/src/explore-education-statistics-common/src/modules/charts/components/MapBlock.tsx @@ -1,14 +1,14 @@ import { SelectOption } from '@common/components/form/FormSelect'; import styles from '@common/modules/charts/components/MapBlock.module.scss'; -import createMapDataSetCategories, { - MapDataSetCategory, -} from '@common/modules/charts/components/utils/createMapDataSetCategories'; -import { LegendDataGroup } from '@common/modules/charts/components/utils/generateLegendDataGroups'; -import MapGeoJSON from '@common/modules/charts/components/MapGeoJSON'; import MapControls from '@common/modules/charts/components/MapControls'; +import MapGeoJSON from '@common/modules/charts/components/MapGeoJSON'; import MapLegend from '@common/modules/charts/components/MapLegend'; import MapSelectedItem from '@common/modules/charts/components/MapSelectedItem'; +import createMapDataSetCategories, { + MapDataSetCategory, +} from '@common/modules/charts/components/utils/createMapDataSetCategories'; import generateFeaturesAndDataGroups from '@common/modules/charts/components/utils/generateFeaturesAndDataGroups'; +import { LegendDataGroup } from '@common/modules/charts/components/utils/generateLegendDataGroups'; import { AxisConfiguration, ChartDefinition, @@ -23,11 +23,11 @@ import getDataSetCategoryConfigs, { } from '@common/modules/charts/util/getDataSetCategoryConfigs'; import { GeoJsonFeatureProperties } from '@common/services/tableBuilderService'; import { Dictionary } from '@common/types'; +import naturalOrderBy from '@common/utils/array/naturalOrderBy'; import classNames from 'classnames'; import { Feature, FeatureCollection, Geometry } from 'geojson'; import { Layer, Path, Polyline } from 'leaflet'; import keyBy from 'lodash/keyBy'; -import orderBy from 'lodash/orderBy'; import React, { useEffect, useMemo, useState } from 'react'; import { MapContainer } from 'react-leaflet'; @@ -160,7 +160,7 @@ export default function MapBlock({ ); const dataSetOptions = useMemo(() => { - return orderBy( + return naturalOrderBy( Object.values(dataSetCategoryConfigs).map(dataSet => ({ label: dataSet.config.label, value: dataSet.dataKey,