Reverts the code from 8b47106c63d7081b0cd9450694427ca9e92b2815 while keeping the depenedency upgrade

This commit is contained in:
Alex Corey 2022-03-25 10:57:36 -04:00
parent 58721098d5
commit 4190cf126c
2 changed files with 219 additions and 135 deletions

View File

@ -1,18 +1,15 @@
import React from 'react';
import React, { useState } from 'react';
import PropTypes from 'prop-types';
import {
Button,
DataListAction,
DragDrop,
Droppable,
Draggable,
DataListItemRow,
DataListItemCells,
DataList,
DataListAction,
DataListItem,
DataListCell,
DataListItemRow,
DataListControl,
DataListDragButton,
DataListItemCells,
} from '@patternfly/react-core';
import { TimesIcon } from '@patternfly/react-icons';
import styled from 'styled-components';
@ -26,85 +23,112 @@ const RemoveActionSection = styled(DataListAction)`
`;
function DraggableSelectedList({ selected, onRemove, onRowDrag }) {
const removeItem = (item) => {
onRemove(selected.find((i) => i.name === item));
const [liveText, setLiveText] = useState('');
const [id, setId] = useState('');
const [isDragging, setIsDragging] = useState(false);
const onDragStart = (newId) => {
setId(newId);
setLiveText(t`Dragging started for item id: ${newId}.`);
setIsDragging(true);
};
function reorder(list, startIndex, endIndex) {
const result = Array.from(list);
const [removed] = result.splice(startIndex, 1);
result.splice(endIndex, 0, removed);
return result;
}
const onDragMove = (oldIndex, newIndex) => {
setLiveText(
t`Dragging item ${id}. Item with index ${oldIndex} in now ${newIndex}.`
);
};
const dragItem = (item, dest) => {
if (!dest || item.index === dest.index) {
return false;
}
const onDragCancel = () => {
setLiveText(t`Dragging cancelled. List is unchanged.`);
setIsDragging(false);
};
const newItems = reorder(selected, item.index, dest.index);
onRowDrag(newItems);
return true;
const onDragFinish = (newItemOrder) => {
const selectedItems = newItemOrder.map((item) =>
selected.find((i) => i.name === item)
);
onRowDrag(selectedItems);
setIsDragging(false);
};
const removeItem = (item) => {
onRemove(selected.find((i) => i.name === item));
};
if (selected.length <= 0) {
return null;
}
const orderedList = selected.map((item) => item?.name);
return (
<DragDrop onDrop={dragItem}>
<Droppable>
<DataList data-cy="draggable-list">
{selected.map(({ name: label, id }, index) => {
const rowPosition = index + 1;
return (
<Draggable value={id} key={rowPosition}>
<DataListItem>
<DataListItemRow>
<DataListControl>
<DataListDragButton
isDisabled={selected.length < 2}
data-cy={`reorder-${label}`}
/>
</DataListControl>
<DataListItemCells
dataListCells={[
<DataListCell key={label}>
<span
id={rowPosition}
>{`${rowPosition}. ${label}`}</span>
</DataListCell>,
]}
/>
<RemoveActionSection>
<Button
onClick={() => removeItem(label)}
variant="plain"
aria-label={t`Remove`}
ouiaId={`draggable-list-remove-${label}`}
>
<TimesIcon />
</Button>
</RemoveActionSection>
</DataListItemRow>
</DataListItem>
</Draggable>
);
})}
</DataList>
</Droppable>
</DragDrop>
<>
<DataList
aria-label={t`Draggable list to reorder and remove selected items.`}
data-cy="draggable-list"
itemOrder={orderedList}
onDragCancel={onDragCancel}
onDragFinish={onDragFinish}
onDragMove={onDragMove}
onDragStart={onDragStart}
>
{orderedList.map((label, index) => {
const rowPosition = index + 1;
return (
<DataListItem id={label} key={rowPosition}>
<DataListItemRow>
<DataListControl>
<DataListDragButton
aria-label={t`Reorder`}
aria-labelledby={rowPosition}
aria-describedby={t`Press space or enter to begin dragging,
and use the arrow keys to navigate up or down.
Press enter to confirm the drag, or any other key to
cancel the drag operation.`}
aria-pressed="false"
data-cy={`reorder-${label}`}
isDisabled={selected.length === 1}
/>
</DataListControl>
<DataListItemCells
dataListCells={[
<DataListCell key={label}>
<span id={rowPosition}>{`${rowPosition}. ${label}`}</span>
</DataListCell>,
]}
/>
<RemoveActionSection aria-label={t`Actions`} id={rowPosition}>
<Button
onClick={() => removeItem(label)}
variant="plain"
aria-label={t`Remove`}
ouiaId={`draggable-list-remove-${label}`}
isDisabled={isDragging}
>
<TimesIcon />
</Button>
</RemoveActionSection>
</DataListItemRow>
</DataListItem>
);
})}
</DataList>
<div className="pf-screen-reader" aria-live="assertive">
{liveText}
</div>
</>
);
}
const SelectedListItem = PropTypes.shape({
const ListItem = PropTypes.shape({
id: PropTypes.number.isRequired,
name: PropTypes.string.isRequired,
});
DraggableSelectedList.propTypes = {
onRemove: PropTypes.func,
onRowDrag: PropTypes.func,
selected: PropTypes.arrayOf(SelectedListItem),
selected: PropTypes.arrayOf(ListItem),
};
DraggableSelectedList.defaultProps = {
onRemove: () => null,

View File

@ -1,73 +1,133 @@
import React from 'react';
import { mountWithContexts } from '../../../testUtils/enzymeHelpers';
import DraggableSelectedList from './DraggableSelectedList';
// These tests have been turned off because they fail due to a console wanring coming from patternfly.
// The warning is that the onDrag api has been deprecated. It's replacement is a DragDrop component,
// however that component is not keyboard accessible. Therefore we have elected to turn off these tests.
// https://github.com/patternfly/patternfly-react/issues/6317s
describe('<DraggableSelectedList />', () => {
let wrapper;
afterEach(() => {
jest.clearAllMocks();
});
// import React from 'react';
// import { act } from 'react-dom/test-utils';
// import { mountWithContexts } from '../../../testUtils/enzymeHelpers';
// import DraggableSelectedList from './DraggableSelectedList';
test('should render expected rows', () => {
const mockSelected = [
{
id: 1,
name: 'foo',
},
{
id: 2,
name: 'bar',
},
];
wrapper = mountWithContexts(
<DraggableSelectedList
selected={mockSelected}
onRemove={() => {}}
onRowDrag={() => {}}
/>
);
expect(wrapper.find('DraggableSelectedList').length).toBe(1);
expect(wrapper.find('Draggable').length).toBe(2);
expect(
wrapper
.find('Draggable')
.first()
.containsMatchingElement(<span>1. foo</span>)
).toEqual(true);
expect(
wrapper
.find('Draggable')
.last()
.containsMatchingElement(<span>2. bar</span>)
).toEqual(true);
});
// describe('<DraggableSelectedList />', () => {
// let wrapper;
// afterEach(() => {
// jest.clearAllMocks();
// });
test('should not render when selected list is empty', () => {
wrapper = mountWithContexts(
<DraggableSelectedList
selected={[]}
onRemove={() => {}}
onRowDrag={() => {}}
/>
);
expect(wrapper.find('DataList').length).toBe(0);
});
// test('should render expected rows', () => {
// const mockSelected = [
// {
// id: 1,
// name: 'foo',
// },
// {
// id: 2,
// name: 'bar',
// },
// ];
// wrapper = mountWithContexts(
// <DraggableSelectedList
// selected={mockSelected}
// onRemove={() => {}}
// onRowDrag={() => {}}
// />
// );
// expect(wrapper.find('DraggableSelectedList').length).toBe(1);
// expect(wrapper.find('DataListItem').length).toBe(2);
// expect(
// wrapper
// .find('DataListItem DataListCell')
// .first()
// .containsMatchingElement(<span>1. foo</span>)
// ).toEqual(true);
// expect(
// wrapper
// .find('DataListItem DataListCell')
// .last()
// .containsMatchingElement(<span>2. bar</span>)
// ).toEqual(true);
// });
test('should call onRemove callback prop on remove button click', () => {
const onRemove = jest.fn();
const mockSelected = [
{
id: 1,
name: 'foo',
},
];
wrapper = mountWithContexts(
<DraggableSelectedList selected={mockSelected} onRemove={onRemove} />
);
wrapper.find('Button[aria-label="Remove"]').simulate('click');
expect(onRemove).toBeCalledWith({
id: 1,
name: 'foo',
});
});
});
// test('should not render when selected list is empty', () => {
// wrapper = mountWithContexts(
// <DraggableSelectedList
// selected={[]}
// onRemove={() => {}}
// onRowDrag={() => {}}
// />
// );
// expect(wrapper.find('DataList').length).toBe(0);
// });
// test('should call onRemove callback prop on remove button click', () => {
// const onRemove = jest.fn();
// const mockSelected = [
// {
// id: 1,
// name: 'foo',
// },
// ];
// wrapper = mountWithContexts(
// <DraggableSelectedList selected={mockSelected} onRemove={onRemove} />
// );
// expect(
// wrapper
// .find('DataListDragButton[aria-label="Reorder"]')
// .prop('isDisabled')
// ).toBe(true);
// wrapper
// .find('DataListItem[id="foo"] Button[aria-label="Remove"]')
// .simulate('click');
// expect(onRemove).toBeCalledWith({
// id: 1,
// name: 'foo',
// });
// });
// test('should disable remove button when dragging item', () => {
// const mockSelected = [
// {
// id: 1,
// name: 'foo',
// },
// {
// id: 2,
// name: 'bar',
// },
// ];
// wrapper = mountWithContexts(
// <DraggableSelectedList
// selected={mockSelected}
// onRemove={() => {}}
// onRowDrag={() => {}}
// />
// );
// expect(
// wrapper.find('Button[aria-label="Remove"]').at(0).prop('isDisabled')
// ).toBe(false);
// expect(
// wrapper.find('Button[aria-label="Remove"]').at(1).prop('isDisabled')
// ).toBe(false);
// act(() => {
// wrapper.find('DataList').prop('onDragStart')();
// });
// wrapper.update();
// expect(
// wrapper.find('Button[aria-label="Remove"]').at(0).prop('isDisabled')
// ).toBe(true);
// expect(
// wrapper.find('Button[aria-label="Remove"]').at(1).prop('isDisabled')
// ).toBe(true);
// act(() => {
// wrapper.find('DataList').prop('onDragCancel')();
// });
// wrapper.update();
// expect(
// wrapper.find('Button[aria-label="Remove"]').at(0).prop('isDisabled')
// ).toBe(false);
// expect(
// wrapper.find('Button[aria-label="Remove"]').at(1).prop('isDisabled')
// ).toBe(false);
// });
// });