mirror of
https://github.com/apache/superset.git
synced 2024-09-12 08:39:45 -04:00
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:
parent
80a459f43b
commit
824e62bd1f
@ -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>
|
||||
|
@ -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 => (
|
||||
|
@ -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>
|
||||
|
@ -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}
|
||||
|
@ -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>;
|
||||
}
|
||||
|
@ -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}
|
||||
|
@ -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 = {
|
||||
|
Loading…
Reference in New Issue
Block a user