diff --git a/superset-frontend/src/explore/components/controls/VizTypeControl/FastVizSwitcher.tsx b/superset-frontend/src/explore/components/controls/VizTypeControl/FastVizSwitcher.tsx index b042867208faf..dafdfb6a34227 100644 --- a/superset-frontend/src/explore/components/controls/VizTypeControl/FastVizSwitcher.tsx +++ b/superset-frontend/src/explore/components/controls/VizTypeControl/FastVizSwitcher.tsx @@ -16,58 +16,17 @@ * specific language governing permissions and limitations * under the License. */ -import { - memo, - ReactElement, - useCallback, - useEffect, - useMemo, - useRef, - useState, -} from 'react'; +import { memo, useMemo } from 'react'; import { useSelector } from 'react-redux'; -import { css, SupersetTheme, t, useTheme } from '@superset-ui/core'; -import { usePluginContext } from 'src/components/DynamicPlugins'; -import { Tooltip } from 'src/components/Tooltip'; +import { css, SupersetTheme } from '@superset-ui/core'; import Icons from 'src/components/Icons'; import { getChartKey } from 'src/explore/exploreUtils'; import { ExplorePageState } from 'src/explore/types'; +import { FastVizSwitcherProps } from './types'; +import { VizTile } from './VizTile'; +import { FEATURED_CHARTS } from './constants'; -export interface VizMeta { - icon: ReactElement; - name: string; -} - -export interface FastVizSwitcherProps { - onChange: (vizName: string) => void; - currentSelection: string | null; -} -interface VizTileProps { - vizMeta: VizMeta; - isActive: boolean; - isRendered: boolean; - onTileClick: (vizType: string) => void; -} - -const FEATURED_CHARTS: VizMeta[] = [ - { - name: 'echarts_timeseries_line', - icon: , - }, - { - name: 'echarts_timeseries_bar', - icon: , - }, - { name: 'echarts_area', icon: }, - { name: 'table', icon: }, - { - name: 'big_number_total', - icon: , - }, - { name: 'pie', icon: }, -]; - -const antdIconProps = { +export const antdIconProps = { iconSize: 'l' as const, css: (theme: SupersetTheme) => css` padding: ${theme.gridUnit}px; @@ -77,124 +36,6 @@ const antdIconProps = { `, }; -const VizTile = ({ - isActive, - isRendered, - vizMeta, - onTileClick, -}: VizTileProps) => { - const { mountedPluginMetadata } = usePluginContext(); - const chartNameRef = useRef(null); - const theme = useTheme(); - const TILE_TRANSITION_TIME = theme.transitionTiming * 2; - const [tooltipVisible, setTooltipVisible] = useState(false); - const [isTransitioning, setIsTransitioning] = useState(false); - const [showTooltip, setShowTooltip] = useState(false); - const chartName = vizMeta.name - ? mountedPluginMetadata[vizMeta.name]?.name || `${vizMeta.name}` - : t('Select Viz Type'); - - const handleTileClick = useCallback(() => { - onTileClick(vizMeta.name); - setIsTransitioning(true); - setTooltipVisible(false); - setTimeout(() => { - setIsTransitioning(false); - }, TILE_TRANSITION_TIME * 1000); - }, [onTileClick, TILE_TRANSITION_TIME, vizMeta.name]); - - // Antd tooltip seems to be bugged - when elements move, the tooltip sometimes - // stays visible even when user doesn't hover over the element. - // Here we manually prevent it from displaying after user triggers transition - useEffect(() => { - setShowTooltip( - Boolean( - !isTransitioning && - (!isActive || - (chartNameRef.current && - chartNameRef.current.scrollWidth > - chartNameRef.current.clientWidth)), - ), - ); - }, [isActive, isTransitioning]); - - const containerProps = useMemo( - () => - !isActive - ? { role: 'button', tabIndex: 0, onClick: handleTileClick } - : {}, - [handleTileClick, isActive], - ); - - let tooltipTitle: string | null = null; - if (showTooltip) { - tooltipTitle = isRendered - ? t('Currently rendered: %s', chartName) - : chartName; - } - return ( - setTooltipVisible(visible)} - visible={tooltipVisible && !isTransitioning} - placement="top" - mouseEnterDelay={0.4} - > -
- {vizMeta.icon}{' '} - - {chartName} - -
-
- ); -}; - export const FastVizSwitcher = memo( ({ currentSelection, onChange }: FastVizSwitcherProps) => { const currentViz = useSelector( diff --git a/superset-frontend/src/explore/components/controls/VizTypeControl/VizTile.tsx b/superset-frontend/src/explore/components/controls/VizTypeControl/VizTile.tsx new file mode 100644 index 0000000000000..c07b8a4c9e839 --- /dev/null +++ b/superset-frontend/src/explore/components/controls/VizTypeControl/VizTile.tsx @@ -0,0 +1,141 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; +import { css, t, useTheme } from '@superset-ui/core'; +import { usePluginContext } from 'src/components/DynamicPlugins'; +import { Tooltip } from 'src/components/Tooltip'; +import { VizTileProps } from './types'; + +export const VizTile = ({ + isActive, + isRendered, + vizMeta, + onTileClick, +}: VizTileProps) => { + const { mountedPluginMetadata } = usePluginContext(); + const chartNameRef = useRef(null); + const theme = useTheme(); + const TILE_TRANSITION_TIME = theme.transitionTiming * 2; + const [tooltipVisible, setTooltipVisible] = useState(false); + const [isTransitioning, setIsTransitioning] = useState(false); + const [showTooltip, setShowTooltip] = useState(false); + const chartName = vizMeta.name + ? mountedPluginMetadata[vizMeta.name]?.name || `${vizMeta.name}` + : t('Select Viz Type'); + + const handleTileClick = useCallback(() => { + onTileClick(vizMeta.name); + setIsTransitioning(true); + setTooltipVisible(false); + setTimeout(() => { + setIsTransitioning(false); + }, TILE_TRANSITION_TIME * 1000); + }, [onTileClick, TILE_TRANSITION_TIME, vizMeta.name]); + + // Antd tooltip seems to be bugged - when elements move, the tooltip sometimes + // stays visible even when user doesn't hover over the element. + // Here we manually prevent it from displaying after user triggers transition + useEffect(() => { + setShowTooltip( + Boolean( + !isTransitioning && + (!isActive || + (chartNameRef.current && + chartNameRef.current.scrollWidth > + chartNameRef.current.clientWidth)), + ), + ); + }, [isActive, isTransitioning]); + + const containerProps = useMemo( + () => + !isActive + ? { role: 'button', tabIndex: 0, onClick: handleTileClick } + : {}, + [handleTileClick, isActive], + ); + + let tooltipTitle: string | null = null; + if (showTooltip) { + tooltipTitle = isRendered + ? t('Currently rendered: %s', chartName) + : chartName; + } + return ( + setTooltipVisible(visible)} + visible={tooltipVisible && !isTransitioning} + placement="top" + mouseEnterDelay={0.4} + > +
+ {vizMeta.icon}{' '} + + {chartName} + +
+
+ ); +}; diff --git a/superset-frontend/src/explore/components/controls/VizTypeControl/constants.tsx b/superset-frontend/src/explore/components/controls/VizTypeControl/constants.tsx new file mode 100644 index 0000000000000..6e1201c8f8e9f --- /dev/null +++ b/superset-frontend/src/explore/components/controls/VizTypeControl/constants.tsx @@ -0,0 +1,38 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import Icons from 'src/components/Icons'; +import { VizMeta } from './types'; + +export const FEATURED_CHARTS: VizMeta[] = [ + { + name: 'echarts_timeseries_line', + icon: , + }, + { + name: 'echarts_timeseries_bar', + icon: , + }, + { name: 'echarts_area', icon: }, + { name: 'table', icon: }, + { + name: 'big_number_total', + icon: , + }, + { name: 'pie', icon: }, +]; diff --git a/superset-frontend/src/explore/components/controls/VizTypeControl/types.ts b/superset-frontend/src/explore/components/controls/VizTypeControl/types.ts new file mode 100644 index 0000000000000..2fe40ba633c47 --- /dev/null +++ b/superset-frontend/src/explore/components/controls/VizTypeControl/types.ts @@ -0,0 +1,35 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import { ReactElement } from 'react'; + +export interface VizMeta { + icon: ReactElement; + name: string; +} + +export interface FastVizSwitcherProps { + onChange: (vizName: string) => void; + currentSelection: string | null; +} +export interface VizTileProps { + vizMeta: VizMeta; + isActive: boolean; + isRendered: boolean; + onTileClick: (vizType: string) => void; +}