diff --git a/frontend/src/metabase-types/store/mocks/qb.ts b/frontend/src/metabase-types/store/mocks/qb.ts index 4e99b74461c6e467f3826c16f388c7e0f0bcbd16..084234129600f28963c938a910632b863e6d407c 100644 --- a/frontend/src/metabase-types/store/mocks/qb.ts +++ b/frontend/src/metabase-types/store/mocks/qb.ts @@ -20,7 +20,7 @@ export const createMockQueryBuilderUIControlsState = ( isShowingQuestionInfoSidebar: false, isShowingSnippetSidebar: false, isShowingTimelineSidebar: false, - initialChartSetting: null, + initialChartSetting: {}, isShowingRawTable: false, isNativeEditorOpen: false, queryBuilderMode: "view", diff --git a/frontend/src/metabase-types/store/qb.ts b/frontend/src/metabase-types/store/qb.ts index 0a8b2f47563081e977cef3061d27db8e236027c3..ad910bcbfa0ac1930c6be6e4d63b7f0d87e12e7f 100644 --- a/frontend/src/metabase-types/store/qb.ts +++ b/frontend/src/metabase-types/store/qb.ts @@ -1,4 +1,5 @@ import type { QueryModalType } from "metabase/query_builder/constants"; +import type { Widget } from "metabase/visualizations/components/ChartSettings/types"; import type { Card, DashboardId, @@ -11,6 +12,10 @@ import type { export type QueryBuilderMode = "view" | "notebook" | "dataset"; export type DatasetEditorTab = "query" | "metadata"; export type QueryBuilderQueryStatus = "idle" | "running" | "complete"; +export type InitialChartSettingState = { + section?: string | null; + widget?: Widget | null; +}; export type ForeignKeyReference = { status: number; @@ -32,7 +37,7 @@ export interface QueryBuilderUIControls { isShowingSnippetSidebar: boolean; isShowingTimelineSidebar: boolean; isNativeEditorOpen: boolean; - initialChartSetting: null; + initialChartSetting: InitialChartSettingState; isShowingRawTable: boolean; queryBuilderMode: QueryBuilderMode | false; previousQueryBuilderMode: boolean; diff --git a/frontend/src/metabase/dashboard/components/DashCard/DashCardActionsPanel/ChartSettingsButton/ChartSettingsButton.tsx b/frontend/src/metabase/dashboard/components/DashCard/DashCardActionsPanel/ChartSettingsButton/ChartSettingsButton.tsx index a6e1b047476e4ec35928cc86d673d222e93ef90f..d882c10856b287ceb5514c63c707860a367d8d42 100644 --- a/frontend/src/metabase/dashboard/components/DashCard/DashCardActionsPanel/ChartSettingsButton/ChartSettingsButton.tsx +++ b/frontend/src/metabase/dashboard/components/DashCard/DashCardActionsPanel/ChartSettingsButton/ChartSettingsButton.tsx @@ -2,9 +2,8 @@ import { useDisclosure } from "@mantine/hooks"; import { t } from "ttag"; import { DEFAULT_Z_INDEX } from "metabase/components/Popover/constants"; -import CS from "metabase/css/core/index.css"; import { Modal } from "metabase/ui"; -import { ChartSettingsWithState } from "metabase/visualizations/components/ChartSettings"; +import { DashboardChartSettings } from "metabase/visualizations/components/ChartSettings"; import type { Dashboard, DashboardCard, @@ -50,11 +49,9 @@ export function ChartSettingsButton({ <Modal.Overlay /> <Modal.Content mih="85%"> <Modal.Body> - <ChartSettingsWithState - className={CS.spread} + <DashboardChartSettings series={series} onChange={onReplaceAllVisualizationSettings} - isDashboard dashboard={dashboard} dashcard={dashcard} onClose={close} diff --git a/frontend/src/metabase/query_builder/components/view/sidebars/ChartSettingsSidebar.tsx b/frontend/src/metabase/query_builder/components/view/sidebars/ChartSettingsSidebar.tsx index 1ab9622d5759599d085788094109dcb7100b4eb2..2eb4d1aa96cdbbfae219a486e7211ad7c05d51c6 100644 --- a/frontend/src/metabase/query_builder/components/view/sidebars/ChartSettingsSidebar.tsx +++ b/frontend/src/metabase/query_builder/components/view/sidebars/ChartSettingsSidebar.tsx @@ -15,9 +15,9 @@ import { getVisualizationSettings, } from "metabase/query_builder/selectors"; import visualizations from "metabase/visualizations"; -import { ChartSettings } from "metabase/visualizations/components/ChartSettings"; +import { QuestionChartSettings } from "metabase/visualizations/components/ChartSettings"; import type Question from "metabase-lib/v1/Question"; -import type { Dataset } from "metabase-types/api"; +import type { Dataset, VisualizationSettings } from "metabase-types/api"; interface ChartSettingsSidebarProps { question: Question; @@ -55,6 +55,9 @@ function ChartSettingsSidebarInner({ ]; }, [card, result]); + const onChange = (settings: VisualizationSettings, question?: Question) => + dispatch(onReplaceAllVisualizationSettings(settings, question)); + return ( result && ( <SidebarContent @@ -63,14 +66,10 @@ function ChartSettingsSidebarInner({ {...sidebarContentProps} > <ErrorBoundary> - <ChartSettings + <QuestionChartSettings question={question} series={series} - onChange={(settings, question) => - dispatch(onReplaceAllVisualizationSettings(settings, question)) - } - onClose={handleClose} - noPreview + onChange={onChange} initial={initialChartSetting} computedSettings={visualizationSettings} /> diff --git a/frontend/src/metabase/query_builder/defaults.ts b/frontend/src/metabase/query_builder/defaults.ts index a48d22c14e68705c3d6de9c0f815a814df450380..4ddc5204a6291608b6d00bc0969e8ff33a7247d7 100644 --- a/frontend/src/metabase/query_builder/defaults.ts +++ b/frontend/src/metabase/query_builder/defaults.ts @@ -18,7 +18,7 @@ export const DEFAULT_UI_CONTROLS: QueryBuilderUIControls = { isShowingQuestionInfoSidebar: false, isShowingTimelineSidebar: false, isNativeEditorOpen: false, - initialChartSetting: null, + initialChartSetting: {}, isShowingRawTable: false, // table/viz toggle queryBuilderMode: false, // "view" | "notebook" | "dataset" previousQueryBuilderMode: false, diff --git a/frontend/src/metabase/visualizations/components/ChartSettings/BaseChartSettings/BaseChartSettings.styled.tsx b/frontend/src/metabase/visualizations/components/ChartSettings/BaseChartSettings/BaseChartSettings.styled.tsx new file mode 100644 index 0000000000000000000000000000000000000000..15b760ef577cbef77c33b24d366782cfa3601ac7 --- /dev/null +++ b/frontend/src/metabase/visualizations/components/ChartSettings/BaseChartSettings/BaseChartSettings.styled.tsx @@ -0,0 +1,49 @@ +import { css } from "@emotion/react"; +import styled from "@emotion/styled"; + +import Radio from "metabase/core/components/Radio"; + +interface SectionContainerProps { + isDashboard: boolean; +} + +export const SectionContainer = styled.div<SectionContainerProps>` + ${({ isDashboard }) => + isDashboard && + css` + margin-top: 1rem; + `} + width: 100%; + + ${Radio.RadioGroupVariants.join(", ")} { + border-bottom: 1px solid var(--mb-color-border); + } + + ${Radio.RadioContainerVariants.join(", ")} { + padding-left: 0.5rem; + padding-right: 0.5rem; + } + + ${Radio.RadioLabelVariants.join(", ")} { + flex-grow: 1; + margin-right: 0; + display: flex; + justify-content: center; + + &:not(:last-child) { + margin-right: 0; + } + } +`; + +export const ChartSettingsMenu = styled.div` + flex: 1 0 0; + display: flex; + flex-direction: column; + overflow-y: auto; +`; + +export const ChartSettingsListContainer = styled.div` + position: relative; + padding: 1.5rem 0; +`; diff --git a/frontend/src/metabase/visualizations/components/ChartSettings/ChartSettings.tsx b/frontend/src/metabase/visualizations/components/ChartSettings/BaseChartSettings/BaseChartSettings.tsx similarity index 60% rename from frontend/src/metabase/visualizations/components/ChartSettings/ChartSettings.tsx rename to frontend/src/metabase/visualizations/components/ChartSettings/BaseChartSettings/BaseChartSettings.tsx index 7c62b16fd0161a569ab6db9a5bbda0c56ae8dd16..369bdcc9d9d89891225047929de076a3c3aada6c 100644 --- a/frontend/src/metabase/visualizations/components/ChartSettings/ChartSettings.tsx +++ b/frontend/src/metabase/visualizations/components/ChartSettings/BaseChartSettings/BaseChartSettings.tsx @@ -1,67 +1,43 @@ -import { assocIn } from "icepick"; -import { useCallback, useEffect, useMemo, useState } from "react"; +import { useCallback, useMemo, useState } from "react"; import { t } from "ttag"; import _ from "underscore"; import Radio from "metabase/core/components/Radio"; import CS from "metabase/css/core/index.css"; -import { - extractRemappings, - getVisualizationTransformed, -} from "metabase/visualizations"; -import { ChartSettingsFooter } from "metabase/visualizations/components/ChartSettings/ChartSettingsFooter"; -import Visualization from "metabase/visualizations/components/Visualization"; import { updateSeriesColor } from "metabase/visualizations/lib/series"; import { - getClickBehaviorSettings, getComputedSettings, getSettingsWidgets, - updateSettings, } from "metabase/visualizations/lib/settings"; import { getSettingDefinitionsForColumn } from "metabase/visualizations/lib/settings/column"; import { keyForSingleSeries } from "metabase/visualizations/lib/settings/series"; -import { getSettingsWidgetsForSeries } from "metabase/visualizations/lib/settings/visualization"; -import type Question from "metabase-lib/v1/Question"; import { getColumnKey } from "metabase-lib/v1/queries/utils/column-key"; -import type { DatasetColumn, VisualizationSettings } from "metabase-types/api"; +import type { DatasetColumn } from "metabase-types/api"; -import ChartSettingsWidgetList from "../ChartSettingsWidgetList"; -import ChartSettingsWidgetPopover from "../ChartSettingsWidgetPopover"; +import ChartSettingsWidgetList from "../../ChartSettingsWidgetList"; +import ChartSettingsWidgetPopover from "../../ChartSettingsWidgetPopover"; +import type { Widget } from "../types"; import { ChartSettingsListContainer, ChartSettingsMenu, - ChartSettingsPreview, - ChartSettingsRoot, - ChartSettingsVisualizationContainer, SectionContainer, - SectionWarnings, -} from "./ChartSettings.styled"; -import type { - ChartSettingsProps, - ChartSettingsWithStateProps, - Widget, -} from "./types"; +} from "./BaseChartSettings.styled"; +import type { BaseChartSettingsProps } from "./types"; // section names are localized const DEFAULT_TAB_PRIORITY = [t`Data`]; -export const ChartSettings = ({ +export const BaseChartSettings = ({ initial, - settings: propSettings, series, - computedSettings: propComputedSettings, + computedSettings = {}, onChange, - isDashboard = false, - noPreview = false, - dashboard, - dashcard, - onDone, - onClose, question, - className, - widgets: propWidgets, -}: ChartSettingsProps) => { + widgets, + chartSettings, + transformedSeries, +}: BaseChartSettingsProps) => { const [currentSection, setCurrentSection] = useState<string | null>( initial?.section ?? null, ); @@ -69,54 +45,6 @@ export const ChartSettings = ({ initial?.widget ?? null, ); const [popoverRef, setPopoverRef] = useState<HTMLElement | null>(); - const [warnings, setWarnings] = useState(); - - const chartSettings = useMemo( - () => propSettings || series[0].card.visualization_settings, - [series, propSettings], - ); - - const computedSettings = useMemo( - () => propComputedSettings || {}, - [propComputedSettings], - ); - - const handleChangeSettings = useCallback( - (changedSettings: VisualizationSettings, question: Question) => { - onChange?.(updateSettings(chartSettings, changedSettings), question); - }, - [chartSettings, onChange], - ); - - const chartSettingsRawSeries = useMemo( - () => assocIn(series, [0, "card", "visualization_settings"], chartSettings), - [chartSettings, series], - ); - - const transformedSeries = useMemo(() => { - const { series: transformedSeries } = getVisualizationTransformed( - extractRemappings(chartSettingsRawSeries), - ); - return transformedSeries; - }, [chartSettingsRawSeries]); - - const widgets = useMemo( - () => - propWidgets || - getSettingsWidgetsForSeries( - transformedSeries, - handleChangeSettings, - isDashboard, - { dashboardId: dashboard?.id }, - ), - [ - propWidgets, - transformedSeries, - handleChangeSettings, - isDashboard, - dashboard?.id, - ], - ); const columnHasSettings = useCallback( (col: DatasetColumn) => { @@ -176,7 +104,7 @@ export const ChartSettings = ({ return null; } - const singleSeriesForColumn = transformedSeries.find(single => { + const singleSeriesForColumn = transformedSeries?.find(single => { const metricColumn = single.data.cols[1]; if (metricColumn) { return ( @@ -230,32 +158,15 @@ export const ChartSettings = ({ setCurrentWidget(null); }, []); - const handleResetSettings = useCallback(() => { - const originalCardSettings = dashcard?.card.visualization_settings; - const clickBehaviorSettings = getClickBehaviorSettings(chartSettings); - - onChange?.({ - ...originalCardSettings, - ...clickBehaviorSettings, - }); - }, [chartSettings, dashcard?.card.visualization_settings, onChange]); - const handleChangeSeriesColor = useCallback( (seriesKey: string, color: string) => { - onChange?.(updateSeriesColor(chartSettings, seriesKey, color)); + if (chartSettings) { + onChange?.(updateSeriesColor(chartSettings, seriesKey, color)); + } }, [chartSettings, onChange], ); - const handleDone = useCallback(() => { - onDone?.(chartSettings); - onClose?.(); - }, [chartSettings, onClose, onDone]); - - const handleCancel = useCallback(() => { - onClose?.(); - }, [onClose]); - const sections: Record<string, Widget[]> = useMemo(() => { const sectionObj: Record<string, Widget[]> = {}; for (const widget of widgets) { @@ -316,12 +227,6 @@ export const ChartSettings = ({ onChangeSeriesColor: handleChangeSeriesColor, }; - const onResetToDefault = - // resetting virtual cards wipes the text and broke the UI (metabase#14644) - !_.isEqual(chartSettings, {}) && (chartSettings || {}).virtual_card == null - ? handleResetSettings - : null; - const showSectionPicker = // don't show section tabs for a single section sectionNames.length > 1 && @@ -334,7 +239,7 @@ export const ChartSettings = ({ ); return ( - <ChartSettingsRoot className={className}> + <> <ChartSettingsMenu data-testid="chartsettings-sidebar"> {showSectionPicker && ( <SectionContainer isDashboard={false}> @@ -356,31 +261,6 @@ export const ChartSettings = ({ /> </ChartSettingsListContainer> </ChartSettingsMenu> - {!noPreview && ( - <ChartSettingsPreview> - <SectionWarnings warnings={warnings} size={20} /> - <ChartSettingsVisualizationContainer> - <Visualization - className={CS.spread} - rawSeries={chartSettingsRawSeries} - showTitle - isEditing - isDashboard - dashboard={dashboard} - dashcard={dashcard} - isSettings - showWarnings - onUpdateVisualizationSettings={handleChangeSettings} - onUpdateWarnings={setWarnings} - /> - </ChartSettingsVisualizationContainer> - <ChartSettingsFooter - onDone={handleDone} - onCancel={handleCancel} - onReset={onResetToDefault} - /> - </ChartSettingsPreview> - )} <ChartSettingsWidgetPopover anchor={popoverRef as HTMLElement} widgets={[styleWidget, formattingWidget].filter( @@ -388,28 +268,6 @@ export const ChartSettings = ({ )} handleEndShowWidget={handleEndShowWidget} /> - </ChartSettingsRoot> - ); -}; - -export const ChartSettingsWithState = (props: ChartSettingsWithStateProps) => { - const [tempSettings, setTempSettings] = useState(props.settings); - - useEffect(() => { - if (props.settings) { - setTempSettings(props.settings); - } - }, [props.settings]); - - const onDone = (settings: VisualizationSettings) => - props.onChange?.(settings ?? tempSettings); - - return ( - <ChartSettings - {...props} - onChange={setTempSettings} - onDone={onDone} - settings={tempSettings} - /> + </> ); }; diff --git a/frontend/src/metabase/visualizations/components/ChartSettings/ChartSettings.unit.spec.tsx b/frontend/src/metabase/visualizations/components/ChartSettings/BaseChartSettings/BaseChartSettings.unit.spec.tsx similarity index 71% rename from frontend/src/metabase/visualizations/components/ChartSettings/ChartSettings.unit.spec.tsx rename to frontend/src/metabase/visualizations/components/ChartSettings/BaseChartSettings/BaseChartSettings.unit.spec.tsx index 583c395ed5d15aae2141ac7af1a32e1b612a2c18..e2324736b5489eb9c9bfe05511ed2723e83812d3 100644 --- a/frontend/src/metabase/visualizations/components/ChartSettings/ChartSettings.unit.spec.tsx +++ b/frontend/src/metabase/visualizations/components/ChartSettings/BaseChartSettings/BaseChartSettings.unit.spec.tsx @@ -1,20 +1,16 @@ -import userEvent from "@testing-library/user-event"; - import { fireEvent, renderWithProviders, screen } from "__support__/ui"; import registerVisualizations from "metabase/visualizations/register"; -import { - createMockCard, - createMockDashboardCard, - createMockDataset, - createMockVisualizationSettings, -} from "metabase-types/api/mocks"; +import { createMockCard, createMockDataset } from "metabase-types/api/mocks"; + +import type { Widget } from "../types"; -import { ChartSettings } from "./ChartSettings"; -import type { ChartSettingsProps, Widget } from "./types"; +import { BaseChartSettings } from "./BaseChartSettings"; +import type { BaseChartSettingsProps } from "./types"; registerVisualizations(); const DEFAULT_PROPS = { + widgets: [], series: [ { card: createMockCard({ visualization_settings: {} }), @@ -35,10 +31,12 @@ function widget(widget: Partial<Widget> = {}): Widget { }; } -type SetupOpts = Partial<ChartSettingsProps>; +type SetupOpts = Partial<BaseChartSettingsProps>; const setup = (props: SetupOpts) => { - return renderWithProviders(<ChartSettings {...DEFAULT_PROPS} {...props} />); + return renderWithProviders( + <BaseChartSettings {...DEFAULT_PROPS} {...props} />, + ); }; describe("ChartSettings", () => { @@ -134,42 +132,4 @@ describe("ChartSettings", () => { expect(screen.queryByText("Foo")).not.toBeInTheDocument(); }); - - it("reset settings should revert to the original card settings with click behavior", async () => { - const onChange = jest.fn(); - - const originalVizSettings = createMockVisualizationSettings({ - "graph.goal_value": 100, - "graph.show_goal": true, - "graph.goal_label": "foo", - }); - - const modifiedSettings = createMockVisualizationSettings({ - "graph.show_goal": false, - "graph.goal_label": "bar", - click_behavior: { - type: "link", - linkType: "url", - }, - }); - - setup({ - dashcard: createMockDashboardCard({ - card: createMockCard({ visualization_settings: originalVizSettings }), - }), - settings: modifiedSettings, - widgets: [], - onChange, - }); - - await userEvent.click(screen.getByText("Reset to defaults")); - - expect(onChange).toHaveBeenCalledWith({ - ...originalVizSettings, - click_behavior: { - type: "link", - linkType: "url", - }, - }); - }); }); diff --git a/frontend/src/metabase/visualizations/components/ChartSettings/BaseChartSettings/index.ts b/frontend/src/metabase/visualizations/components/ChartSettings/BaseChartSettings/index.ts new file mode 100644 index 0000000000000000000000000000000000000000..f53411d9751f79b1a18533a2a3bc5b90428542dc --- /dev/null +++ b/frontend/src/metabase/visualizations/components/ChartSettings/BaseChartSettings/index.ts @@ -0,0 +1 @@ +export * from "./BaseChartSettings"; diff --git a/frontend/src/metabase/visualizations/components/ChartSettings/BaseChartSettings/types.ts b/frontend/src/metabase/visualizations/components/ChartSettings/BaseChartSettings/types.ts new file mode 100644 index 0000000000000000000000000000000000000000..a0ca3979cfe572c3d5f1bcf9bb0f1e5b53f7e253 --- /dev/null +++ b/frontend/src/metabase/visualizations/components/ChartSettings/BaseChartSettings/types.ts @@ -0,0 +1,14 @@ +import type { ComputedVisualizationSettings } from "metabase/visualizations/types"; +import type Question from "metabase-lib/v1/Question"; +import type { QueryBuilderUIControls } from "metabase-types/store"; + +import type { UseChartSettingsStateReturned } from "../hooks"; +import type { CommonChartSettingsProps, Widget } from "../types"; + +export type BaseChartSettingsProps = { + initial?: QueryBuilderUIControls["initialChartSetting"]; + computedSettings?: ComputedVisualizationSettings; + question?: Question; + widgets: Widget[]; +} & CommonChartSettingsProps & + Pick<UseChartSettingsStateReturned, "chartSettings" | "transformedSeries">; diff --git a/frontend/src/metabase/visualizations/components/ChartSettings/ChartSettings.styled.tsx b/frontend/src/metabase/visualizations/components/ChartSettings/ChartSettings.styled.tsx index 2784285ef6e6ab2a3662db9611e5472515d2fb19..c3ba9ea353ee2cebc825ad38c04a20b975832853 100644 --- a/frontend/src/metabase/visualizations/components/ChartSettings/ChartSettings.styled.tsx +++ b/frontend/src/metabase/visualizations/components/ChartSettings/ChartSettings.styled.tsx @@ -1,85 +1,7 @@ -import { css } from "@emotion/react"; import styled from "@emotion/styled"; -import Button from "metabase/core/components/Button"; -import Radio from "metabase/core/components/Radio"; -import { color } from "metabase/lib/colors"; -import Warnings from "metabase/query_builder/components/Warnings"; - -interface SectionContainerProps { - isDashboard: boolean; -} -export const SectionContainer = styled.div<SectionContainerProps>` - ${({ isDashboard }) => - isDashboard && - css` - margin-top: 1rem; - `} - width: 100%; - ${Radio.RadioGroupVariants.join(", ")} { - border-bottom: 1px solid var(--mb-color-border); - } - ${Radio.RadioContainerVariants.join(", ")} { - padding-left: 0.5rem; - padding-right: 0.5rem; - } - ${Radio.RadioLabelVariants.join(", ")} { - flex-grow: 1; - margin-right: 0; - display: flex; - justify-content: center; - - &:not(:last-child) { - margin-right: 0; - } - } -`; - -export const SectionWarnings = styled(Warnings)` - color: ${() => color("accent4")}; - position: absolute; - top: 2rem; - right: 2rem; - z-index: 2; -`; - export const ChartSettingsRoot = styled.div` display: flex; flex-grow: 1; height: 100%; `; - -export const ChartSettingsMenu = styled.div` - flex: 1 0 0; - display: flex; - flex-direction: column; - overflow-y: auto; -`; - -export const ChartSettingsListContainer = styled.div` - position: relative; - padding: 1.5rem 0; -`; - -export const ChartSettingsPreview = styled.div` - flex: 2 0 0; - display: flex; - flex-direction: column; - border-left: 1px solid var(--mb-color-border); - padding-top: 1.5rem; -`; - -export const ChartSettingsVisualizationContainer = styled.div` - position: relative; - margin: 0 2rem; - flex-grow: 1; -`; - -export const ChartSettingsFooterRoot = styled.div` - display: flex; - justify-content: end; - padding: 1rem 2rem; - ${Button} { - margin-left: 1rem; - } -`; diff --git a/frontend/src/metabase/visualizations/components/ChartSettings/ChartSettingsFooter/ChartSettingsFooter.styled.tsx b/frontend/src/metabase/visualizations/components/ChartSettings/ChartSettingsFooter/ChartSettingsFooter.styled.tsx new file mode 100644 index 0000000000000000000000000000000000000000..a2af738edb0ef7aa1f82d75a9b597c39c94dfbed --- /dev/null +++ b/frontend/src/metabase/visualizations/components/ChartSettings/ChartSettingsFooter/ChartSettingsFooter.styled.tsx @@ -0,0 +1,12 @@ +import styled from "@emotion/styled"; + +import Button from "metabase/core/components/Button"; + +export const ChartSettingsFooterRoot = styled.div` + display: flex; + justify-content: end; + padding: 1rem 2rem; + ${Button} { + margin-left: 1rem; + } +`; diff --git a/frontend/src/metabase/visualizations/components/ChartSettings/ChartSettingsFooter.tsx b/frontend/src/metabase/visualizations/components/ChartSettings/ChartSettingsFooter/ChartSettingsFooter.tsx similarity index 83% rename from frontend/src/metabase/visualizations/components/ChartSettings/ChartSettingsFooter.tsx rename to frontend/src/metabase/visualizations/components/ChartSettings/ChartSettingsFooter/ChartSettingsFooter.tsx index 19a76b704762ae6072d4983df91f775cc1fa51ac..bafe5d53ef47835160ec72c0775e56e22e70be9b 100644 --- a/frontend/src/metabase/visualizations/components/ChartSettings/ChartSettingsFooter.tsx +++ b/frontend/src/metabase/visualizations/components/ChartSettings/ChartSettingsFooter/ChartSettingsFooter.tsx @@ -2,9 +2,9 @@ import { t } from "ttag"; import Button from "metabase/core/components/Button"; -import { ChartSettingsFooterRoot } from "./ChartSettings.styled"; +import { ChartSettingsFooterRoot } from "./ChartSettingsFooter.styled"; -type ChartSettingsFooterProps = { +export type ChartSettingsFooterProps = { onDone: () => void; onCancel: () => void; onReset: (() => void) | null; diff --git a/frontend/src/metabase/visualizations/components/ChartSettings/ChartSettingsFooter/index.ts b/frontend/src/metabase/visualizations/components/ChartSettings/ChartSettingsFooter/index.ts new file mode 100644 index 0000000000000000000000000000000000000000..b30f29c2326a4ceb7a2f9f2e702e23db9afb46e1 --- /dev/null +++ b/frontend/src/metabase/visualizations/components/ChartSettings/ChartSettingsFooter/index.ts @@ -0,0 +1 @@ +export * from "./ChartSettingsFooter"; diff --git a/frontend/src/metabase/visualizations/components/ChartSettings/ChartSettingsVisualization/ChartSettingsVisualization.styled.tsx b/frontend/src/metabase/visualizations/components/ChartSettings/ChartSettingsVisualization/ChartSettingsVisualization.styled.tsx new file mode 100644 index 0000000000000000000000000000000000000000..5d314dc5ed52dc8848d0f00e9b36850f96371491 --- /dev/null +++ b/frontend/src/metabase/visualizations/components/ChartSettings/ChartSettingsVisualization/ChartSettingsVisualization.styled.tsx @@ -0,0 +1,26 @@ +import styled from "@emotion/styled"; + +import { color } from "metabase/lib/colors"; +import Warnings from "metabase/query_builder/components/Warnings"; + +export const SectionWarnings = styled(Warnings)` + color: ${() => color("accent4")}; + position: absolute; + top: 2rem; + right: 2rem; + z-index: 2; +`; + +export const ChartSettingsPreview = styled.div` + flex: 2 0 0; + display: flex; + flex-direction: column; + border-left: 1px solid var(--mb-color-border); + padding-top: 1.5rem; +`; + +export const ChartSettingsVisualizationContainer = styled.div` + position: relative; + margin: 0 2rem; + flex-grow: 1; +`; diff --git a/frontend/src/metabase/visualizations/components/ChartSettings/ChartSettingsVisualization/ChartSettingsVisualization.tsx b/frontend/src/metabase/visualizations/components/ChartSettings/ChartSettingsVisualization/ChartSettingsVisualization.tsx new file mode 100644 index 0000000000000000000000000000000000000000..084bf20b24e798f2d7c65962c481d14af53b4285 --- /dev/null +++ b/frontend/src/metabase/visualizations/components/ChartSettings/ChartSettingsVisualization/ChartSettingsVisualization.tsx @@ -0,0 +1,51 @@ +import { useState } from "react"; + +import CS from "metabase/css/core/index.css"; +import Visualization from "metabase/visualizations/components/Visualization"; + +import { ChartSettingsFooter } from "../ChartSettingsFooter"; + +import { + ChartSettingsPreview, + ChartSettingsVisualizationContainer, + SectionWarnings, +} from "./ChartSettingsVisualization.styled"; +import type { ChartSettingsVisualizationProps } from "./types"; + +export const ChartSettingsVisualization = ({ + dashboard, + dashcard, + onCancel, + onDone, + onReset, + onUpdateVisualizationSettings, + rawSeries, +}: ChartSettingsVisualizationProps) => { + const [warnings, setWarnings] = useState<string[]>(); + + return ( + <ChartSettingsPreview> + <SectionWarnings warnings={warnings} size={20} /> + <ChartSettingsVisualizationContainer> + <Visualization + className={CS.spread} + rawSeries={rawSeries} + showTitle + isEditing + isDashboard + dashboard={dashboard} + dashcard={dashcard} + isSettings + showWarnings + onUpdateVisualizationSettings={onUpdateVisualizationSettings} + onUpdateWarnings={setWarnings} + /> + </ChartSettingsVisualizationContainer> + <ChartSettingsFooter + onDone={onDone} + onCancel={onCancel} + onReset={onReset} + /> + </ChartSettingsPreview> + ); +}; diff --git a/frontend/src/metabase/visualizations/components/ChartSettings/ChartSettingsVisualization/index.ts b/frontend/src/metabase/visualizations/components/ChartSettings/ChartSettingsVisualization/index.ts new file mode 100644 index 0000000000000000000000000000000000000000..893520319a25aafb56ca01c8ce9f08dd33ed18e5 --- /dev/null +++ b/frontend/src/metabase/visualizations/components/ChartSettings/ChartSettingsVisualization/index.ts @@ -0,0 +1 @@ +export * from "./ChartSettingsVisualization"; diff --git a/frontend/src/metabase/visualizations/components/ChartSettings/ChartSettingsVisualization/types.ts b/frontend/src/metabase/visualizations/components/ChartSettings/ChartSettingsVisualization/types.ts new file mode 100644 index 0000000000000000000000000000000000000000..6cfe13d8b42fca13d515f0dc845337bc18a22843 --- /dev/null +++ b/frontend/src/metabase/visualizations/components/ChartSettings/ChartSettingsVisualization/types.ts @@ -0,0 +1,19 @@ +import type Question from "metabase-lib/v1/Question"; +import type { + Dashboard, + DashboardCard, + RawSeries, + VisualizationSettings, +} from "metabase-types/api"; + +import type { ChartSettingsFooterProps } from "../ChartSettingsFooter"; + +export type ChartSettingsVisualizationProps = { + rawSeries: RawSeries; + dashboard?: Dashboard; + dashcard?: DashboardCard; + onUpdateVisualizationSettings: ( + changedSettings: VisualizationSettings, + question: Question, + ) => void; +} & ChartSettingsFooterProps; diff --git a/frontend/src/metabase/visualizations/components/ChartSettings/DashboardChartSettings/DashboardChartSettings.tsx b/frontend/src/metabase/visualizations/components/ChartSettings/DashboardChartSettings/DashboardChartSettings.tsx new file mode 100644 index 0000000000000000000000000000000000000000..0fd9022967e4f13b99870a983bd249e57d4655f2 --- /dev/null +++ b/frontend/src/metabase/visualizations/components/ChartSettings/DashboardChartSettings/DashboardChartSettings.tsx @@ -0,0 +1,93 @@ +import { useCallback, useMemo, useState } from "react"; +import _ from "underscore"; + +import CS from "metabase/css/core/index.css"; +import { getClickBehaviorSettings } from "metabase/visualizations/lib/settings"; +import { getSettingsWidgetsForSeries } from "metabase/visualizations/lib/settings/visualization"; +import type { VisualizationSettings } from "metabase-types/api"; + +import { BaseChartSettings } from "../BaseChartSettings"; +import { ChartSettingsRoot } from "../ChartSettings.styled"; +import { ChartSettingsVisualization } from "../ChartSettingsVisualization"; +import { useChartSettingsState } from "../hooks"; + +import type { DashboardChartSettingsProps } from "./types"; + +export const DashboardChartSettings = ({ + dashboard, + dashcard, + onChange, + series, + onClose, + widgets: propWidgets, + settings, +}: DashboardChartSettingsProps) => { + const [tempSettings, setTempSettings] = useState< + VisualizationSettings | undefined + >(settings); + + const { + chartSettings, + handleChangeSettings, + chartSettingsRawSeries, + transformedSeries, + } = useChartSettingsState({ + series, + settings: tempSettings, + onChange: setTempSettings, + }); + + const handleDone = useCallback(() => { + onChange?.(chartSettings ?? tempSettings ?? {}); + onClose?.(); + }, [chartSettings, onChange, onClose, tempSettings]); + + const handleResetSettings = useCallback(() => { + const originalCardSettings = dashcard?.card.visualization_settings; + const clickBehaviorSettings = getClickBehaviorSettings(chartSettings); + + onChange?.({ + ...originalCardSettings, + ...clickBehaviorSettings, + }); + }, [chartSettings, dashcard?.card.visualization_settings, onChange]); + + const onResetToDefault = + // resetting virtual cards wipes the text and broke the UI (metabase#14644) + !_.isEqual(chartSettings, {}) && (chartSettings || {}).virtual_card == null + ? handleResetSettings + : null; + + const widgets = useMemo( + () => + propWidgets || + getSettingsWidgetsForSeries( + transformedSeries, + handleChangeSettings, + true, + { dashboardId: dashboard?.id }, + ), + [propWidgets, transformedSeries, handleChangeSettings, dashboard?.id], + ); + + return ( + <ChartSettingsRoot className={CS.spread}> + <BaseChartSettings + series={series} + onChange={setTempSettings} + chartSettings={chartSettings} + widgets={widgets} + transformedSeries={transformedSeries} + /> + <ChartSettingsVisualization + rawSeries={chartSettingsRawSeries} + dashboard={dashboard} + dashcard={dashcard} + onUpdateVisualizationSettings={handleChangeSettings} + onDone={handleDone} + onCancel={() => onClose?.()} + onReset={onResetToDefault} + /> + </ChartSettingsRoot> + ); +}; diff --git a/frontend/src/metabase/visualizations/components/ChartSettings/DashboardChartSettings/DashboardChartSettings.unit.spec.tsx b/frontend/src/metabase/visualizations/components/ChartSettings/DashboardChartSettings/DashboardChartSettings.unit.spec.tsx new file mode 100644 index 0000000000000000000000000000000000000000..f173862d6ca9c6e43c6e6a85550c4d78ba98adcd --- /dev/null +++ b/frontend/src/metabase/visualizations/components/ChartSettings/DashboardChartSettings/DashboardChartSettings.unit.spec.tsx @@ -0,0 +1,74 @@ +import userEvent from "@testing-library/user-event"; + +import { renderWithProviders, screen } from "__support__/ui"; +import registerVisualizations from "metabase/visualizations/register"; +import { + createMockCard, + createMockDashboardCard, + createMockDataset, + createMockVisualizationSettings, +} from "metabase-types/api/mocks"; + +import { DashboardChartSettings } from "./DashboardChartSettings"; +import type { DashboardChartSettingsProps } from "./types"; + +registerVisualizations(); + +const DEFAULT_PROPS = { + widgets: [], + series: [ + { + card: createMockCard({ visualization_settings: {} }), + ...createMockDataset({ data: { rows: [], cols: [] } }), + }, + ], + settings: {}, +}; + +type SetupOpts = Partial<DashboardChartSettingsProps>; + +const setup = (props: SetupOpts) => { + return renderWithProviders( + <DashboardChartSettings {...DEFAULT_PROPS} {...props} />, + ); +}; + +describe("DashboardChartSettings", () => { + it("reset settings should revert to the original card settings with click behavior", async () => { + const onChange = jest.fn(); + + const originalVizSettings = createMockVisualizationSettings({ + "graph.goal_value": 100, + "graph.show_goal": true, + "graph.goal_label": "foo", + }); + + const modifiedSettings = createMockVisualizationSettings({ + "graph.show_goal": false, + "graph.goal_label": "bar", + click_behavior: { + type: "link", + linkType: "url", + }, + }); + + setup({ + dashcard: createMockDashboardCard({ + card: createMockCard({ visualization_settings: originalVizSettings }), + }), + settings: modifiedSettings, + widgets: [], + onChange, + }); + + await userEvent.click(screen.getByText("Reset to defaults")); + + expect(onChange).toHaveBeenCalledWith({ + ...originalVizSettings, + click_behavior: { + type: "link", + linkType: "url", + }, + }); + }); +}); diff --git a/frontend/src/metabase/visualizations/components/ChartSettings/DashboardChartSettings/index.ts b/frontend/src/metabase/visualizations/components/ChartSettings/DashboardChartSettings/index.ts new file mode 100644 index 0000000000000000000000000000000000000000..ac228428c333cd44bba9f61e340828877672c197 --- /dev/null +++ b/frontend/src/metabase/visualizations/components/ChartSettings/DashboardChartSettings/index.ts @@ -0,0 +1 @@ +export * from "./DashboardChartSettings"; diff --git a/frontend/src/metabase/visualizations/components/ChartSettings/DashboardChartSettings/types.ts b/frontend/src/metabase/visualizations/components/ChartSettings/DashboardChartSettings/types.ts new file mode 100644 index 0000000000000000000000000000000000000000..3702093f9c4f70b28cb7a4e9a98cbf10f794874d --- /dev/null +++ b/frontend/src/metabase/visualizations/components/ChartSettings/DashboardChartSettings/types.ts @@ -0,0 +1,23 @@ +import type { + Dashboard, + DashboardCard, + VisualizationSettings, +} from "metabase-types/api"; + +import type { + BaseChartSettingsTestProps, + CommonChartSettingsProps, +} from "../types"; + +export type DashboardChartSettingsProps = { + className?: string; + dashboard?: Dashboard; + dashcard?: DashboardCard; + isDashboard?: boolean; + onClose?: () => void; +} & CommonChartSettingsProps & + DashboardChartSettingsTestProps; + +export type DashboardChartSettingsTestProps = BaseChartSettingsTestProps & { + settings?: VisualizationSettings; +}; diff --git a/frontend/src/metabase/visualizations/components/ChartSettings/QuestionChartSettings/QuestionChartSettings.tsx b/frontend/src/metabase/visualizations/components/ChartSettings/QuestionChartSettings/QuestionChartSettings.tsx new file mode 100644 index 0000000000000000000000000000000000000000..19e052663a594df896256e6e59c328cdf5c27bdc --- /dev/null +++ b/frontend/src/metabase/visualizations/components/ChartSettings/QuestionChartSettings/QuestionChartSettings.tsx @@ -0,0 +1,47 @@ +import { useMemo } from "react"; + +import { getSettingsWidgetsForSeries } from "metabase/visualizations/lib/settings/visualization"; + +import { BaseChartSettings } from "../BaseChartSettings"; +import { ChartSettingsRoot } from "../ChartSettings.styled"; +import { useChartSettingsState } from "../hooks"; + +import type { QuestionChartSettingsProps } from "./types"; + +export const QuestionChartSettings = ({ + question, + widgets: propWidgets, + series, + onChange, + computedSettings, + initial, +}: QuestionChartSettingsProps) => { + const { chartSettings, handleChangeSettings, transformedSeries } = + useChartSettingsState({ series, onChange }); + + const widgets = useMemo( + () => + propWidgets || + getSettingsWidgetsForSeries( + transformedSeries, + handleChangeSettings, + false, + ), + [propWidgets, transformedSeries, handleChangeSettings], + ); + + return ( + <ChartSettingsRoot> + <BaseChartSettings + question={question} + series={series} + onChange={onChange} + initial={initial} + computedSettings={computedSettings} + chartSettings={chartSettings} + transformedSeries={transformedSeries} + widgets={widgets} + /> + </ChartSettingsRoot> + ); +}; diff --git a/frontend/src/metabase/visualizations/components/ChartSettings/QuestionChartSettings/index.ts b/frontend/src/metabase/visualizations/components/ChartSettings/QuestionChartSettings/index.ts new file mode 100644 index 0000000000000000000000000000000000000000..701b0d86bb5dfedb776e139d8313aff807d50ba0 --- /dev/null +++ b/frontend/src/metabase/visualizations/components/ChartSettings/QuestionChartSettings/index.ts @@ -0,0 +1 @@ +export * from "./QuestionChartSettings"; diff --git a/frontend/src/metabase/visualizations/components/ChartSettings/QuestionChartSettings/types.ts b/frontend/src/metabase/visualizations/components/ChartSettings/QuestionChartSettings/types.ts new file mode 100644 index 0000000000000000000000000000000000000000..fd6a45a1aaa3c4c7345d70b836da77d04ac4a63d --- /dev/null +++ b/frontend/src/metabase/visualizations/components/ChartSettings/QuestionChartSettings/types.ts @@ -0,0 +1,9 @@ +import type { BaseChartSettingsProps } from "../BaseChartSettings/types"; +import type { + BaseChartSettingsTestProps, + CommonChartSettingsProps, +} from "../types"; + +export type QuestionChartSettingsProps = CommonChartSettingsProps & + Pick<BaseChartSettingsProps, "initial" | "computedSettings" | "question"> & + BaseChartSettingsTestProps; diff --git a/frontend/src/metabase/visualizations/components/ChartSettings/hooks.ts b/frontend/src/metabase/visualizations/components/ChartSettings/hooks.ts new file mode 100644 index 0000000000000000000000000000000000000000..5cd66d8797e17afa14d5663b98c665ffc09b6ab0 --- /dev/null +++ b/frontend/src/metabase/visualizations/components/ChartSettings/hooks.ts @@ -0,0 +1,72 @@ +import { assocIn } from "icepick"; +import { useCallback, useMemo } from "react"; + +import { + extractRemappings, + getVisualizationTransformed, +} from "metabase/visualizations"; +import { updateSettings } from "metabase/visualizations/lib/settings"; +import type { ComputedVisualizationSettings } from "metabase/visualizations/types"; +import type Question from "metabase-lib/v1/Question"; +import type { + RawSeries, + Series, + TransformedSeries, + VisualizationSettings, +} from "metabase-types/api"; + +export type UseChartSettingsStateProps = { + settings?: VisualizationSettings; + series: Series; + onChange?: ( + settings: ComputedVisualizationSettings, + question?: Question, + ) => void; +}; + +export type UseChartSettingsStateReturned = { + chartSettings?: VisualizationSettings; + handleChangeSettings: ( + changedSettings: VisualizationSettings, + question: Question, + ) => void; + chartSettingsRawSeries: Series; + transformedSeries?: RawSeries | TransformedSeries; +}; + +export const useChartSettingsState = ({ + settings, + series, + onChange, +}: UseChartSettingsStateProps): UseChartSettingsStateReturned => { + const chartSettings = useMemo( + () => settings || series[0].card.visualization_settings, + [series, settings], + ); + + const handleChangeSettings = useCallback( + (changedSettings: VisualizationSettings, question: Question) => { + onChange?.(updateSettings(chartSettings, changedSettings), question); + }, + [chartSettings, onChange], + ); + + const chartSettingsRawSeries = useMemo( + () => assocIn(series, [0, "card", "visualization_settings"], chartSettings), + [chartSettings, series], + ); + + const transformedSeries = useMemo(() => { + const { series: transformedSeries } = getVisualizationTransformed( + extractRemappings(chartSettingsRawSeries), + ); + return transformedSeries; + }, [chartSettingsRawSeries]); + + return { + chartSettings, + handleChangeSettings, + chartSettingsRawSeries, + transformedSeries, + }; +}; diff --git a/frontend/src/metabase/visualizations/components/ChartSettings/index.ts b/frontend/src/metabase/visualizations/components/ChartSettings/index.ts index 50271a0d71d347e1353cfdfe1439e2ad69636c70..18f9a175a50e1f3e32025c06c929c8bf762358d7 100644 --- a/frontend/src/metabase/visualizations/components/ChartSettings/index.ts +++ b/frontend/src/metabase/visualizations/components/ChartSettings/index.ts @@ -1 +1,2 @@ -export * from "./ChartSettings"; +export { QuestionChartSettings } from "./QuestionChartSettings"; +export { DashboardChartSettings } from "./DashboardChartSettings"; diff --git a/frontend/src/metabase/visualizations/components/ChartSettings/types.ts b/frontend/src/metabase/visualizations/components/ChartSettings/types.ts index d3db2bfe55fd9693a88ba87c94df11ad444a4cf1..dbd1fdeaeed93becd322ab87365f52c67bc25cc4 100644 --- a/frontend/src/metabase/visualizations/components/ChartSettings/types.ts +++ b/frontend/src/metabase/visualizations/components/ChartSettings/types.ts @@ -1,11 +1,5 @@ -import type { ComputedVisualizationSettings } from "metabase/visualizations/types"; import type Question from "metabase-lib/v1/Question"; -import type { - Dashboard, - DashboardCard, - Series, - VisualizationSettings, -} from "metabase-types/api"; +import type { Series, VisualizationSettings } from "metabase-types/api"; // this type is not full, we need to extend it later export type Widget = { @@ -17,29 +11,12 @@ export type Widget = { widget: (() => JSX.Element | null) | undefined; }; -export type ChartSettingsWithStateProps = { - className?: string; - isDashboard?: boolean; - dashboard?: Dashboard; - dashcard?: DashboardCard; - initial?: { - section: string; - widget?: Widget; - }; - onClose?: () => void; +export type CommonChartSettingsProps = { series: Series; - computedSettings?: ComputedVisualizationSettings; - question?: Question; - noPreview?: boolean; - widgets?: Widget[]; - - onChange?: ( - settings: ComputedVisualizationSettings, - question?: Question, - ) => void; - settings?: VisualizationSettings; + onChange?: (settings: VisualizationSettings, question?: Question) => void; }; -export type ChartSettingsProps = ChartSettingsWithStateProps & { - onDone?: (settings: VisualizationSettings) => void; +// Only used for the tests in ChartSettings.unit.spec.tsx +export type BaseChartSettingsTestProps = { + widgets?: Widget[]; }; diff --git a/frontend/src/metabase/visualizations/components/settings/ChartNestedSettingsSeriesMultiple.unit.spec.js b/frontend/src/metabase/visualizations/components/settings/ChartNestedSettingsSeriesMultiple.unit.spec.js index dd85bd52d421d0f2e921e87a0e0bd56c68407133..b80149364c3316be6d67935fcfebfcf6c60aa1e9 100644 --- a/frontend/src/metabase/visualizations/components/settings/ChartNestedSettingsSeriesMultiple.unit.spec.js +++ b/frontend/src/metabase/visualizations/components/settings/ChartNestedSettingsSeriesMultiple.unit.spec.js @@ -2,7 +2,7 @@ import userEvent from "@testing-library/user-event"; import { renderWithProviders, screen, within } from "__support__/ui"; -import { ChartSettings } from "metabase/visualizations/components/ChartSettings"; +import { DashboardChartSettings } from "metabase/visualizations/components/ChartSettings"; import registerVisualizations from "metabase/visualizations/register"; import { createMockCard } from "metabase-types/api/mocks"; @@ -36,7 +36,7 @@ const setup = (seriesDisplay, numberOfSeries = 1, changeSeriesName = false) => { .fill(1) .map((s, index) => getSeries(seriesDisplay, index, changeSeriesName)); return renderWithProviders( - <ChartSettings + <DashboardChartSettings series={series} initial={{ section: "Display" }} isDashboard={true} diff --git a/frontend/src/metabase/visualizations/components/settings/ChartSettingFieldPicker.unit.spec.js b/frontend/src/metabase/visualizations/components/settings/ChartSettingFieldPicker.unit.spec.js index ef81f1493ce72ec14b24bd67ad701d10afb13245..445066de9c3587d02f33badeaa6ab52916b5e8b5 100644 --- a/frontend/src/metabase/visualizations/components/settings/ChartSettingFieldPicker.unit.spec.js +++ b/frontend/src/metabase/visualizations/components/settings/ChartSettingFieldPicker.unit.spec.js @@ -1,8 +1,8 @@ -// these tests use ChartSettings directly, but logic we're testing logic in ChartSettingFieldPicker +// these tests use QuestionChartSettings directly, but logic we're testing logic in ChartSettingFieldPicker import { within } from "@testing-library/react"; import { renderWithProviders, screen } from "__support__/ui"; -import { ChartSettings } from "metabase/visualizations/components/ChartSettings"; +import { QuestionChartSettings } from "metabase/visualizations/components/ChartSettings"; import registerVisualizations from "metabase/visualizations/register"; import { createMockCard } from "metabase-types/api/mocks"; @@ -48,7 +48,7 @@ function getSeries(metricColumnProps) { const setup = seriesDisplay => { const series = getSeries(seriesDisplay); return renderWithProviders( - <ChartSettings series={series} initial={{ section: "Data" }} />, + <QuestionChartSettings series={series} initial={{ section: "Data" }} />, ); }; diff --git a/frontend/src/metabase/visualizations/components/settings/ChartSettingStacked.unit.spec.js b/frontend/src/metabase/visualizations/components/settings/ChartSettingStacked.unit.spec.js index 479cda507ed275a20a1f60541a4c0dc57209a208..9369f03b50568dd009d3f0bf937494198b3b00dc 100644 --- a/frontend/src/metabase/visualizations/components/settings/ChartSettingStacked.unit.spec.js +++ b/frontend/src/metabase/visualizations/components/settings/ChartSettingStacked.unit.spec.js @@ -1,6 +1,6 @@ -// these tests use ChartSettings directly, but logic we're testing lives in ChartNestedSettingSeries +// these tests use QuestionChartSettings directly, but logic we're testing lives in ChartNestedSettingSeries import { renderWithProviders, screen } from "__support__/ui"; -import { ChartSettings } from "metabase/visualizations/components/ChartSettings"; +import { QuestionChartSettings } from "metabase/visualizations/components/ChartSettings"; import registerVisualizations from "metabase/visualizations/register"; registerVisualizations(); @@ -82,7 +82,7 @@ function getSeries(metrics) { const setup = seriesMetrics => { return renderWithProviders( - <ChartSettings + <QuestionChartSettings series={getSeries(seriesMetrics)} initial={{ section: "Display" }} />, diff --git a/frontend/src/metabase/visualizations/visualizations/BarChart.unit.spec.tsx b/frontend/src/metabase/visualizations/visualizations/BarChart.unit.spec.tsx index a628c711646a09c06b659bc9baec28e8f4ab8e67..064bcb79dec3a9c7d0109a928c4695d3b9f40c2f 100644 --- a/frontend/src/metabase/visualizations/visualizations/BarChart.unit.spec.tsx +++ b/frontend/src/metabase/visualizations/visualizations/BarChart.unit.spec.tsx @@ -1,6 +1,6 @@ import { createMockMetadata } from "__support__/metadata"; import { renderWithProviders, screen } from "__support__/ui"; -import { ChartSettings } from "metabase/visualizations/components/ChartSettings"; +import { QuestionChartSettings } from "metabase/visualizations/components/ChartSettings"; import registerVisualizations from "metabase/visualizations/register"; import Question from "metabase-lib/v1/Question"; import type { Series } from "metabase-types/api"; @@ -24,11 +24,10 @@ interface SetupProps { const setup = ({ series, question }: SetupProps) => { renderWithProviders( - <ChartSettings + <QuestionChartSettings series={series} question={question} initial={{ section: "Data" }} - noPreview />, ); }; diff --git a/frontend/src/metabase/visualizations/visualizations/PivotTable/PivotTable.unit.spec.js b/frontend/src/metabase/visualizations/visualizations/PivotTable/PivotTable.unit.spec.js index ba199b1e152e32ad4ba23433e69935b1c3856a89..d581d33c833567ee66ac0c2d3a84cc59c240a504 100644 --- a/frontend/src/metabase/visualizations/visualizations/PivotTable/PivotTable.unit.spec.js +++ b/frontend/src/metabase/visualizations/visualizations/PivotTable/PivotTable.unit.spec.js @@ -4,7 +4,7 @@ import { useState } from "react"; import { createMockMetadata } from "__support__/metadata"; import { render, screen } from "__support__/ui"; -import { ChartSettings } from "metabase/visualizations/components/ChartSettings"; +import { QuestionChartSettings } from "metabase/visualizations/components/ChartSettings"; import registerVisualizations from "metabase/visualizations/register"; import Question from "metabase-lib/v1/Question"; import { createMockColumn } from "metabase-types/api/mocks"; @@ -61,7 +61,7 @@ const setup = () => { }; return ( - <ChartSettings + <QuestionChartSettings onChange={onChange} series={[ { @@ -93,7 +93,6 @@ const setup = () => { }, ]} initial={{ section: "Data" }} - noPreview question={question} /> ); diff --git a/frontend/src/metabase/visualizations/visualizations/Table.unit.spec.js b/frontend/src/metabase/visualizations/visualizations/Table.unit.spec.js index 88a395ff9a06e45970a2ca28a64e36b54d893b7f..8119be79f87f4239000aaa3e656b93e8af252596 100644 --- a/frontend/src/metabase/visualizations/visualizations/Table.unit.spec.js +++ b/frontend/src/metabase/visualizations/visualizations/Table.unit.spec.js @@ -4,7 +4,7 @@ import { useState } from "react"; import { createMockMetadata } from "__support__/metadata"; import { renderWithProviders, screen, within } from "__support__/ui"; -import { ChartSettings } from "metabase/visualizations/components/ChartSettings"; +import { QuestionChartSettings } from "metabase/visualizations/components/ChartSettings"; import registerVisualizations from "metabase/visualizations/register"; import Question from "metabase-lib/v1/Question"; import { createMockVisualizationSettings } from "metabase-types/api/mocks"; @@ -52,7 +52,7 @@ const setup = ({ display, visualization_settings = {} }) => { }; return ( - <ChartSettings + <QuestionChartSettings onChange={handleChange} series={[ {