Skip to content

Commit

Permalink
Merge pull request #1598 from visualize-admin/fix/shared-filter-confi…
Browse files Browse the repository at this point in the history
…gurator

Shared filter configurator filter
  • Loading branch information
ptbrowne authored Jun 12, 2024
2 parents 2e09097 + d799ab3 commit 1fe3762
Show file tree
Hide file tree
Showing 8 changed files with 198 additions and 86 deletions.
31 changes: 8 additions & 23 deletions app/components/dashboard-interactive-filters.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import {
} from "@mui/material";
import { Theme } from "@mui/material/styles";
import { makeStyles } from "@mui/styles";
import uniqBy from "lodash/uniqBy";
import { useEffect, useMemo, useState } from "react";

import {
Expand All @@ -19,8 +18,8 @@ import {
timeUnitToParser,
} from "@/configurator/components/ui-helpers";
import { canDimensionBeTimeFiltered } from "@/domain/data";
import { useDataCubesComponentsQuery } from "@/graphql/hooks";
import { DataCubeComponentFilter, TimeUnit } from "@/graphql/query-hooks";
import { useConfigsCubeComponents } from "@/graphql/hooks";
import { TimeUnit } from "@/graphql/query-hooks";
import { useLocale } from "@/src";
import {
SharedFilter,
Expand Down Expand Up @@ -90,35 +89,21 @@ const DashboardTimeRangeSlider = ({
const dashboardInteractiveFilters = useDashboardInteractiveFilters();

const [state] = useConfiguratorState(hasChartConfigs);
const source = state.dataSource;
const locale = useLocale();

const cubeFilters = useMemo(() => {
return uniqBy(
state.chartConfigs.flatMap((chartConfig) =>
chartConfig.cubes.map((x: DataCubeComponentFilter) => ({
iri: x.iri,
componentIris: [filter.componentIri],
joinBy: x.joinBy,
}))
),
(x) => x.iri
);
}, [filter.componentIri, state.chartConfigs]);

const [data] = useDataCubesComponentsQuery({
const [data] = useConfigsCubeComponents({
variables: {
sourceUrl: source.url,
sourceType: source.type,
cubeFilters,
state,
locale,
},
});

const timeUnit = useMemo(() => {
const dim = data?.data?.dataCubesComponents?.dimensions?.[0];
const dim = data?.data?.dataCubesComponents?.dimensions?.find(
(d) => d.iri === filter.componentIri
);
return canDimensionBeTimeFiltered(dim) ? dim.timeUnit : undefined;
}, [data?.data?.dataCubesComponents?.dimensions]);
}, [data?.data?.dataCubesComponents?.dimensions, filter.componentIri]);

const presets = filter.presets;
assert(
Expand Down
54 changes: 22 additions & 32 deletions app/configurator/components/layout-configurator.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Trans, t } from "@lingui/macro";
import { t, Trans } from "@lingui/macro";
import {
Box,
FormControlLabel,
Expand All @@ -11,8 +11,7 @@ import {
import capitalize from "lodash/capitalize";
import keyBy from "lodash/keyBy";
import omit from "lodash/omit";
import uniqBy from "lodash/uniqBy";
import { useMemo } from "react";
import { Fragment, useMemo } from "react";

import { DataFilterGenericDimensionProps } from "@/charts/shared/chart-data-filters";
import { Select } from "@/components/form";
Expand All @@ -25,9 +24,9 @@ import {
SubsectionTitle,
} from "@/configurator/components/chart-controls/section";
import {
canRenderDatePickerField,
DatePickerField,
DatePickerFieldProps,
canRenderDatePickerField,
} from "@/configurator/components/field-date-picker";
import { IconButton } from "@/configurator/components/icon-button";
import {
Expand All @@ -39,15 +38,15 @@ import {
useConfiguratorState,
} from "@/configurator/configurator-state";
import {
canDimensionBeTimeFiltered,
Dimension,
isJoinByComponent,
TemporalDimension,
TemporalEntityDimension,
canDimensionBeTimeFiltered,
isJoinByComponent,
} from "@/domain/data";
import { useFlag } from "@/flags";
import { useTimeFormatLocale, useTimeFormatUnit } from "@/formatters";
import { useDataCubesComponentsQuery } from "@/graphql/hooks";
import { useConfigsCubeComponents } from "@/graphql/hooks";
import { useLocale } from "@/src";
import {
SharedFilter,
Expand Down Expand Up @@ -114,31 +113,18 @@ const LayoutSharedFiltersConfigurator = () => {
const { layout } = state;
const { sharedFilters, potentialSharedFilters } =
useDashboardInteractiveFilters();

const locale = useLocale();
const cubeFilters = useMemo(() => {
return uniqBy(
state.chartConfigs.flatMap((config) =>
config.cubes.map((x) => ({
iri: x.iri,
joinBy: x.joinBy,
loadValues: true,
}))
),
"iri"
);
}, [state.chartConfigs]);
const [data] = useDataCubesComponentsQuery({
const [{ data }] = useConfigsCubeComponents({
variables: {
sourceType: state.dataSource.type,
sourceUrl: state.dataSource.url,
state,
locale: locale,
cubeFilters: cubeFilters,
},
});

const dimensionsByIri = useMemo(() => {
const res: Record<string, Dimension> = {};
for (const dim of data.data?.dataCubesComponents.dimensions ?? []) {
for (const dim of data?.dataCubesComponents.dimensions ?? []) {
res[dim.iri] = dim;
if (isJoinByComponent(dim)) {
for (const o of dim.originalIris) {
Expand All @@ -147,7 +133,7 @@ const LayoutSharedFiltersConfigurator = () => {
}
}
return res;
}, [data.data?.dataCubesComponents.dimensions]);
}, [data?.dataCubesComponents.dimensions]);

const sharedFiltersByIri = useMemo(() => {
return keyBy(sharedFilters, (x) => x.componentIri);
Expand Down Expand Up @@ -211,6 +197,14 @@ const LayoutSharedFiltersConfigurator = () => {
switch (layout.type) {
case "tab":
case "dashboard":
const shownFilters = potentialSharedFilters.filter((filter) => {
const dimension = dimensionsByIri[filter.componentIri];
return dimension && canDimensionBeTimeFiltered(dimension);
});

if (!shownFilters.length) {
return null;
}
return (
<ControlSection
role="tablist"
Expand All @@ -226,15 +220,11 @@ const LayoutSharedFiltersConfigurator = () => {
</SubsectionTitle>
<ControlSectionContent>
<Stack gap="0.5rem">
{potentialSharedFilters.map((filter) => {
{shownFilters.map((filter) => {
const dimension = dimensionsByIri[filter.componentIri];
const sharedFilter = sharedFiltersByIri[filter.componentIri];

if (!dimension || !canDimensionBeTimeFiltered(dimension)) {
return null;
}
return (
<>
<Fragment key={filter.componentIri}>
<Box
display="flex"
alignItems="center"
Expand Down Expand Up @@ -272,7 +262,7 @@ const LayoutSharedFiltersConfigurator = () => {
sharedFilter={sharedFilter}
dimension={dimension}
/>
</>
</Fragment>
);
})}
</Stack>
Expand Down
18 changes: 13 additions & 5 deletions app/domain/user-configs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,29 @@ import { useCallback } from "react";

import { ParsedConfig } from "@/db/config";
import { fetchChartConfig, fetchChartConfigs } from "@/utils/chart-config/api";
import { UseFetchDataOptions, useFetchData } from "@/utils/use-fetch-data";
import { useFetchData, UseFetchDataOptions } from "@/utils/use-fetch-data";

export const userConfigsKey = ["userConfigs"];
const userConfigKey = (t: string) => ["userConfigs", t];

export const useUserConfigs = (options?: UseFetchDataOptions<ParsedConfig[]>) =>
useFetchData(userConfigsKey, fetchChartConfigs, options);
useFetchData({
queryKey: userConfigsKey,
queryFn: fetchChartConfigs,
options,
});

export const useUserConfig = (
chartId: string | undefined,
options?: UseFetchDataOptions
) => {
let queryFn = useCallback(() => fetchChartConfig(chartId ?? ""), [chartId]);
return useFetchData(userConfigKey(chartId!), queryFn, {
enable: !!chartId,
...options,
return useFetchData({
queryKey: userConfigKey(chartId!),
queryFn,
options: {
enable: !!chartId,
...options,
},
});
};
4 changes: 3 additions & 1 deletion app/graphql/hooks.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ describe("makeUseQuery", () => {
});
});

const useMockQuery = makeUseQuery(mockQuery);
const useMockQuery = makeUseQuery({
fetch: mockQuery,
});

afterEach(() => {
mockQuery.mockClear();
Expand Down
Loading

0 comments on commit 1fe3762

Please sign in to comment.