diff --git a/superset-frontend/src/explore/components/ChartPills.tsx b/superset-frontend/src/explore/components/ChartPills.tsx new file mode 100644 index 0000000000..09595576dd --- /dev/null +++ b/superset-frontend/src/explore/components/ChartPills.tsx @@ -0,0 +1,88 @@ +/** + * 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 React, { forwardRef, RefObject } from 'react'; +import { css, QueryData, SupersetTheme } from '@superset-ui/core'; +import RowCountLabel from 'src/explore/components/RowCountLabel'; +import CachedLabel from 'src/components/CachedLabel'; +import Timer from 'src/components/Timer'; + +enum CHART_STATUS_MAP { + failed = 'danger', + loading = 'warning', + success = 'success', +} + +export type ChartPillsProps = { + queriesResponse: QueryData[]; + chartStatus: keyof typeof CHART_STATUS_MAP; + chartUpdateStartTime: number; + chartUpdateEndTime: number; + refreshCachedQuery: () => void; + rowLimit: string | number; +}; + +export const ChartPills = forwardRef( + ( + { + queriesResponse, + chartStatus, + chartUpdateStartTime, + chartUpdateEndTime, + refreshCachedQuery, + rowLimit, + }: ChartPillsProps, + ref: RefObject, + ) => { + const isLoading = chartStatus === 'loading'; + const firstQueryResponse = queriesResponse?.[0]; + return ( +
+
css` + display: flex; + justify-content: flex-end; + padding-bottom: ${theme.gridUnit * 4}px; + & .ant-tag:last-of-type { + margin: 0; + } + `} + > + {!isLoading && firstQueryResponse && ( + + )} + {!isLoading && firstQueryResponse?.is_cached && ( + + )} + +
+
+ ); + }, +); diff --git a/superset-frontend/src/explore/components/ExploreChartHeader/index.jsx b/superset-frontend/src/explore/components/ExploreChartHeader/index.jsx index d9d615dc1f..6c8d3cb799 100644 --- a/superset-frontend/src/explore/components/ExploreChartHeader/index.jsx +++ b/superset-frontend/src/explore/components/ExploreChartHeader/index.jsx @@ -36,22 +36,12 @@ import { isFeatureEnabled, FeatureFlag } from 'src/featureFlags'; import { chartPropShape } from 'src/dashboard/util/propShapes'; import AlteredSliceTag from 'src/components/AlteredSliceTag'; import FaveStar from 'src/components/FaveStar'; -import Timer from 'src/components/Timer'; -import CachedLabel from 'src/components/CachedLabel'; import PropertiesModal from 'src/explore/components/PropertiesModal'; import { sliceUpdated } from 'src/explore/actions/exploreActions'; import CertifiedBadge from 'src/components/CertifiedBadge'; -import withToasts from 'src/components/MessageToasts/withToasts'; -import RowCountLabel from '../RowCountLabel'; import ExploreAdditionalActionsMenu from '../ExploreAdditionalActionsMenu'; import { ChartEditableTitle } from './ChartEditableTitle'; -const CHART_STATUS_MAP = { - failed: 'danger', - loading: 'warning', - success: 'success', -}; - const propTypes = { actions: PropTypes.object.isRequired, canOverwrite: PropTypes.bool.isRequired, @@ -85,7 +75,7 @@ const StyledHeader = styled.div` display: flex; align-items: center; min-width: 0; - margin-right: ${theme.gridUnit * 6}px; + margin-right: ${theme.gridUnit * 12}px; } .right-button-panel { @@ -231,20 +221,8 @@ export class ExploreChartHeader extends React.PureComponent { sliceUpdated, sliceName, } = this.props; - const { - chartStatus, - chartUpdateEndTime, - chartUpdateStartTime, - latestQueryFormData, - queriesResponse, - sliceFormData, - } = chart; - // TODO: when will get appropriate design for multi queries use all results and not first only - const queryResponse = queriesResponse?.[0]; + const { latestQueryFormData, sliceFormData } = chart; const oldSliceName = slice?.slice_name; - const chartFinished = ['failed', 'rendered', 'success'].includes( - chartStatus, - ); return (
@@ -296,24 +274,6 @@ export class ExploreChartHeader extends React.PureComponent { )}
- {chartFinished && queryResponse && ( - - )} - {chartFinished && queryResponse && queryResponse.is_cached && ( - - )} - { refreshMode: 'debounce', refreshRate: 300, }); + const { height: pillsHeight, ref: pillsRef } = useResizeDetector({ + refreshMode: 'debounce', + refreshRate: 1000, + }); const [splitSizes, setSplitSizes] = useState( getItem(LocalStorageKeys.chart_split_sizes, INITIAL_SIZES), ); @@ -150,10 +155,16 @@ const ExploreChartPanel = props => { }, [updateQueryContext]); const calcSectionHeight = useCallback( - percent => - (parseInt(props.height, 10) * percent) / 100 - - (gutterHeight / 2 + gutterMargin), - [gutterHeight, gutterMargin, props.height, props.standalone], + percent => { + let containerHeight = parseInt(props.height, 10); + if (pillsHeight) { + containerHeight -= pillsHeight; + } + return ( + (containerHeight * percent) / 100 - (gutterHeight / 2 + gutterMargin) + ); + }, + [gutterHeight, gutterMargin, pillsHeight, props.height, props.standalone], ); const [tableSectionHeight, setTableSectionHeight] = useState( @@ -179,6 +190,17 @@ const ExploreChartPanel = props => { setSplitSizes(sizes); }; + const refreshCachedQuery = () => { + props.actions.postChartFormData( + props.form_data, + true, + props.timeout, + props.chart.id, + undefined, + props.ownState, + ); + }; + const onCollapseChange = openPanelName => { let splitSizes; if (!openPanelName) { @@ -229,6 +251,15 @@ const ExploreChartPanel = props => { const panelBody = useMemo( () => (
+ {renderChart()}
), diff --git a/superset-frontend/src/explore/components/RowCountLabel.stories.tsx b/superset-frontend/src/explore/components/RowCountLabel/RowCountLabel.stories.tsx similarity index 97% rename from superset-frontend/src/explore/components/RowCountLabel.stories.tsx rename to superset-frontend/src/explore/components/RowCountLabel/RowCountLabel.stories.tsx index 9030b828d8..716830f9ca 100644 --- a/superset-frontend/src/explore/components/RowCountLabel.stories.tsx +++ b/superset-frontend/src/explore/components/RowCountLabel/RowCountLabel.stories.tsx @@ -17,7 +17,7 @@ * under the License. */ import React from 'react'; -import RowCountLabel from './RowCountLabel'; +import RowCountLabel from '.'; export default { title: 'RowCountLabel', diff --git a/superset-frontend/src/explore/components/RowCountLabel.test.jsx b/superset-frontend/src/explore/components/RowCountLabel/RowCountLabel.test.jsx similarity index 96% rename from superset-frontend/src/explore/components/RowCountLabel.test.jsx rename to superset-frontend/src/explore/components/RowCountLabel/RowCountLabel.test.jsx index 128a0329c2..452f68a745 100644 --- a/superset-frontend/src/explore/components/RowCountLabel.test.jsx +++ b/superset-frontend/src/explore/components/RowCountLabel/RowCountLabel.test.jsx @@ -21,7 +21,7 @@ import { shallow } from 'enzyme'; import Label from 'src/components/Label'; import { Tooltip } from 'src/components/Tooltip'; -import RowCountLabel from 'src/explore/components/RowCountLabel'; +import RowCountLabel from '.'; describe('RowCountLabel', () => { const defaultProps = { diff --git a/superset-frontend/src/explore/components/RowCountLabel.tsx b/superset-frontend/src/explore/components/RowCountLabel/index.tsx similarity index 100% rename from superset-frontend/src/explore/components/RowCountLabel.tsx rename to superset-frontend/src/explore/components/RowCountLabel/index.tsx