diff --git a/superset-embedded-sdk/src/index.ts b/superset-embedded-sdk/src/index.ts index 9332e876e82..7af13aa9085 100644 --- a/superset-embedded-sdk/src/index.ts +++ b/superset-embedded-sdk/src/index.ts @@ -46,6 +46,7 @@ export type UiConfigType = { urlParams?: { [key: string]: any; }; + showRowLimitWarning?: boolean; }; export type EmbedDashboardParams = { @@ -133,6 +134,9 @@ export async function embedDashboard({ if (dashboardUiConfig.emitDataMasks) { configNumber += 16; } + if (dashboardUiConfig.showRowLimitWarning) { + configNumber += 32; + } } return configNumber; } diff --git a/superset-frontend/src/components/UiConfigContext/index.tsx b/superset-frontend/src/components/UiConfigContext/index.tsx index 78439676699..79af83957e4 100644 --- a/superset-frontend/src/components/UiConfigContext/index.tsx +++ b/superset-frontend/src/components/UiConfigContext/index.tsx @@ -26,8 +26,9 @@ interface UiConfigType { hideTab: boolean; hideNav: boolean; hideChartControls: boolean; - // Only used in superset-embedded-sdk to emit data masks to the parent window - emitDataMasks: boolean; + // superset-embedded-sdk specific + emitDataMasks: boolean; // emit data masks to the parent window + showRowLimitWarning: boolean; // show the row limit warning } interface EmbeddedUiConfigProviderProps { children: JSX.Element; @@ -39,6 +40,7 @@ export const UiConfigContext = createContext({ hideNav: false, hideChartControls: false, emitDataMasks: false, + showRowLimitWarning: false, }); export const useUiConfig = () => useContext(UiConfigContext); @@ -53,6 +55,7 @@ export const EmbeddedUiConfigProvider: FC = ({ hideNav: (config & 4) !== 0, hideChartControls: (config & 8) !== 0, emitDataMasks: (config & 16) !== 0, + showRowLimitWarning: (config & 32) !== 0, }); return ( diff --git a/superset-frontend/src/dashboard/components/SliceHeader/SliceHeader.test.tsx b/superset-frontend/src/dashboard/components/SliceHeader/SliceHeader.test.tsx index 2ff9da080a3..b7bc53eb5a1 100644 --- a/superset-frontend/src/dashboard/components/SliceHeader/SliceHeader.test.tsx +++ b/superset-frontend/src/dashboard/components/SliceHeader/SliceHeader.test.tsx @@ -20,6 +20,8 @@ import { Router } from 'react-router-dom'; import { createMemoryHistory } from 'history'; import { getExtensionsRegistry, VizType } from '@superset-ui/core'; import { render, screen, userEvent } from 'spec/helpers/testing-library'; +import { isEmbedded } from 'src/dashboard/util/isEmbedded'; +import { useUiConfig } from 'src/components/UiConfigContext'; import SliceHeader from '.'; jest.mock('src/dashboard/components/SliceHeaderControls', () => ({ @@ -100,6 +102,21 @@ jest.mock('src/dashboard/components/FiltersBadge', () => ({ ), })); +jest.mock('src/dashboard/util/isEmbedded', () => ({ + isEmbedded: jest.fn().mockReturnValue(false), +})); + +jest.mock('src/components/UiConfigContext', () => ({ + useUiConfig: jest.fn().mockReturnValue({ + hideTitle: false, + hideTab: false, + hideNav: false, + hideChartControls: false, + emitDataMasks: false, + showRowLimitWarning: false, + }), +})); + const MOCKED_CHART_ID = 312; const initialState = { @@ -584,3 +601,84 @@ test('Should render RowCountLabel when row limit is hit, and hide it otherwise', expect(screen.queryByTestId('warning')).not.toBeInTheDocument(); }); + +test('Should hide RowCountLabel in embedded by default', () => { + const mockIsEmbedded = isEmbedded as jest.MockedFunction; + mockIsEmbedded.mockReturnValue(true); + + const props = createProps({ + formData: { + ...createProps().formData, + row_limit: 10, + }, + }); + const rowCountState = { + ...initialState, + charts: { + [props.slice.slice_id]: { + queriesResponse: [ + { + sql_rowcount: 10, + }, + ], + }, + }, + }; + + render(, { + useRedux: true, + useRouter: true, + initialState: rowCountState, + }); + + expect(screen.queryByTestId('warning')).not.toBeInTheDocument(); + + mockIsEmbedded.mockRestore(); +}); + +test('Should show RowCountLabel in embedded when uiConfig.showRowLimitWarning is true', () => { + const mockIsEmbedded = isEmbedded as jest.MockedFunction; + const mockUseUiConfig = useUiConfig as jest.MockedFunction< + typeof useUiConfig + >; + + mockIsEmbedded.mockReturnValue(true); + mockUseUiConfig.mockReturnValue({ + hideTitle: false, + hideTab: false, + hideNav: false, + hideChartControls: false, + emitDataMasks: false, + showRowLimitWarning: true, + }); + + const props = createProps({ + formData: { + ...createProps().formData, + row_limit: 10, + }, + }); + const rowCountState = { + ...initialState, + charts: { + [props.slice.slice_id]: { + queriesResponse: [ + { + sql_rowcount: 10, + }, + ], + }, + }, + }; + + render(, { + useRedux: true, + useRouter: true, + initialState: rowCountState, + }); + + expect(screen.getByTestId('warning')).toBeInTheDocument(); + + mockIsEmbedded.mockRestore(); + mockUseUiConfig.mockRestore(); +}); diff --git a/superset-frontend/src/dashboard/components/SliceHeader/index.tsx b/superset-frontend/src/dashboard/components/SliceHeader/index.tsx index 16201655e34..cbe548691f0 100644 --- a/superset-frontend/src/dashboard/components/SliceHeader/index.tsx +++ b/superset-frontend/src/dashboard/components/SliceHeader/index.tsx @@ -34,6 +34,7 @@ import { useTheme, } from '@superset-ui/core'; import { useUiConfig } from 'src/components/UiConfigContext'; +import { isEmbedded } from 'src/dashboard/util/isEmbedded'; import { Tooltip, EditableTitle, Icons } from '@superset-ui/core/components'; import { useSelector } from 'react-redux'; import SliceHeaderControls from 'src/dashboard/components/SliceHeaderControls'; @@ -173,6 +174,8 @@ const SliceHeader = forwardRef( 'dashboard.slice.header', ); const uiConfig = useUiConfig(); + const shouldShowRowLimitWarning = + !isEmbedded() || uiConfig.showRowLimitWarning; const dashboardPageId = useContext(DashboardPageIdContext); const [headerTooltip, setHeaderTooltip] = useState(null); const headerRef = useRef(null); @@ -296,7 +299,7 @@ const SliceHeader = forwardRef( )} - {sqlRowCount === rowLimit && ( + {shouldShowRowLimitWarning && sqlRowCount === rowLimit && (