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"
itemOrder={orderedList}
onDragCancel={onDragCancel}
onDragFinish={onDragFinish}
onDragMove={onDragMove}
onDragStart={onDragStart}
>
{orderedList.map((label, index) => {
const rowPosition = index + 1; const rowPosition = index + 1;
return ( return (
<Draggable value={id} key={rowPosition}> <DataListItem id={label} key={rowPosition}>
<DataListItem>
<DataListItemRow> <DataListItemRow>
<DataListControl> <DataListControl>
<DataListDragButton <DataListDragButton
isDisabled={selected.length < 2} 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}`} data-cy={`reorder-${label}`}
isDisabled={selected.length === 1}
/> />
</DataListControl> </DataListControl>
<DataListItemCells <DataListItemCells
dataListCells={[ dataListCells={[
<DataListCell key={label}> <DataListCell key={label}>
<span <span id={rowPosition}>{`${rowPosition}. ${label}`}</span>
id={rowPosition}
>{`${rowPosition}. ${label}`}</span>
</DataListCell>, </DataListCell>,
]} ]}
/> />
<RemoveActionSection> <RemoveActionSection aria-label={t`Actions`} id={rowPosition}>
<Button <Button
onClick={() => removeItem(label)} onClick={() => removeItem(label)}
variant="plain" variant="plain"
aria-label={t`Remove`} aria-label={t`Remove`}
ouiaId={`draggable-list-remove-${label}`} ouiaId={`draggable-list-remove-${label}`}
isDisabled={isDragging}
> >
<TimesIcon /> <TimesIcon />
</Button> </Button>
</RemoveActionSection> </RemoveActionSection>
</DataListItemRow> </DataListItemRow>
</DataListItem> </DataListItem>
</Draggable>
); );
})} })}
</DataList> </DataList>
</Droppable> <div className="pf-screen-reader" aria-live="assertive">
</DragDrop> {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');
}); });
}); });