Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: dropdown placement for cascading filters popover #17046

Merged
merged 14 commits into from
Oct 22, 2021
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -28,14 +28,14 @@ export interface CascadeFilterControlProps {
filter: CascadeFilter;
directPathToChild?: string[];
onFilterSelectionChange: (filter: Filter, dataMask: DataMask) => void;
parentRef?: RefObject<any>;
}

const StyledDiv = styled.div`
display: flex;
width: 100%;
flex-direction: column;
align-items: center;

.ant-form-item {
margin-bottom: ${({ theme }) => theme.gridUnit * 4}px;
}
Expand All @@ -46,12 +46,15 @@ const CascadeFilterControl: React.FC<CascadeFilterControlProps> = ({
filter,
directPathToChild,
onFilterSelectionChange,
parentRef,
}) => (
<>
<FilterControl
dataMaskSelected={dataMaskSelected}
filter={filter}
directPathToChild={directPathToChild}
parentRef={parentRef}
showOverflow
pkdotson marked this conversation as resolved.
Show resolved Hide resolved
onFilterSelectionChange={onFilterSelectionChange}
/>
<StyledDiv>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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> = ({
Expand All @@ -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);
Expand Down Expand Up @@ -178,16 +185,17 @@ const CascadePopover: React.FC<CascadePopoverProps> = ({
);

const content = (
<ContentWrapper>
<ContentStyles>
<CascadeFilterControl
dataMaskSelected={dataMaskSelected}
data-test="cascade-filters-control"
key={filter.id}
filter={filter}
directPathToChild={visible ? currentPathToChild : undefined}
onFilterSelectionChange={onFilterSelectionChange}
parentRef={parent}
/>
</ContentWrapper>
</ContentStyles>
);

return (
Expand All @@ -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 => (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ const FilterControl: React.FC<FilterProps> = ({
onFilterSelectionChange,
directPathToChild,
inView,
showOverflow,
parentRef,
}) => {
const { name = '<undefined>' } = filter;

Expand Down Expand Up @@ -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>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -30,4 +30,6 @@ export interface FilterProps {
directPathToChild?: string[];
onFilterSelectionChange: (filter: Filter, dataMask: DataMask) => void;
inView?: boolean;
showOverflow?: boolean;
parentRef?: RefObject<any>;
}
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ export default function PluginFilterSelect(props: PluginFilterSelectProps) {
setFocusedFilter,
unsetFocusedFilter,
appSection,
showOverflow,
parentRef,
} = props;
const {
enableEmptyFilter,
Expand Down Expand Up @@ -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}
Expand Down
2 changes: 2 additions & 0 deletions superset-frontend/src/filters/components/Select/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand Down