Merge pull request #11963 from AlexSCorey/11467-RevertDraagandDrop

Revert "updated patternfly"
This commit is contained in:
Sarah Akus
2022-04-04 21:44:08 -04:00
committed by GitHub
3 changed files with 163 additions and 78 deletions

View File

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

View File

@@ -1,8 +1,14 @@
// 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.
//github.com/patternfly/patternfly-react/issues/6317s
import React from 'react'; import React from 'react';
import { act } from 'react-dom/test-utils';
import { mountWithContexts } from '../../../testUtils/enzymeHelpers'; import { mountWithContexts } from '../../../testUtils/enzymeHelpers';
import DraggableSelectedList from './DraggableSelectedList'; import DraggableSelectedList from './DraggableSelectedList';
describe('<DraggableSelectedList />', () => { describe.skip('<DraggableSelectedList />', () => {
let wrapper; let wrapper;
afterEach(() => { afterEach(() => {
jest.clearAllMocks(); jest.clearAllMocks();
@@ -27,16 +33,16 @@ describe('<DraggableSelectedList />', () => {
/> />
); );
expect(wrapper.find('DraggableSelectedList').length).toBe(1); expect(wrapper.find('DraggableSelectedList').length).toBe(1);
expect(wrapper.find('Draggable').length).toBe(2); expect(wrapper.find('DataListItem').length).toBe(2);
expect( expect(
wrapper wrapper
.find('Draggable') .find('DataListItem DataListCell')
.first() .first()
.containsMatchingElement(<span>1. foo</span>) .containsMatchingElement(<span>1. foo</span>)
).toEqual(true); ).toEqual(true);
expect( expect(
wrapper wrapper
.find('Draggable') .find('DataListItem DataListCell')
.last() .last()
.containsMatchingElement(<span>2. bar</span>) .containsMatchingElement(<span>2. bar</span>)
).toEqual(true); ).toEqual(true);
@@ -64,10 +70,64 @@ describe('<DraggableSelectedList />', () => {
wrapper = mountWithContexts( wrapper = mountWithContexts(
<DraggableSelectedList selected={mockSelected} onRemove={onRemove} /> <DraggableSelectedList selected={mockSelected} onRemove={onRemove} />
); );
wrapper.find('Button[aria-label="Remove"]').simulate('click'); 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({ expect(onRemove).toBeCalledWith({
id: 1, id: 1,
name: 'foo', 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);
});
}); });

View File

@@ -44,9 +44,9 @@ describe('JobOutputSearch', () => {
wrapper.find(searchBtn).simulate('click'); wrapper.find(searchBtn).simulate('click');
}); });
expect(wrapper.find('Search').prop('columns')).toHaveLength(3); expect(wrapper.find('Search').prop('columns')).toHaveLength(3);
expect(wrapper.find('Search').prop('columns').at(0).name).toBe('Stdout'); expect(wrapper.find('Search').prop('columns')[0].name).toBe('Stdout');
expect(wrapper.find('Search').prop('columns').at(1).name).toBe('Event'); expect(wrapper.find('Search').prop('columns')[1].name).toBe('Event');
expect(wrapper.find('Search').prop('columns').at(2).name).toBe('Advanced'); expect(wrapper.find('Search').prop('columns')[2].name).toBe('Advanced');
expect(history.location.search).toEqual('?stdout__icontains=99'); expect(history.location.search).toEqual('?stdout__icontains=99');
}); });
test('Should not have Event key in search drop down for system job', () => { test('Should not have Event key in search drop down for system job', () => {
@@ -70,8 +70,8 @@ describe('JobOutputSearch', () => {
} }
); );
expect(wrapper.find('Search').prop('columns')).toHaveLength(2); expect(wrapper.find('Search').prop('columns')).toHaveLength(2);
expect(wrapper.find('Search').prop('columns').at(0).name).toBe('Stdout'); expect(wrapper.find('Search').prop('columns')[0].name).toBe('Stdout');
expect(wrapper.find('Search').prop('columns').at(1).name).toBe('Advanced'); expect(wrapper.find('Search').prop('columns')[1].name).toBe('Advanced');
}); });
test('Should not have Event key in search drop down for inventory update job', () => { test('Should not have Event key in search drop down for inventory update job', () => {
@@ -94,8 +94,9 @@ describe('JobOutputSearch', () => {
context: { router: { history } }, context: { router: { history } },
} }
); );
expect(wrapper.find('Search').prop('columns')).toHaveLength(2); expect(wrapper.find('Search').prop('columns')).toHaveLength(2);
expect(wrapper.find('Search').prop('columns').at(0).name).toBe('Stdout'); expect(wrapper.find('Search').prop('columns')[0].name).toBe('Stdout');
expect(wrapper.find('Search').prop('columns').at(1).name).toBe('Advanced'); expect(wrapper.find('Search').prop('columns')[1].name).toBe('Advanced');
}); });
}); });