Skip to content

Commit

Permalink
refactor: Switch to multi-cube ChartConfig (III)
Browse files Browse the repository at this point in the history
  • Loading branch information
bprusinowski committed Nov 21, 2023
1 parent 7ec5451 commit 34c0b37
Show file tree
Hide file tree
Showing 4 changed files with 152 additions and 130 deletions.
182 changes: 96 additions & 86 deletions app/configurator/components/chart-configurator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import {
import { makeStyles } from "@mui/styles";
import isEmpty from "lodash/isEmpty";
import isEqual from "lodash/isEqual";
import omitBy from "lodash/omitBy";
import sortBy from "lodash/sortBy";
import { useEffect, useMemo, useRef, useState } from "react";
import {
Expand All @@ -41,6 +40,7 @@ import {
DataSource,
Filters,
getChartConfig,
getChartConfigFilters,
isMapConfig,
useChartConfigFilters,
} from "@/configurator";
Expand Down Expand Up @@ -167,71 +167,82 @@ const useEnsurePossibleFilters = ({
const chartConfig = getChartConfig(state);
const [fetching, setFetching] = useState(false);
const [error, setError] = useState<Error>();
const lastFilters = useRef<Filters>();
const lastFilters = useRef<Record<string, Filters>>({});
const client = useClient();

useEffect(() => {
const run = async () => {
const { mappedFilters, unmappedFilters } =
getFiltersByMappingStatus(chartConfig);
if (
lastFilters.current &&
orderedIsEqual(lastFilters.current, unmappedFilters)
) {
return;
}
lastFilters.current = unmappedFilters;

setFetching(true);
const { data, error } = await client
.query<PossibleFiltersQuery, PossibleFiltersQueryVariables>(
PossibleFiltersDocument,
{
iri: chartConfig.dataSet,
sourceType: state.dataSource.type,
sourceUrl: state.dataSource.url,
filters: unmappedFilters,

// @ts-ignore This is to make urql requery
filterKey: Object.keys(unmappedFilters).join(", "),
}
)
.toPromise();
if (error || !data) {
setError(error);
chartConfig.cubes.forEach(async (cube) => {
const { mappedFilters, unmappedFilters } = getFiltersByMappingStatus(
chartConfig,
cube.iri
);

if (
lastFilters.current[cube.iri] &&
orderedIsEqual(lastFilters.current[cube.iri], unmappedFilters)
) {
return;
}

lastFilters.current[cube.iri] = unmappedFilters;
setFetching(true);

const { data, error } = await client
.query<PossibleFiltersQuery, PossibleFiltersQueryVariables>(
PossibleFiltersDocument,
{
iri: cube.iri,
sourceType: state.dataSource.type,
sourceUrl: state.dataSource.url,
filters: unmappedFilters,
// @ts-ignore This is to make urql requery
filterKey: Object.keys(unmappedFilters).join(", "),
}
)
.toPromise();

if (error || !data) {
setError(error);
setFetching(false);
console.error("Could not fetch possible filters", error);

return;
}

setError(undefined);
setFetching(false);
console.error("Could not fetch possible filters", error);
return;
}
setError(undefined);
setFetching(false);

const filters = Object.assign(
Object.fromEntries(
data.possibleFilters.map((x) => [
x.iri,
{ type: x.type, value: x.value },
])
) as Filters,
mappedFilters
);

if (!isEqual(filters, chartConfig.filters) && !isEmpty(filters)) {
dispatch({
type: "CHART_CONFIG_FILTERS_UPDATE",
value: {
filters,
},
});
}
const filters = Object.assign(
Object.fromEntries(
data.possibleFilters.map((x) => [
x.iri,
{ type: x.type, value: x.value },
])
) as Filters,
mappedFilters
);

const oldFilters = getChartConfigFilters(chartConfig.cubes, cube.iri);

if (!isEqual(filters, oldFilters) && !isEmpty(filters)) {
dispatch({
type: "CHART_CONFIG_FILTERS_UPDATE",
value: {
cubeIri: cube.iri,
filters,
},
});
}
});
};

run();
}, [
client,
dispatch,
chartConfig,
chartConfig.dataSet,
chartConfig.cubes,
state.dataSource.type,
state.dataSource.url,
]);
Expand All @@ -247,37 +258,41 @@ const useFilterReorder = ({
const [state, dispatch] = useConfiguratorState(isConfiguring);
const chartConfig = getChartConfig(state);
const locale = useLocale();

const { filters } = chartConfig;
const { unmappedFilters, mappedFiltersIris } = useMemo(() => {
const filters = getChartConfigFilters(chartConfig.cubes);
const { mappedFiltersIris } = useMemo(() => {
return getFiltersByMappingStatus(chartConfig);
}, [chartConfig]);

const variables = useMemo(() => {
const hasUnmappedFilters = Object.keys(unmappedFilters).length > 0;
const vars = {
iri: chartConfig.dataSet,
sourceType: state.dataSource.type,
sourceUrl: state.dataSource.url,
locale,
filters: hasUnmappedFilters ? unmappedFilters : undefined,
// This is important for urql not to think that filters
// are the same while the order of the keys has changed.
// If this is not present, we'll have outdated dimension
// values after we change the filter order
filterKeys: hasUnmappedFilters
? Object.keys(unmappedFilters).join(", ")
: undefined,
};
const filters = chartConfig.cubes.map((cube) => {
const { unmappedFilters } = getFiltersByMappingStatus(
chartConfig,
cube.iri
);
return Object.keys(unmappedFilters).length > 0
? {
iri: cube.iri,
filters: unmappedFilters,
}
: {
iri: cube.iri,
filters: undefined,
};
});

return omitBy(vars, (x) => x === undefined) as typeof vars;
}, [
chartConfig.dataSet,
state.dataSource.type,
state.dataSource.url,
locale,
unmappedFilters,
]);
// This is important for urql not to think that filters
// are the same while the order of the keys has changed.
// If this is not present, we'll have outdated dimension
// values after we change the filter order
const requeryKey = filters.reduce((acc, d) => {
return `${acc}${d.iri}${JSON.stringify(d.filters)}`;
}, "");

return {
filters,
requeryKey: requeryKey ? requeryKey : undefined,
};
}, [chartConfig]);

const [
{ data: componentsData, fetching: componentsFetching },
Expand All @@ -287,9 +302,7 @@ const useFilterReorder = ({
sourceType: state.dataSource.type,
sourceUrl: state.dataSource.url,
locale,
filters: [{ iri: chartConfig.dataSet, filters: variables.filters }],
// @ts-ignore This is to make urql requery
filterKeys: variables.filterKeys,
...variables,
},
});

Expand All @@ -299,9 +312,7 @@ const useFilterReorder = ({
sourceType: state.dataSource.type,
sourceUrl: state.dataSource.url,
locale,
filters: [{ iri: chartConfig.dataSet, filters: variables.filters }],
// @ts-ignore This is to make urql requery
filterKeys: variables.filterKeys,
...variables,
},
});
}, [
Expand All @@ -310,7 +321,6 @@ const useFilterReorder = ({
state.dataSource.type,
state.dataSource.url,
locale,
chartConfig.dataSet,
]);

const dimensions = componentsData?.dataCubesComponents?.dimensions;
Expand Down
14 changes: 8 additions & 6 deletions app/configurator/config-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -435,15 +435,17 @@ export const useSingleFilterSelect = ({
[cubeIri, dimensionIri, dispatch]
);

let value: string | undefined;
let value = FIELD_VALUE_NONE;

if (state.state === "CONFIGURING_CHART") {
const chartConfig = getChartConfig(state);
value = get(
chartConfig,
["filters", dimensionIri, "value"],
FIELD_VALUE_NONE
);
const cube = chartConfig.cubes.find((cube) => cube.iri === cubeIri);

if (cube) {
value = get(cube, ["filters", dimensionIri, "value"], FIELD_VALUE_NONE);
}
}

return {
value,
onChange,
Expand Down
2 changes: 1 addition & 1 deletion app/configurator/configurator-state.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -784,7 +784,7 @@ describe("getFiltersByMappingStatus", () => {
},
} as any as MapConfig;

const { mappedFiltersIris } = getFiltersByMappingStatus(config);
const { mappedFiltersIris } = getFiltersByMappingStatus(config, "");

expect([...mappedFiltersIris]).toEqual(
expect.arrayContaining(["areaColorIri", "symbolColorIri"])
Expand Down
Loading

0 comments on commit 34c0b37

Please sign in to comment.