Skip to content

Commit 9f42c36

Browse files
authored
Merge branch 'main' into feat/toggle-flags-w-cmd
2 parents 624b90b + 52ae32d commit 9f42c36

File tree

80 files changed

+2739
-717
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

80 files changed

+2739
-717
lines changed

CHANGELOG.md

+41
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,51 @@ You can also check the
1212
# Unreleased
1313

1414

15+
- Features
16+
- Limits can now be displayed in bar charts
17+
- Exact limit values are now displayed in legend
18+
- Fixes
19+
- Line chart dots are now based on data, eliminating misaligned dots
20+
- Added a fallback to color selector
21+
- Dynamic descriptions for custom color palette types
22+
- Show line dot sizes are now translated
23+
24+
# [5.2.6] - 2025-02-18
25+
26+
- Features
27+
- Added a way to display limit values and targets coming from the data with
28+
compatible chart types
29+
- Fixes
30+
- Color picker's HEX code input now stays up-to-date with the selected color
31+
- Markdown links now open in a new tab
32+
- Publishing of a dashboard with text blocks doesn't crash the application in
33+
some rare cases anymore
34+
35+
# [5.2.5] - 2025-02-18
36+
1537
- Features
1638
- Added option for hiding legend titles using a toggle switch
39+
- Bar charts, dashboard text blocks and Markdown inputs are not hidden behind
40+
flags anymore
41+
- Added improved Iframe view for the use of ODS
1742
- Fixes
43+
- Added button translations for custom color palette update and create button
44+
- Color swatches inside the color picker dynamically adjust to the colors of
45+
the selected palette
46+
- All colors of a selected custom color palette are displayed when selected at
47+
all times regardless of the color type
48+
- Dashboard text block are now automatically resized also in published charts
49+
- Added (required) hint for palette titles and disabled the "add color button"
50+
if the color palette title is missing
51+
- Added dynamic translations for color contrast checking warnings
52+
- Added error displaying for title names that already exists on the custom
53+
color palette form inside the user profile only when adding palettes
1854
- Fixed button translations for custom color palette update and create button.
55+
- Fixed errors regarding switching form existing categorical palette to a
56+
diverging color palette
57+
- Improved filter section styling
58+
- Removed legend titles tooltip on the toggle switch
59+
- Fixed Map Symbol Layer custom color palette support for all palette types
1960
- Maintenance
2061
- Added authentication method to e2e tests
2162
- Added authentication to vercel previews for easier testing

app/browser/dataset-preview.tsx

+36-12
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1+
import { ParsedUrlQuery } from "querystring";
2+
13
import { Trans } from "@lingui/macro";
24
import { Box, Button, Paper, Theme, Typography } from "@mui/material";
35
import { makeStyles } from "@mui/styles";
46
import Head from "next/head";
57
import Link from "next/link";
8+
import { useRouter } from "next/router";
69
import React, { useEffect } from "react";
710

811
import { DataSetPreviewTable } from "@/browse/datatable";
@@ -19,6 +22,10 @@ import {
1922
import { DataCubePublicationStatus } from "@/graphql/resolver-types";
2023
import { useLocale } from "@/locales/use-locale";
2124

25+
export const isOdsIframe = (query: ParsedUrlQuery) => {
26+
return query["odsiframe"] === "true";
27+
};
28+
2229
const useStyles = makeStyles<Theme, { descriptionPresent: boolean }>(
2330
(theme) => ({
2431
root: {
@@ -108,6 +115,7 @@ export const DataSetPreview = ({
108115
}) => {
109116
const footnotesClasses = useFootnotesStyles({ useMarginTop: false });
110117
const locale = useLocale();
118+
const router = useRouter();
111119
const variables = {
112120
sourceType: dataSource.type,
113121
sourceUrl: dataSource.url,
@@ -165,23 +173,37 @@ export const DataSetPreview = ({
165173
onClick={(ev) => onCreateChartFromDataset?.(ev, dataSetIri)}
166174
className={classes.createChartButton}
167175
component="a"
176+
target={isOdsIframe(router.query) ? "_blank" : undefined}
168177
>
169-
<Trans id="browse.dataset.create-visualization">
170-
Create visualization from dataset
171-
</Trans>
178+
{!isOdsIframe(router.query) ? (
179+
<Trans id="browse.dataset.create-visualization">
180+
Create visualization from dataset
181+
</Trans>
182+
) : (
183+
<Trans id="browse.dataset.create-visualization-visualize">
184+
Create visualization on visualize from this dataset
185+
</Trans>
186+
)}
172187
</Button>
173188
) : (
174189
<Link
175190
href={`/create/new?cube=${
176191
dataCubeMetadata.iri
177192
}&dataSource=${sourceToLabel(dataSource)}`}
178193
passHref
179-
legacyBehavior
194+
legacyBehavior={!isOdsIframe(router.query)}
195+
target={isOdsIframe(router.query) ? "_blank" : undefined}
180196
>
181197
<Button className={classes.createChartButton} component="a">
182-
<Trans id="browse.dataset.create-visualization">
183-
Create visualization from dataset
184-
</Trans>
198+
{!isOdsIframe(router.query) ? (
199+
<Trans id="browse.dataset.create-visualization">
200+
Create visualization from dataset
201+
</Trans>
202+
) : (
203+
<Trans id="browse.dataset.create-visualization-visualize">
204+
Create visualization on visualize from this dataset
205+
</Trans>
206+
)}
185207
</Button>
186208
</Link>
187209
)}
@@ -206,11 +228,13 @@ export const DataSetPreview = ({
206228
</Flex>
207229
<Flex className={classes.footnotesWrapper}>
208230
<Flex className={footnotesClasses.actions}>
209-
<DataDownloadMenu
210-
dataSource={dataSource}
211-
title={dataCubeMetadata.title}
212-
filters={variables.cubeFilter}
213-
/>
231+
{!isOdsIframe(router.query) && (
232+
<DataDownloadMenu
233+
dataSource={dataSource}
234+
title={dataCubeMetadata.title}
235+
filters={variables.cubeFilter}
236+
/>
237+
)}
214238
</Flex>
215239
<FirstTenRowsCaption />
216240
</Flex>

app/browser/select-dataset-step.tsx

+76-49
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import uniqBy from "lodash/uniqBy";
77
import Head from "next/head";
88
import NextLink from "next/link";
99
import { Router, useRouter } from "next/router";
10-
import React, { useMemo } from "react";
10+
import React, { useCallback, useMemo } from "react";
1111
import { useDebounce } from "use-debounce";
1212

1313
import {
@@ -22,8 +22,13 @@ import {
2222
SearchDatasetInput,
2323
SearchFilters,
2424
} from "@/browser/dataset-browse";
25-
import { DataSetPreview, DataSetPreviewProps } from "@/browser/dataset-preview";
25+
import {
26+
DataSetPreview,
27+
DataSetPreviewProps,
28+
isOdsIframe,
29+
} from "@/browser/dataset-preview";
2630
import { BrowseFilter, DataCubeAbout } from "@/browser/filters";
31+
import { CHART_RESIZE_EVENT_TYPE } from "@/charts/shared/use-size";
2732
import { DatasetMetadata } from "@/components/dataset-metadata";
2833
import Flex from "@/components/flex";
2934
import { Footer } from "@/components/footer";
@@ -53,6 +58,7 @@ import {
5358
} from "@/graphql/query-hooks";
5459
import { Icon } from "@/icons";
5560
import { useConfiguratorState, useLocale } from "@/src";
61+
import { useResizeObserver } from "@/utils/use-resize-observer";
5662

5763
const softJSONParse = (v: string) => {
5864
try {
@@ -67,14 +73,17 @@ const useStyles = makeStyles<
6773
{
6874
datasetPresent: boolean;
6975
variant: NonNullable<SelectDatasetStepContentProps["variant"]>;
76+
isOdsIframe: boolean;
7077
}
7178
>((theme) => ({
7279
panelLayout: {
73-
maxWidth: 1400,
80+
maxWidth: ({ isOdsIframe }) => (isOdsIframe ? "auto" : 1400),
7481
margin: "auto",
7582
position: "static",
76-
marginTop: ({ datasetPresent, variant }) =>
77-
datasetPresent && variant !== "drawer" ? BANNER_MARGIN_TOP : 0,
83+
marginTop: ({ datasetPresent, variant, isOdsIframe }) =>
84+
datasetPresent && variant !== "drawer" && !isOdsIframe
85+
? BANNER_MARGIN_TOP
86+
: 0,
7887
height: "auto",
7988
transition: "margin-top 0.5s ease",
8089
},
@@ -195,7 +204,19 @@ const SelectDatasetStepContent = ({
195204
leading: true,
196205
});
197206
const router = useRouter();
198-
const classes = useStyles({ datasetPresent: !!dataset, variant });
207+
const handleHeightChange = useCallback(
208+
({ height }: { width: number; height: number }) => {
209+
window.parent.postMessage({ type: CHART_RESIZE_EVENT_TYPE, height }, "*");
210+
},
211+
[]
212+
);
213+
const [ref] = useResizeObserver(handleHeightChange);
214+
215+
const classes = useStyles({
216+
datasetPresent: !!dataset,
217+
variant,
218+
isOdsIframe: isOdsIframe(router.query),
219+
});
199220
const backLink = useMemo(() => {
200221
return formatBackLink(router.query);
201222
}, [router.query]);
@@ -324,7 +345,7 @@ const SelectDatasetStepContent = ({
324345
}
325346

326347
return (
327-
<Box>
348+
<Box ref={ref}>
328349
<AnimatePresence>
329350
{!dataset && variant === "page" && (
330351
<MotionBox key="banner" {...bannerPresenceProps}>
@@ -357,51 +378,57 @@ const SelectDatasetStepContent = ({
357378
</MotionBox>
358379
)}
359380
</AnimatePresence>
360-
<PanelLayout type="LM" className={classes.panelLayout} key="panel">
361-
<PanelBodyWrapper type="L" className={classes.panelLeft}>
362-
<AnimatePresence mode="wait">
363-
{dataset ? (
364-
<MotionBox
365-
key="metadata"
366-
sx={{ mx: 4, px: 4 }}
367-
{...navPresenceProps}
368-
>
369-
<NextLink href={backLink} passHref legacyBehavior>
370-
<Button
371-
variant="contained"
372-
color="secondary"
373-
startIcon={<Icon name="chevronLeft" size={12} />}
374-
onClick={onClickBackLink}
375-
>
376-
<Trans id="dataset-preview.back-to-results">
377-
Back to the list
378-
</Trans>
379-
</Button>
380-
</NextLink>
381-
<MotionBox sx={{ mt: 6 }} {...smoothPresenceProps}>
382-
<DatasetMetadataSingleCubeAdapter
383-
datasetIri={dataset}
384-
dataSource={configState.dataSource}
381+
<PanelLayout
382+
type={isOdsIframe(router.query) ? "M" : "LM"}
383+
className={classes.panelLayout}
384+
key="panel"
385+
>
386+
{!isOdsIframe(router.query) && (
387+
<PanelBodyWrapper type="L" className={classes.panelLeft}>
388+
<AnimatePresence mode="wait">
389+
{dataset ? (
390+
<MotionBox
391+
key="metadata"
392+
sx={{ mx: 4, px: 4 }}
393+
{...navPresenceProps}
394+
>
395+
<NextLink href={backLink} passHref legacyBehavior>
396+
<Button
397+
variant="contained"
398+
color="secondary"
399+
startIcon={<Icon name="chevronLeft" size={12} />}
400+
onClick={onClickBackLink}
401+
>
402+
<Trans id="dataset-preview.back-to-results">
403+
Back to the list
404+
</Trans>
405+
</Button>
406+
</NextLink>
407+
<MotionBox sx={{ mt: 6 }} {...smoothPresenceProps}>
408+
<DatasetMetadataSingleCubeAdapter
409+
datasetIri={dataset}
410+
dataSource={configState.dataSource}
411+
/>
412+
</MotionBox>
413+
</MotionBox>
414+
) : (
415+
<MotionBox key="search-filters" {...navPresenceProps}>
416+
<SearchFilters
417+
cubes={allCubes}
418+
themes={themes}
419+
orgs={orgs}
420+
termsets={termsets}
421+
disableNavLinks
385422
/>
386423
</MotionBox>
387-
</MotionBox>
388-
) : (
389-
<MotionBox key="search-filters" {...navPresenceProps}>
390-
<SearchFilters
391-
cubes={allCubes}
392-
themes={themes}
393-
orgs={orgs}
394-
termsets={termsets}
395-
disableNavLinks
396-
/>
397-
</MotionBox>
398-
)}
399-
</AnimatePresence>
400-
</PanelBodyWrapper>
424+
)}
425+
</AnimatePresence>
426+
</PanelBodyWrapper>
427+
)}
401428
<PanelBodyWrapper
402-
type="M"
429+
type={"M"}
403430
className={classes.panelMiddle}
404-
sx={{ maxWidth: 1040, p: 6 }}
431+
sx={isOdsIframe(router.query) ? { p: 6 } : { maxWidth: 1040, p: 6 }}
405432
>
406433
<AnimatePresence mode="wait">
407434
{dataset ? (
@@ -494,7 +521,7 @@ const SelectDatasetStepContent = ({
494521
</AnimatePresence>
495522
</PanelBodyWrapper>
496523
</PanelLayout>
497-
{variant == "page" ? (
524+
{variant == "page" && !isOdsIframe(router.query) ? (
498525
<Box
499526
sx={{
500527
borderTop: "2px solid rgba(0,0,0,0.05)",

app/charts/area/chart-area.tsx

+13-4
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,10 @@ import {
1414
import { Ruler } from "@/charts/shared/interaction/ruler";
1515
import { Tooltip } from "@/charts/shared/interaction/tooltip";
1616
import { LegendColor } from "@/charts/shared/legend-color";
17+
import { VerticalLimits } from "@/charts/shared/limits";
1718
import { InteractionHorizontal } from "@/charts/shared/overlay-horizontal";
1819
import { AreaConfig } from "@/config-types";
20+
import { useLimits } from "@/config-utils";
1921

2022
import { ChartProps, VisualizationProps } from "../shared/ChartProps";
2123

@@ -26,29 +28,36 @@ export const ChartAreasVisualization = (
2628
};
2729

2830
const ChartAreas = memo((props: ChartProps<AreaConfig>) => {
29-
const { chartConfig, dimensionsById } = props;
31+
const { chartConfig, dimensions, measures, dimensionsById } = props;
3032
const { fields, interactiveFiltersConfig } = chartConfig;
33+
const limits = useLimits({
34+
chartConfig,
35+
dimensions,
36+
measures,
37+
});
3138

3239
return (
3340
<AreaChart {...props}>
3441
<ChartContainer>
3542
<ChartSvg>
3643
<AxisTime /> <AxisHeightLinear />
3744
<Areas /> <AxisTimeDomain />
45+
<VerticalLimits {...limits} />
3846
<InteractionHorizontal />
3947
{interactiveFiltersConfig?.timeRange.active === true && <BrushTime />}
4048
</ChartSvg>
4149
<Tooltip type={fields.segment ? "multiple" : "single"} />
4250
<Ruler />
4351
</ChartContainer>
44-
{fields.segment && (
52+
{(fields.segment || limits.limits.length > 0) && (
4553
<ChartControlsContainer>
4654
<LegendColor
47-
dimensionsById={dimensionsById}
4855
chartConfig={chartConfig}
4956
symbol="square"
5057
interactive={interactiveFiltersConfig?.legend.active}
51-
showTitle={fields.segment && fields.segment.showTitle}
58+
showTitle={fields.segment?.showTitle}
59+
dimensionsById={dimensionsById}
60+
limits={limits.limits}
5261
/>
5362
</ChartControlsContainer>
5463
)}

0 commit comments

Comments
 (0)