fix: dropdown placement for cascading filters popover (#17046)

* inital fix

* remove content wrapper

* allow dropdown to overflow in long chart

* only pass through filtercontrol

* change to auto

* add ref and pass to child

* fix bug

* fix lint

* add type

* remove code

* add currrent param
This commit is contained in:
Phillip Kelley-Dotson 2021-10-21 20:25:25 -07:00 committed by GitHub
parent 80a459f43b
commit 824e62bd1f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 42 additions and 9 deletions

View File

@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
import React from 'react';
import React, { RefObject } from 'react';
import { styled, DataMask } from '@superset-ui/core';
import FilterControl from 'src/dashboard/components/nativeFilters/FilterBar/FilterControls/FilterControl';
import { CascadeFilter } from 'src/dashboard/components/nativeFilters/FilterBar/CascadeFilters/types';
@ -28,6 +28,7 @@ export interface CascadeFilterControlProps {
filter: CascadeFilter;
directPathToChild?: string[];
onFilterSelectionChange: (filter: Filter, dataMask: DataMask) => void;
parentRef?: RefObject<any>;
}
const StyledDiv = styled.div`
@ -35,7 +36,6 @@ const StyledDiv = styled.div`
width: 100%;
flex-direction: column;
align-items: center;
.ant-form-item {
margin-bottom: ${({ theme }) => theme.gridUnit * 4}px;
}
@ -46,12 +46,15 @@ const CascadeFilterControl: React.FC<CascadeFilterControlProps> = ({
filter,
directPathToChild,
onFilterSelectionChange,
parentRef,
}) => (
<>
<FilterControl
dataMaskSelected={dataMaskSelected}
filter={filter}
directPathToChild={directPathToChild}
parentRef={parentRef}
showOverflow
onFilterSelectionChange={onFilterSelectionChange}
/>
<StyledDiv>

View File

@ -16,7 +16,13 @@
* specific language governing permissions and limitations
* under the License.
*/
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import React, {
useCallback,
useEffect,
useMemo,
useState,
useRef,
} from 'react';
import { styled, t, DataMask, css, SupersetTheme } from '@superset-ui/core';
import Popover from 'src/components/Popover';
import Icons from 'src/components/Icons';
@ -74,9 +80,9 @@ const StyledPill = styled(Pill)`
background: ${({ theme }) => theme.colors.grayscale.light1};
`;
const ContentWrapper = styled.div`
const ContentStyles = styled.div`
max-height: 700px;
overflow-y: auto;
overflow: auto;
`;
const CascadePopover: React.FC<CascadePopoverProps> = ({
@ -90,6 +96,7 @@ const CascadePopover: React.FC<CascadePopoverProps> = ({
}) => {
const [currentPathToChild, setCurrentPathToChild] = useState<string[]>();
const dataMask = dataMaskSelected[filter.id];
const parent = useRef();
useEffect(() => {
setCurrentPathToChild(directPathToChild);
@ -178,7 +185,7 @@ const CascadePopover: React.FC<CascadePopoverProps> = ({
);
const content = (
<ContentWrapper>
<ContentStyles>
<CascadeFilterControl
dataMaskSelected={dataMaskSelected}
data-test="cascade-filters-control"
@ -186,8 +193,9 @@ const CascadePopover: React.FC<CascadePopoverProps> = ({
filter={filter}
directPathToChild={visible ? currentPathToChild : undefined}
onFilterSelectionChange={onFilterSelectionChange}
parentRef={parent}
/>
</ContentWrapper>
</ContentStyles>
);
return (
@ -199,7 +207,12 @@ const CascadePopover: React.FC<CascadePopoverProps> = ({
onVisibleChange={onVisibleChange}
placement="rightTop"
id={filter.id}
overlayStyle={{ width: '400px' }}
overlayStyle={{
width: '400px',
position: 'relative',
overflow: 'auto',
}}
ref={parent}
>
<div>
{activeFilters.map(activeFilter => (

View File

@ -59,6 +59,8 @@ const FilterControl: React.FC<FilterProps> = ({
onFilterSelectionChange,
directPathToChild,
inView,
showOverflow,
parentRef,
}) => {
const { name = '<undefined>' } = filter;
@ -89,9 +91,11 @@ const FilterControl: React.FC<FilterProps> = ({
<FilterValue
dataMaskSelected={dataMaskSelected}
filter={filter}
showOverflow={showOverflow}
directPathToChild={directPathToChild}
onFilterSelectionChange={onFilterSelectionChange}
inView={inView}
parentRef={parentRef}
/>
</FormItem>
</StyledFilterControlContainer>

View File

@ -68,6 +68,8 @@ const FilterValue: React.FC<FilterProps> = ({
directPathToChild,
onFilterSelectionChange,
inView = true,
showOverflow,
parentRef,
}) => {
const { id, targets, filterType, adhoc_filters, time_range } = filter;
const metadata = getChartMetadataRegistry().get(filterType);
@ -251,7 +253,9 @@ const FilterValue: React.FC<FilterProps> = ({
<SuperChart
height={HEIGHT}
width="100%"
showOverflow={showOverflow}
formData={formData}
parentRef={parentRef}
// For charts that don't have datasource we need workaround for empty placeholder
queriesData={hasDataSource ? state : queriesDataPlaceholder}
chartType={filterType}

View File

@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
import React from 'react';
import React, { RefObject } from 'react';
import { DataMask } from '@superset-ui/core';
import { DataMaskStateWithId } from 'src/dataMask/types';
import { Filter } from '../../types';
@ -30,4 +30,6 @@ export interface FilterProps {
directPathToChild?: string[];
onFilterSelectionChange: (filter: Filter, dataMask: DataMask) => void;
inView?: boolean;
showOverflow?: boolean;
parentRef?: RefObject<any>;
}

View File

@ -82,6 +82,8 @@ export default function PluginFilterSelect(props: PluginFilterSelectProps) {
setFocusedFilter,
unsetFocusedFilter,
appSection,
showOverflow,
parentRef,
} = props;
const {
enableEmptyFilter,
@ -285,6 +287,9 @@ export default function PluginFilterSelect(props: PluginFilterSelectProps) {
// @ts-ignore
value={filterState.value || []}
disabled={isDisabled}
getPopupContainer={
showOverflow ? () => parentRef?.current : undefined
}
showSearch={showSearch}
mode={multiSelect ? 'multiple' : 'single'}
placeholder={placeholderText}

View File

@ -59,6 +59,8 @@ export type PluginFilterSelectProps = PluginFilterStylesProps & {
formData: PluginFilterSelectQueryFormData;
filterState: FilterState;
isRefreshing: boolean;
showOverflow: boolean;
parentRef?: RefObject<any>;
} & PluginFilterHooks;
export const DEFAULT_FORM_DATA: PluginFilterSelectCustomizeProps = {