From 75b7712bb360b8d95cd9af296f02d35f3424431e Mon Sep 17 00:00:00 2001 From: Bartosz Prusinowski Date: Fri, 1 Dec 2023 11:24:15 +0100 Subject: [PATCH] fix: Properly handle joinByDimension when setting range filters --- app/configurator/components/filters.tsx | 5 +-- app/configurator/configurator-state.tsx | 51 +++++++++++++++---------- app/graphql/hook-utils.ts | 41 ++++++++++++++++++++ 3 files changed, 73 insertions(+), 24 deletions(-) diff --git a/app/configurator/components/filters.tsx b/app/configurator/components/filters.tsx index f78d17a1c8..acfcac072e 100644 --- a/app/configurator/components/filters.tsx +++ b/app/configurator/components/filters.tsx @@ -903,14 +903,13 @@ export const TimeFilter = (props: TimeFilterProps) => { dispatch({ type: "CHART_CONFIG_FILTER_SET_RANGE", value: { - cubeIri: dimension.cubeIri, - dimensionIri: dimension.iri, + dimension, from, to, }, }); }, - [dispatch, dimension.cubeIri, dimension.iri] + [dispatch, dimension] ); const temporalDimension = diff --git a/app/configurator/configurator-state.tsx b/app/configurator/configurator-state.tsx index 8c570a4936..696f05b0fd 100644 --- a/app/configurator/configurator-state.tsx +++ b/app/configurator/configurator-state.tsx @@ -242,8 +242,7 @@ export type ConfiguratorStateAction = | { type: "CHART_CONFIG_FILTER_SET_RANGE"; value: { - cubeIri: string; - dimensionIri: string; + dimension: Dimension; from: string; to: string; }; @@ -1197,28 +1196,38 @@ const reducer: Reducer = ( case "CHART_CONFIG_FILTER_SET_RANGE": if (draft.state === "CONFIGURING_CHART") { - const { cubeIri, dimensionIri, from, to } = action.value; + const { dimension, from, to } = action.value; const chartConfig = getChartConfig(draft); - const cube = chartConfig.cubes.find((cube) => cube.iri === cubeIri); - - if (cube) { - cube.filters[dimensionIri] = { - type: "range", - from, - to, - }; - - if (chartConfig.interactiveFiltersConfig) { - chartConfig.interactiveFiltersConfig.timeRange = { - componentIri: dimensionIri, - active: chartConfig.interactiveFiltersConfig.timeRange.active, - presets: { - type: "range", - from, - to, - }, + const adjustFilter = (cubeIri: string, dimensionIri: string) => { + const cube = chartConfig.cubes.find((cube) => cube.iri === cubeIri); + + if (cube) { + cube.filters[dimensionIri] = { + type: "range", + from, + to, }; } + }; + + if (dimension.isJoinByDimension) { + for (const { cubeIri, dimensionIri } of dimension.originalIris) { + adjustFilter(cubeIri, dimensionIri); + } + } else { + adjustFilter(dimension.cubeIri, dimension.iri); + } + + if (chartConfig.interactiveFiltersConfig) { + chartConfig.interactiveFiltersConfig.timeRange = { + componentIri: dimension.iri, + active: chartConfig.interactiveFiltersConfig.timeRange.active, + presets: { + type: "range", + from, + to, + }, + }; } } diff --git a/app/graphql/hook-utils.ts b/app/graphql/hook-utils.ts index b5077488c8..e72bf97644 100644 --- a/app/graphql/hook-utils.ts +++ b/app/graphql/hook-utils.ts @@ -2,6 +2,8 @@ import { ascending } from "d3"; import uniqBy from "lodash/uniqBy"; import { OperationResult } from "urql"; +import { Filters } from "@/configurator"; +import { FIELD_VALUE_NONE } from "@/configurator/constants"; import { Dimension, Observation, ObservationValue } from "@/domain/data"; import { DataCubeComponentsQuery, @@ -11,6 +13,45 @@ import { Exact, } from "@/graphql/query-hooks"; +/** Use in both components and observations query, to omit literal `joinBy` filter, + * and use the value of the `joinBy` property of the cube filter instead. + * + * This is required to be able to properly filter the LINDAS cubes, as we use + * `joinBy` dimension on the client side. + */ +export const getJoinedCubeFilters = < + T extends { filters?: Filters | null; joinBy?: string | null } +>( + cubeFilters: T[] +) => { + const joinedCubeFilters: T[] = []; + + for (const cubeFilter of cubeFilters) { + if (cubeFilter.filters && cubeFilter.joinBy) { + const { joinBy: joinByFilter, ...filters } = cubeFilter.filters; + + if ( + joinByFilter && + joinByFilter.type === "single" && + joinByFilter.value !== FIELD_VALUE_NONE + ) { + joinedCubeFilters.push({ + ...cubeFilter, + filters: { + [cubeFilter.joinBy]: { type: "single", value: joinByFilter.value }, + ...filters, + }, + }); + + continue; + } + } + joinedCubeFilters.push(cubeFilter); + } + + return joinedCubeFilters; +}; + /** Use to exclude joinBy dimensions when fetching dimensions, and create * a new joinBy dimension with values from all joinBy dimensions. */