Skip to content

Commit 2d10ec8

Browse files
committed
chore: Merge main
2 parents d1b6b86 + 67e5d08 commit 2d10ec8

22 files changed

Lines changed: 1074 additions & 385 deletions

app/charts/shared/chart-data-filters.tsx

Lines changed: 87 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -7,31 +7,32 @@ import { ChartFiltersList } from "@/components/chart-filters-list";
77
import Flex from "@/components/flex";
88
import { Select } from "@/components/form";
99
import { Loading } from "@/components/hint";
10+
import SelectTree from "@/components/select-tree";
1011
import {
1112
ChartConfig,
1213
DataSource,
1314
InteractiveFiltersDataConfig,
1415
OptionGroup,
1516
Option,
1617
} from "@/configurator";
17-
import { TimeInput } from "@/configurator/components/field";
18+
import { hierarchyToOptions, TimeInput } from "@/configurator/components/field";
1819
import {
1920
getTimeIntervalFormattedSelectOptions,
2021
getTimeIntervalWithProps,
2122
} from "@/configurator/components/ui-helpers";
22-
import useHierarchyParents from "@/configurator/components/use-hierarchy-parents";
2323
import { FIELD_VALUE_NONE } from "@/configurator/constants";
2424
import { isTemporalDimension } from "@/domain/data";
2525
import { useTimeFormatLocale } from "@/formatters";
2626
import {
2727
Dimension,
28+
HierarchyValue,
2829
TemporalDimension,
2930
TimeUnit,
31+
useDimensionHierarchyQuery,
3032
useDimensionValuesQuery,
3133
} from "@/graphql/query-hooks";
3234
import { Icon } from "@/icons";
3335
import { useLocale } from "@/locales/use-locale";
34-
import { makeOptionGroups } from "@/utils/hierarchy";
3536

3637
export const ChartDataFilters = ({
3738
dataSet,
@@ -150,19 +151,25 @@ const DataFilter = ({
150151
},
151152
});
152153

153-
const { data: hierarchyParents } = useHierarchyParents({
154-
datasetIri: dataSetIri,
155-
dataSource,
156-
dimension: data?.dataCubeByIri?.dimensionByIri!,
157-
locale,
158-
pause: !data?.dataCubeByIri?.dimensionByIri,
154+
const dimension = data?.dataCubeByIri?.dimensionByIri;
155+
156+
const [hierarchyResp] = useDimensionHierarchyQuery({
157+
variables: {
158+
cubeIri: dataSetIri,
159+
dimensionIri: dimension?.iri!,
160+
sourceType: dataSource.type,
161+
sourceUrl: dataSource.url,
162+
locale: locale,
163+
},
164+
pause: !dimension,
159165
});
160166

161-
const optionGroups = React.useMemo(() => {
162-
return makeOptionGroups(hierarchyParents);
163-
}, [hierarchyParents]);
167+
const hierarchy =
168+
hierarchyResp.data?.dataCubeByIri?.dimensionByIri?.hierarchy;
164169

165-
const setDataFilter = (e: SelectChangeEvent<unknown>) => {
170+
const setDataFilter = (
171+
e: SelectChangeEvent<unknown> | { target: { value: string } }
172+
) => {
166173
dispatch({
167174
type: "UPDATE_DATA_FILTER",
168175
value: { dimensionIri, dimensionValueIri: e.target.value as string },
@@ -195,33 +202,40 @@ const DataFilter = ({
195202
" > div": { width: "100%" },
196203
}}
197204
>
198-
{!isTemporalDimension(dimension) ? (
199-
<DataFilterBaseDimension
205+
{isTemporalDimension(dimension) ? (
206+
dimension.timeUnit === TimeUnit.Year ? (
207+
<DataFilterTemporalDimension
208+
value={value as string}
209+
dimension={dimension}
210+
onChange={setDataFilter}
211+
/>
212+
) : null
213+
) : hierarchy ? (
214+
<DataFilterHierarchyDimension
200215
dimension={dimension}
201-
optionGroups={optionGroups}
202216
onChange={setDataFilter}
217+
hierarchy={hierarchy}
203218
value={value as string}
204219
/>
205-
) : dimension.timeUnit === TimeUnit.Year ? (
206-
<DataFilterTemporalDimension
207-
value={value as string}
220+
) : (
221+
<DataFilterGenericDimension
208222
dimension={dimension}
209223
onChange={setDataFilter}
224+
value={value as string}
210225
/>
211-
) : null}
226+
)}
212227
</Flex>
213228
);
214229
} else {
215230
return <Loading />;
216231
}
217232
};
218233

219-
const DataFilterBaseDimension = ({
234+
const DataFilterGenericDimension = ({
220235
dimension,
221236
value,
222237
onChange,
223238
options: propOptions,
224-
optionGroups,
225239
}: {
226240
dimension: Dimension;
227241
value: string;
@@ -255,14 +269,63 @@ const DataFilterBaseDimension = ({
255269
id="dataFilterBaseDimension"
256270
label={label}
257271
options={allOptions}
258-
optionGroups={optionGroups}
259272
value={value}
260273
tooltipText={tooltipText || undefined}
261274
onChange={onChange}
262275
/>
263276
);
264277
};
265278

279+
const DataFilterHierarchyDimension = ({
280+
dimension,
281+
value,
282+
onChange,
283+
hierarchy,
284+
}: {
285+
dimension: Dimension;
286+
value: string;
287+
onChange: (e: { target: { value: string } }) => void;
288+
hierarchy?: HierarchyValue[];
289+
}) => {
290+
const noneLabel = t({
291+
id: "controls.dimensionvalue.none",
292+
message: `No Filter`,
293+
});
294+
295+
const {
296+
label,
297+
isKeyDimension,
298+
description: tooltipText,
299+
values: dimensionValues,
300+
} = dimension;
301+
const options = React.useMemo(() => {
302+
let opts = [] as { label: string; value: string; isNoneValue?: boolean }[];
303+
if (hierarchy) {
304+
opts = hierarchyToOptions(hierarchy);
305+
} else {
306+
opts = dimensionValues;
307+
}
308+
if (!isKeyDimension) {
309+
opts.unshift({
310+
value: FIELD_VALUE_NONE,
311+
label: noneLabel,
312+
isNoneValue: true,
313+
});
314+
}
315+
return opts;
316+
}, [hierarchy, isKeyDimension, dimensionValues, noneLabel]);
317+
318+
return (
319+
<SelectTree
320+
value={value}
321+
options={options}
322+
onChange={onChange}
323+
label={label}
324+
tooltipText={tooltipText || undefined}
325+
/>
326+
);
327+
};
328+
266329
const DataFilterTemporalDimension = ({
267330
dimension,
268331
value,
@@ -300,7 +363,7 @@ const DataFilterTemporalDimension = ({
300363

301364
if (timeIntervalWithProps.range < 100) {
302365
return (
303-
<DataFilterBaseDimension
366+
<DataFilterGenericDimension
304367
dimension={dimension}
305368
options={timeIntervalOptions}
306369
value={value}

app/components/form.tsx

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
Input as MUIInput,
1212
Radio as MUIRadio,
1313
Select as MUISelect,
14+
Skeleton,
1415
Slider as MUISlider,
1516
Switch as MUISwitch,
1617
SelectProps,
@@ -20,7 +21,6 @@ import {
2021
MenuItem,
2122
TypographyProps,
2223
Stack,
23-
CircularProgress,
2424
styled,
2525
PaperProps,
2626
} from "@mui/material";
@@ -285,23 +285,17 @@ const LoadingMenuPaper = forwardRef<HTMLDivElement>(
285285
const loading = useContext(LoadingMenuPaperContext);
286286
return (
287287
<MenuPaper {...props} ref={ref}>
288-
{props.children}
289288
{loading ? (
290-
<Box
291-
px={4}
292-
py={2}
293-
sx={{
294-
position: "sticky",
295-
bottom: 0,
296-
backgroundColor: "warning.light",
297-
}}
298-
>
299-
<Typography variant="body2">
289+
<Box px={4} py={5}>
290+
<Typography variant="body2" sx={{ mb: 2 }} color="text.secondary">
300291
<Trans id="hint.loading.data" />
301-
<CircularProgress size={12} color="inherit" />
302292
</Typography>
293+
<Skeleton sx={{ bgcolor: "grey.300" }} />
294+
<Skeleton sx={{ bgcolor: "grey.300" }} />
303295
</Box>
304-
) : null}
296+
) : (
297+
props.children
298+
)}
305299
</MenuPaper>
306300
);
307301
}
@@ -318,6 +312,8 @@ export const Select = ({
318312
controls,
319313
optionGroups,
320314
tooltipText,
315+
open,
316+
onClose,
321317
onOpen,
322318
loading,
323319
}: {
@@ -367,7 +363,9 @@ export const Select = ({
367363
onChange={onChange}
368364
value={value}
369365
disabled={disabled}
366+
open={open}
370367
onOpen={onOpen}
368+
onClose={onClose}
371369
MenuProps={{
372370
PaperProps: {
373371
// @ts-ignore - It works

0 commit comments

Comments
 (0)