chore(explore): Hide non-droppable metric and column list (#27717)

This commit is contained in:
JUST.in DO IT
2024-04-05 09:29:05 -07:00
committed by GitHub
parent 9377227e06
commit eda304bda9
8 changed files with 393 additions and 107 deletions

View File

@@ -23,6 +23,7 @@ import { DndItemType } from 'src/explore/components/DndItemType';
import DndSelectLabel, {
DndSelectLabelProps,
} from 'src/explore/components/controls/DndColumnSelectControl/DndSelectLabel';
import ExploreContainer, { DropzoneContext } from '../../ExploreContainer';
const defaultProps: DndSelectLabelProps = {
name: 'Column',
@@ -33,6 +34,23 @@ const defaultProps: DndSelectLabelProps = {
ghostButtonText: 'Drop columns here or click',
onClickGhostButton: jest.fn(),
};
const MockChildren = () => {
const [zones] = React.useContext(DropzoneContext);
return (
<>
{Object.keys(zones).map(key => (
<div key={key} data-test={`mock-result-${key}`}>
{String(
zones[key]({
value: { column_name: 'test' },
type: DndItemType.Column,
}),
)}
</div>
))}
</>
);
};
test('renders with default props', () => {
render(<DndSelectLabel {...defaultProps} />, { useDnd: true });
@@ -62,3 +80,25 @@ test('Handles ghost button click', () => {
userEvent.click(screen.getByText('Drop columns here or click'));
expect(defaultProps.onClickGhostButton).toHaveBeenCalled();
});
test('updates dropValidator on changes', () => {
const { getByTestId, rerender } = render(
<ExploreContainer>
<DndSelectLabel {...defaultProps} />
<MockChildren />
</ExploreContainer>,
{ useDnd: true },
);
expect(getByTestId(`mock-result-${defaultProps.name}`)).toHaveTextContent(
'false',
);
rerender(
<ExploreContainer>
<DndSelectLabel {...defaultProps} canDrop={() => true} />
<MockChildren />
</ExploreContainer>,
);
expect(getByTestId(`mock-result-${defaultProps.name}`)).toHaveTextContent(
'true',
);
});

View File

@@ -16,7 +16,13 @@
* specific language governing permissions and limitations
* under the License.
*/
import React, { ReactNode, useContext, useMemo } from 'react';
import React, {
ReactNode,
useCallback,
useContext,
useEffect,
useMemo,
} from 'react';
import { useDrop } from 'react-dnd';
import { t, useTheme } from '@superset-ui/core';
import ControlHeader from 'src/explore/components/ControlHeader';
@@ -31,7 +37,7 @@ import {
} from 'src/explore/components/DatasourcePanel/types';
import Icons from 'src/components/Icons';
import { DndItemType } from '../../DndItemType';
import { DraggingContext } from '../../ExploreContainer';
import { DraggingContext, DropzoneContext } from '../../ExploreContainer';
export type DndSelectLabelProps = {
name: string;
@@ -55,6 +61,14 @@ export default function DndSelectLabel({
...props
}: DndSelectLabelProps) {
const theme = useTheme();
const canDropProp = props.canDrop;
const canDropValueProp = props.canDropValue;
const dropValidator = useCallback(
(item: DatasourcePanelDndItem) =>
canDropProp(item) && (canDropValueProp?.(item.value) ?? true),
[canDropProp, canDropValueProp],
);
const [{ isOver, canDrop }, datasourcePanelDrop] = useDrop({
accept: isLoading ? [] : accept,
@@ -64,8 +78,7 @@ export default function DndSelectLabel({
props.onDropValue?.(item.value);
},
canDrop: (item: DatasourcePanelDndItem) =>
props.canDrop(item) && (props.canDropValue?.(item.value) ?? true),
canDrop: dropValidator,
collect: monitor => ({
isOver: monitor.isOver(),
@@ -73,6 +86,16 @@ export default function DndSelectLabel({
type: monitor.getItemType(),
}),
});
const dispatch = useContext(DropzoneContext)[1];
useEffect(() => {
dispatch({ key: props.name, canDrop: dropValidator });
return () => {
dispatch({ key: props.name });
};
}, [dispatch, props.name, dropValidator]);
const isDragging = useContext(DraggingContext);
const values = useMemo(() => valuesRenderer(), [valuesRenderer]);