diff --git a/app/components/chart-preview.tsx b/app/components/chart-preview.tsx index fa2ddf780..b21d7b13b 100644 --- a/app/components/chart-preview.tsx +++ b/app/components/chart-preview.tsx @@ -1,6 +1,5 @@ import { Trans } from "@lingui/macro"; -import { Box, Theme, Typography } from "@mui/material"; -import { makeStyles } from "@mui/styles"; +import { Box } from "@mui/material"; import Head from "next/head"; import { useMemo } from "react"; @@ -22,6 +21,7 @@ import { hasChartConfigs, useConfiguratorState, } from "@/configurator"; +import { Description, Title } from "@/configurator/components/annotator"; import { useDataCubesComponentsQuery, useDataCubesMetadataQuery, @@ -42,29 +42,11 @@ export const ChartPreview = (props: ChartPreviewProps) => { ); }; -const useStyles = makeStyles({ - title: { - marginBottom: 2, - cursor: "pointer", - "&:hover": { - textDecoration: "underline", - }, - }, - description: { - marginBottom: 2, - cursor: "pointer", - "&:hover": { - textDecoration: "underline", - }, - }, -}); - export const ChartPreviewInner = (props: ChartPreviewProps) => { const { dataSource } = props; const [state, dispatch] = useConfiguratorState(); const chartConfig = getChartConfig(state); const locale = useLocale(); - const classes = useStyles(); const commonQueryVariables = { sourceType: dataSource.type, sourceUrl: dataSource.url, @@ -145,28 +127,20 @@ export const ChartPreviewInner = (props: ChartPreviewProps) => { gap: 2, }} > - + { dispatch({ type: "ACTIVE_FIELD_CHANGED", value: "title", - }) - } - > - {chartConfig.meta.title[locale] === "" ? ( - <Trans id="annotation.add.title">[ Title ]</Trans> - ) : ( - chartConfig.meta.title[locale] - )} - </Typography> + }); + } + : undefined + } + /> <MetadataPanel // FIXME: adapt to design @@ -185,28 +159,20 @@ export const ChartPreviewInner = (props: ChartPreviewProps) => { - visualize.admin.ch - + { dispatch({ type: "ACTIVE_FIELD_CHANGED", value: "description", - }) - } - > - {chartConfig.meta.description[locale] === "" ? ( - [ Description ] - ) : ( - chartConfig.meta.description[locale] - )} - + }); + } + : undefined + } + /> {isTablePreview ? ( diff --git a/app/components/chart-published.tsx b/app/components/chart-published.tsx index c44159e51..e6a9f2544 100644 --- a/app/components/chart-published.tsx +++ b/app/components/chart-published.tsx @@ -1,5 +1,5 @@ import { Trans } from "@lingui/macro"; -import { Box, Theme, Typography } from "@mui/material"; +import { Box, Theme } from "@mui/material"; import { makeStyles } from "@mui/styles"; import { useEffect, useMemo, useRef } from "react"; import { useStore } from "zustand"; @@ -29,6 +29,7 @@ import { isPublished, useConfiguratorState, } from "@/configurator"; +import { Description, Title } from "@/configurator/components/annotator"; import { DRAWER_WIDTH } from "@/configurator/components/drawer"; import { DEFAULT_DATA_SOURCE, @@ -222,15 +223,12 @@ const ChartPublishedInner = (props: ChartPublishInnerProps) => { )} - - {meta.title[locale]} - - + {meta.title[locale] && } <MetadataPanel // FIXME: adapt to design datasetIri={chartConfig.cubes[0].iri} @@ -239,11 +237,8 @@ const ChartPublishedInner = (props: ChartPublishInnerProps) => { container={rootRef.current} /> </Flex> - {meta.description[locale] && ( - <Typography component="div" variant="body1" mb={2}> - {meta.description[locale]} - </Typography> + <Description text={meta.description[locale]} /> )} <InteractiveFiltersProvider> <Flex diff --git a/app/configurator/components/annotator.tsx b/app/configurator/components/annotator.tsx new file mode 100644 index 000000000..78c9f02c8 --- /dev/null +++ b/app/configurator/components/annotator.tsx @@ -0,0 +1,62 @@ +import { Trans } from "@lingui/macro"; +import { Theme, Typography, TypographyProps } from "@mui/material"; +import { makeStyles } from "@mui/styles"; +import clsx from "clsx"; + +const useStyles = makeStyles<Theme, { hoverable?: boolean }>({ + text: { + marginBottom: 4, + cursor: "pointer", + + "&:hover": { + textDecoration: ({ hoverable }) => (hoverable ? "underline" : "none"), + }, + }, +}); + +const getEmptyColor = (lighterColor?: boolean) => { + return lighterColor ? "grey.500" : "secondary.main"; +}; + +type Props = TypographyProps & { + text: string; + lighterColor?: boolean; +}; + +export const Title = (props: Props) => { + const { text, lighterColor, onClick, className, sx, ...rest } = props; + const classes = useStyles({ hoverable: !!onClick }); + + return ( + <Typography + {...rest} + variant="h2" + className={clsx(classes.text, className)} + onClick={onClick} + sx={{ color: text === "" ? getEmptyColor(lighterColor) : "text", ...sx }} + > + {text === "" ? <Trans id="annotation.add.title">[ Title ]</Trans> : text} + </Typography> + ); +}; + +export const Description = (props: Props) => { + const { text, lighterColor, onClick, className, sx, ...rest } = props; + const classes = useStyles({ hoverable: !!onClick }); + + return ( + <Typography + {...rest} + variant="body1" + className={clsx(classes.text, className)} + onClick={onClick} + sx={{ color: text === "" ? getEmptyColor(lighterColor) : "text", ...sx }} + > + {text === "" ? ( + <Trans id="annotation.add.description">[ Description ]</Trans> + ) : ( + text + )} + </Typography> + ); +}; diff --git a/app/configurator/components/chart-annotator.tsx b/app/configurator/components/chart-annotator.tsx index b8ae1894e..a65e9339d 100644 --- a/app/configurator/components/chart-annotator.tsx +++ b/app/configurator/components/chart-annotator.tsx @@ -9,10 +9,9 @@ import { } from "@/configurator/components/chart-controls/section"; import { AnnotatorTabField } from "@/configurator/components/field"; import { getFieldLabel } from "@/configurator/components/field-i18n"; +import { isConfiguring } from "@/configurator/configurator-state"; import { useConfiguratorState, useLocale } from "@/src"; -import { isConfiguring } from "../configurator-state"; - export const TitleAndDescriptionConfigurator = () => { const [state] = useConfiguratorState(isConfiguring); const chartConfig = getChartConfig(state); diff --git a/app/configurator/components/configurator.tsx b/app/configurator/components/configurator.tsx index 23ec06a1e..eb4f6ec87 100644 --- a/app/configurator/components/configurator.tsx +++ b/app/configurator/components/configurator.tsx @@ -16,6 +16,7 @@ import { getChartConfig, useConfiguratorState, } from "@/configurator"; +import { Description, Title } from "@/configurator/components/annotator"; import { ChartAnnotationsSelector } from "@/configurator/components/chart-annotations-selector"; import { ChartConfigurator } from "@/configurator/components/chart-configurator"; import { ChartOptionsSelector } from "@/configurator/components/chart-options-selector"; @@ -32,6 +33,7 @@ import { } from "@/configurator/components/layout"; import { ChartConfiguratorTable } from "@/configurator/table/table-chart-configurator"; import SvgIcChevronLeft from "@/icons/components/IcChevronLeft"; +import { useLocale } from "@/locales/use-locale"; import { useDataSourceStore } from "@/stores/data-source"; import { InteractiveFiltersProvider } from "@/stores/interactive-filters"; import useEvent from "@/utils/use-event"; @@ -195,6 +197,7 @@ const ConfigureChartStep = () => { }; const LayoutingStep = () => { + const locale = useLocale(); const [state, dispatch] = useConfiguratorState(); const handlePrevious = useEvent(() => { if (state.state !== "LAYOUTING") { @@ -271,6 +274,21 @@ const LayoutingStep = () => { </PanelHeaderLayout> <PanelBodyWrapper type="M"> <Box sx={{ maxWidth: 980, mx: "auto" }}> + <Box + sx={{ + display: "flex", + flexDirection: "column", + gap: 1, + mt: 3, + mb: 4, + }} + > + <Title text={state.meta.title[locale]} onClick={() => {}} /> + <Description + text={state.meta.description[locale]} + onClick={() => {}} + /> + </Box> <ChartPanel> <ChartPreview dataSource={state.dataSource} /> </ChartPanel>