Disable remove button if row is being dragged

Disable remove button if row is being dragged.
Also, disable drag button there is just one item selected.

closes: https://github.com/ansible/awx/issues/10548
This commit is contained in:
nixocio
2021-07-07 14:43:51 -04:00
parent bc8e19b51d
commit fb64df21c5
4 changed files with 81 additions and 3 deletions

View File

@@ -90,7 +90,7 @@ function InstanceGroupsLookup({
<br /> <br />
<Trans> <Trans>
Note: The order in which these are selected sets the execution Note: The order in which these are selected sets the execution
precedence. precedence. Select more than one to enable drag.
</Trans> </Trans>
</> </>
} }

View File

@@ -25,10 +25,12 @@ const RemoveActionSection = styled(DataListAction)`
function DraggableSelectedList({ selected, onRemove, onRowDrag }) { function DraggableSelectedList({ selected, onRemove, onRowDrag }) {
const [liveText, setLiveText] = useState(''); const [liveText, setLiveText] = useState('');
const [id, setId] = useState(''); const [id, setId] = useState('');
const [isDragging, setIsDragging] = useState(false);
const onDragStart = newId => { const onDragStart = newId => {
setId(newId); setId(newId);
setLiveText(t`Dragging started for item id: ${newId}.`); setLiveText(t`Dragging started for item id: ${newId}.`);
setIsDragging(true);
}; };
const onDragMove = (oldIndex, newIndex) => { const onDragMove = (oldIndex, newIndex) => {
@@ -39,6 +41,7 @@ function DraggableSelectedList({ selected, onRemove, onRowDrag }) {
const onDragCancel = () => { const onDragCancel = () => {
setLiveText(t`Dragging cancelled. List is unchanged.`); setLiveText(t`Dragging cancelled. List is unchanged.`);
setIsDragging(false);
}; };
const onDragFinish = newItemOrder => { const onDragFinish = newItemOrder => {
@@ -46,6 +49,7 @@ function DraggableSelectedList({ selected, onRemove, onRowDrag }) {
selected.find(i => i.name === item) selected.find(i => i.name === item)
); );
onRowDrag(selectedItems); onRowDrag(selectedItems);
setIsDragging(false);
}; };
const removeItem = item => { const removeItem = item => {
@@ -56,7 +60,8 @@ function DraggableSelectedList({ selected, onRemove, onRowDrag }) {
return null; return null;
} }
const orderedList = selected.map(item => item.name); const orderedList = selected.map(item => item?.name);
return ( return (
<> <>
<DataList <DataList
@@ -83,6 +88,7 @@ function DraggableSelectedList({ selected, onRemove, onRowDrag }) {
cancel the drag operation.`} cancel the drag operation.`}
aria-pressed="false" aria-pressed="false"
data-cy={`reorder-${label}`} data-cy={`reorder-${label}`}
isDisabled={selected.length === 1}
/> />
</DataListControl> </DataListControl>
<DataListItemCells <DataListItemCells
@@ -98,6 +104,7 @@ function DraggableSelectedList({ selected, onRemove, onRowDrag }) {
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>

View File

@@ -1,4 +1,5 @@
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';
@@ -64,6 +65,11 @@ describe('<DraggableSelectedList />', () => {
wrapper = mountWithContexts( wrapper = mountWithContexts(
<DraggableSelectedList selected={mockSelected} onRemove={onRemove} /> <DraggableSelectedList selected={mockSelected} onRemove={onRemove} />
); );
expect(
wrapper
.find('DataListDragButton[aria-label="Reorder"]')
.prop('isDisabled')
).toBe(true);
wrapper wrapper
.find('DataListItem[id="foo"] Button[aria-label="Remove"]') .find('DataListItem[id="foo"] Button[aria-label="Remove"]')
.simulate('click'); .simulate('click');
@@ -72,4 +78,69 @@ describe('<DraggableSelectedList />', () => {
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

@@ -115,7 +115,7 @@ function OrganizationFormFields({
<br /> <br />
<Trans> <Trans>
Note: The order of these credentials sets precedence for the sync Note: The order of these credentials sets precedence for the sync
and lookup of the content. and lookup of the content. Select more than one to enable drag.
</Trans> </Trans>
</> </>
} }