fix(dashboard): invalid drop item on a tab (#28507)
This commit is contained in:
parent
821c7d7f2c
commit
65e0d54fa5
|
|
@ -55,8 +55,11 @@ export default function handleDrop(props, monitor, Component) {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const shouldAppendToChildren =
|
||||||
|
typeof dropToChild === 'function' ? dropToChild(draggingItem) : dropToChild;
|
||||||
|
|
||||||
// simplest case, append as child
|
// simplest case, append as child
|
||||||
if (dropToChild) {
|
if (shouldAppendToChildren) {
|
||||||
dropResult.destination = {
|
dropResult.destination = {
|
||||||
id: component.id,
|
id: component.id,
|
||||||
type: component.type,
|
type: component.type,
|
||||||
|
|
@ -74,7 +77,9 @@ export default function handleDrop(props, monitor, Component) {
|
||||||
const sameParent =
|
const sameParent =
|
||||||
parentComponent && draggingItem.parentId === parentComponent.id;
|
parentComponent && draggingItem.parentId === parentComponent.id;
|
||||||
const sameParentLowerIndex =
|
const sameParentLowerIndex =
|
||||||
sameParent && draggingItem.index < componentIndex;
|
sameParent &&
|
||||||
|
draggingItem.index < componentIndex &&
|
||||||
|
draggingItem.type !== component.type;
|
||||||
|
|
||||||
const nextIndex = sameParentLowerIndex
|
const nextIndex = sameParentLowerIndex
|
||||||
? componentIndex - 1
|
? componentIndex - 1
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@ import DragDroppable, {
|
||||||
Droppable,
|
Droppable,
|
||||||
} from 'src/dashboard/components/dnd/DragDroppable';
|
} from 'src/dashboard/components/dnd/DragDroppable';
|
||||||
import { componentShape } from 'src/dashboard/util/propShapes';
|
import { componentShape } from 'src/dashboard/util/propShapes';
|
||||||
|
import { TAB_TYPE } from 'src/dashboard/util/componentTypes';
|
||||||
|
|
||||||
export const RENDER_TAB = 'RENDER_TAB';
|
export const RENDER_TAB = 'RENDER_TAB';
|
||||||
export const RENDER_TAB_CONTENT = 'RENDER_TAB_CONTENT';
|
export const RENDER_TAB_CONTENT = 'RENDER_TAB_CONTENT';
|
||||||
|
|
@ -139,6 +140,10 @@ class Tab extends React.PureComponent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
shouldDropToChild(item) {
|
||||||
|
return item.type !== TAB_TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
renderTabContent() {
|
renderTabContent() {
|
||||||
const {
|
const {
|
||||||
component: tabComponent,
|
component: tabComponent,
|
||||||
|
|
@ -275,6 +280,7 @@ class Tab extends React.PureComponent {
|
||||||
onDrop={this.handleDrop}
|
onDrop={this.handleDrop}
|
||||||
onHover={this.handleOnHover}
|
onHover={this.handleOnHover}
|
||||||
editMode={editMode}
|
editMode={editMode}
|
||||||
|
dropToChild={this.shouldDropToChild}
|
||||||
>
|
>
|
||||||
{({ dropIndicatorProps, dragSourceRef }) => (
|
{({ dropIndicatorProps, dragSourceRef }) => (
|
||||||
<TabTitleContainer
|
<TabTitleContainer
|
||||||
|
|
|
||||||
|
|
@ -19,12 +19,18 @@
|
||||||
|
|
||||||
import userEvent from '@testing-library/user-event';
|
import userEvent from '@testing-library/user-event';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { render, screen } from 'spec/helpers/testing-library';
|
import {
|
||||||
|
fireEvent,
|
||||||
|
render,
|
||||||
|
screen,
|
||||||
|
waitFor,
|
||||||
|
} from 'spec/helpers/testing-library';
|
||||||
import DashboardComponent from 'src/dashboard/containers/DashboardComponent';
|
import DashboardComponent from 'src/dashboard/containers/DashboardComponent';
|
||||||
import EditableTitle from 'src/components/EditableTitle';
|
import EditableTitle from 'src/components/EditableTitle';
|
||||||
import { setEditMode } from 'src/dashboard/actions/dashboardState';
|
import { setEditMode } from 'src/dashboard/actions/dashboardState';
|
||||||
|
|
||||||
import Tab from './Tab';
|
import Tab from './Tab';
|
||||||
|
import Markdown from './Markdown';
|
||||||
|
|
||||||
jest.mock('src/dashboard/containers/DashboardComponent', () =>
|
jest.mock('src/dashboard/containers/DashboardComponent', () =>
|
||||||
jest.fn(() => <div data-test="DashboardComponent" />),
|
jest.fn(() => <div data-test="DashboardComponent" />),
|
||||||
|
|
@ -128,6 +134,82 @@ test('Render tab (no content) editMode:true', () => {
|
||||||
expect(getByTestId('dragdroppable-object')).toBeInTheDocument();
|
expect(getByTestId('dragdroppable-object')).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('Drop on a tab', async () => {
|
||||||
|
const props = createProps();
|
||||||
|
const mockOnDropOnTab = jest.fn();
|
||||||
|
render(
|
||||||
|
<>
|
||||||
|
<Tab {...props} renderType="RENDER_TAB" editMode />
|
||||||
|
<Tab
|
||||||
|
{...props}
|
||||||
|
renderType="RENDER_TAB"
|
||||||
|
index={2}
|
||||||
|
component={{
|
||||||
|
...props.component,
|
||||||
|
id: 'TAB-Next-',
|
||||||
|
meta: { text: 'Next Tab' } as any,
|
||||||
|
}}
|
||||||
|
handleComponentDrop={mockOnDropOnTab}
|
||||||
|
editMode
|
||||||
|
/>
|
||||||
|
<Markdown
|
||||||
|
id="MARKDOWN-1"
|
||||||
|
parentId="GRID_ID"
|
||||||
|
parentComponent={{
|
||||||
|
id: 'GRID_ID',
|
||||||
|
type: 'GRID',
|
||||||
|
parents: ['ROOT_ID'],
|
||||||
|
}}
|
||||||
|
depth={0}
|
||||||
|
editMode
|
||||||
|
index={1}
|
||||||
|
availableColumnCount={12}
|
||||||
|
columnWidth={120}
|
||||||
|
component={{
|
||||||
|
...props.component,
|
||||||
|
type: 'MARKDOWN',
|
||||||
|
id: 'MARKDOWN-1',
|
||||||
|
meta: { code: 'Dashboard Component' } as any,
|
||||||
|
}}
|
||||||
|
logEvent={jest.fn()}
|
||||||
|
deleteComponent={jest.fn()}
|
||||||
|
handleComponentDrop={jest.fn()}
|
||||||
|
onResizeStart={jest.fn()}
|
||||||
|
onResize={jest.fn()}
|
||||||
|
onResizeStop={jest.fn()}
|
||||||
|
updateComponents={jest.fn()}
|
||||||
|
addDangerToast={jest.fn()}
|
||||||
|
/>
|
||||||
|
</>,
|
||||||
|
{
|
||||||
|
useRedux: true,
|
||||||
|
useDnd: true,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
fireEvent.dragStart(screen.getByText('🚀 Aspiring Developers'));
|
||||||
|
fireEvent.drop(screen.getByText('Next Tab'));
|
||||||
|
await waitFor(() => expect(mockOnDropOnTab).toHaveBeenCalled());
|
||||||
|
expect(mockOnDropOnTab).toHaveBeenCalledWith(
|
||||||
|
expect.objectContaining({
|
||||||
|
destination: { id: props.parentComponent.id, index: 2, type: 'TABS' },
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
fireEvent.dragStart(screen.getByText('Dashboard Component'));
|
||||||
|
fireEvent.drop(screen.getByText('Next Tab'));
|
||||||
|
await waitFor(() => expect(mockOnDropOnTab).toHaveBeenCalledTimes(2));
|
||||||
|
expect(mockOnDropOnTab).toHaveBeenLastCalledWith(
|
||||||
|
expect.objectContaining({
|
||||||
|
destination: {
|
||||||
|
id: 'TAB-Next-',
|
||||||
|
index: props.component.children.length,
|
||||||
|
type: 'TAB',
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
test('Edit table title', () => {
|
test('Edit table title', () => {
|
||||||
const props = createProps();
|
const props = createProps();
|
||||||
props.editMode = true;
|
props.editMode = true;
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,7 @@ export default function getDropPosition(monitor, Component) {
|
||||||
const siblingDropOrientation =
|
const siblingDropOrientation =
|
||||||
orientation === 'row' ? 'horizontal' : 'vertical';
|
orientation === 'row' ? 'horizontal' : 'vertical';
|
||||||
|
|
||||||
if (isDraggingOverShallow && validChild && !validSibling) {
|
if (validChild && !validSibling) {
|
||||||
// easiest case, insert as child
|
// easiest case, insert as child
|
||||||
if (childDropOrientation === 'vertical') {
|
if (childDropOrientation === 'vertical') {
|
||||||
return hasChildren ? DROP_RIGHT : DROP_LEFT;
|
return hasChildren ? DROP_RIGHT : DROP_LEFT;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue