diff --git a/cypress/e2e/AllAccessibleRecordsPage/AllAccessibleRecordsPage.js b/cypress/e2e/AllAccessibleRecordsPage/AllAccessibleRecordsPage.js index 9ea6ac3f02..dbf29a6a8c 100644 --- a/cypress/e2e/AllAccessibleRecordsPage/AllAccessibleRecordsPage.js +++ b/cypress/e2e/AllAccessibleRecordsPage/AllAccessibleRecordsPage.js @@ -61,6 +61,8 @@ Then('the working list should be updated', () => { .click(); cy.contains('WHOMCH Hemoglobin value') + .parents('tr') + .find('input[type="checkbox"]') .click(); cy.contains('Save') diff --git a/cypress/e2e/WorkingLists/EventWorkingLists/EventWorkingListsUser/EventWorkingListsUser.js b/cypress/e2e/WorkingLists/EventWorkingLists/EventWorkingListsUser/EventWorkingListsUser.js index 51cb81153b..c5cb9fc63b 100644 --- a/cypress/e2e/WorkingLists/EventWorkingLists/EventWorkingListsUser/EventWorkingListsUser.js +++ b/cypress/e2e/WorkingLists/EventWorkingLists/EventWorkingListsUser/EventWorkingListsUser.js @@ -149,7 +149,8 @@ When('you open the column selector', () => { When('you select Household location and save from the column selector', () => { cy.get('aside[role="dialog"]') .contains('Household location') - .find('input') + .parents('tr') + .find('input[type="checkbox"]') .click(); cy.get('aside[role="dialog"]') diff --git a/cypress/e2e/WorkingLists/TeiWorkingLists/TeiWorkingListsUser/TeiWorkingListsUser.js b/cypress/e2e/WorkingLists/TeiWorkingLists/TeiWorkingListsUser/TeiWorkingListsUser.js index 5361178c6d..9026a15f3d 100644 --- a/cypress/e2e/WorkingLists/TeiWorkingLists/TeiWorkingListsUser/TeiWorkingListsUser.js +++ b/cypress/e2e/WorkingLists/TeiWorkingLists/TeiWorkingListsUser/TeiWorkingListsUser.js @@ -254,7 +254,8 @@ When('you open the column selector', () => { When('you select the organisation unit and save from the column selector', () => { cy.get('aside[role="dialog"]') .contains('Organisation unit') - .find('input') + .parents('tr') + .find('input[type="checkbox"]') .click(); cy.get('aside[role="dialog"]') @@ -616,7 +617,8 @@ When('you select the Foci response program stage', () => { When('you select a data element columns and save from the column selector', () => { cy.get('aside[role="dialog"]') .contains('People included') - .find('input') + .parents('tr') + .find('input[type="checkbox"]') .click(); cy.get('aside[role="dialog"]') @@ -677,7 +679,8 @@ Then('you see scheduledAt filter', () => { When('you select a scheduledAt column and save from the column selector', () => { cy.get('aside[role="dialog"]') .contains('Appointment date') - .find('input') + .parents('tr') + .find('input[type="checkbox"]') .click(); cy.get('aside[role="dialog"]') diff --git a/i18n/en.pot b/i18n/en.pot index 53ce989a6f..cc88503ce6 100644 --- a/i18n/en.pot +++ b/i18n/en.pot @@ -562,6 +562,9 @@ msgstr "Columns to show in table" msgid "Column" msgstr "Column" +msgid "Visible" +msgstr "Visible" + msgid "Update" msgstr "Update" diff --git a/src/core_modules/capture-core/components/ListView/ColumnSelector/DragDropList/DragDropList.component.js b/src/core_modules/capture-core/components/ListView/ColumnSelector/DragDropList/DragDropList.component.js index a9f242fa89..e8cf16e2ed 100644 --- a/src/core_modules/capture-core/components/ListView/ColumnSelector/DragDropList/DragDropList.component.js +++ b/src/core_modules/capture-core/components/ListView/ColumnSelector/DragDropList/DragDropList.component.js @@ -1,34 +1,28 @@ // @flow import React, { Component } from 'react'; - import { DndProvider } from 'react-dnd'; import { HTML5Backend } from 'react-dnd-html5-backend'; import update from 'react-addons-update'; - -import Table from '@material-ui/core/Table'; -import TableBody from '@material-ui/core/TableBody'; -import TableCell from '@material-ui/core/TableCell'; -import TableHead from '@material-ui/core/TableHead'; -import TableRow from '@material-ui/core/TableRow'; - +import { DataTable, TableHead, TableBody, DataTableRow, DataTableColumnHeader } from '@dhis2/ui'; import i18n from '@dhis2/d2-i18n'; - import { DragDropListItem } from './DragDropListItem.component'; type Props = { listItems: Array, handleUpdateListOrder: (sortedList: Array) => void, - handleToggle: (id: string) => () => void, + handleToggle: (id: string) => () => any, }; -export class DragDropList extends Component { - moveListItem: (dragIndex: any, hoverIndex: any) => void; - constructor(props: Props) { - super(props); - this.moveListItem = this.moveListItem.bind(this); - } +type State = { + isDraggingAny: boolean, +}; + +export class DragDropList extends Component { + state = { + isDraggingAny: false, + }; - moveListItem(dragIndex: any, hoverIndex: any) { + moveListItem = (dragIndex: number, hoverIndex: number) => { const { listItems } = this.props; const dragListItem = listItems[dragIndex]; let sortedList = []; @@ -40,18 +34,29 @@ export class DragDropList extends Component { }); this.props.handleUpdateListOrder(sortedList); - } + }; + + handleDragStart = () => { + this.setState({ isDraggingAny: true }); + }; + + handleDragEnd = () => { + this.setState({ isDraggingAny: false }); + }; render() { const { listItems } = this.props; + const { isDraggingAny } = this.state; return ( - + - - {i18n.t('Column')} - + + + {i18n.t('Column')} + {i18n.t('Visible')} + {listItems.map((item, i) => ( @@ -63,10 +68,13 @@ export class DragDropList extends Component { moveListItem={this.moveListItem} handleToggle={this.props.handleToggle} visible={item.visible} + isDraggingAny={isDraggingAny} + onDragStart={this.handleDragStart} + onDragEnd={this.handleDragEnd} /> ))} -
+
); } diff --git a/src/core_modules/capture-core/components/ListView/ColumnSelector/DragDropList/DragDropListItem.component.js b/src/core_modules/capture-core/components/ListView/ColumnSelector/DragDropList/DragDropListItem.component.js index d7f63bde76..2f9087aa2f 100644 --- a/src/core_modules/capture-core/components/ListView/ColumnSelector/DragDropList/DragDropListItem.component.js +++ b/src/core_modules/capture-core/components/ListView/ColumnSelector/DragDropList/DragDropListItem.component.js @@ -1,107 +1,102 @@ // @flow -import React, { Component } from 'react'; -import { DragSource, DropTarget } from 'react-dnd'; -import { Checkbox, IconReorder24, spacersNum } from '@dhis2/ui'; -import TableCell from '@material-ui/core/TableCell'; +import React, { useRef } from 'react'; +import { useDrag, useDrop } from 'react-dnd'; +import { DataTableRow, DataTableCell, Checkbox } from '@dhis2/ui'; import { withStyles } from '@material-ui/core/styles'; -const styles = () => ({ - checkbox: { - marginTop: spacersNum.dp12, - marginBottom: spacersNum.dp12, +const ItemTypes = { + LISTITEM: 'listItem', +}; + +const styles = { + rowWithoutHover: { + '&:hover > td': { + backgroundColor: 'transparent !important', + }, }, -}); +}; type Props = { id: string, visible: boolean, text: string, - handleToggle: (id: string) => void, - isDragging: () => void, - connectDragSource: (any) => void, - connectDropTarget: (any) => void, - classes: { - checkbox: string, - } + index: number, + handleToggle: (id: string) => any, + moveListItem: (dragIndex: number, hoverIndex: number) => void, + isDraggingAny: boolean, + onDragStart: () => void, + onDragEnd: () => void, + classes: any, }; -const style = { - cursor: 'move', - outline: 'none', -}; +const DragDropListItemPlain = ({ + id, + index, + text, + visible, + handleToggle, + moveListItem, + isDraggingAny, + onDragStart, + onDragEnd, + classes, +}: Props) => { + const ref = useRef(null); -const ItemTypes = { - LISTITEM: 'listItem', -}; + const [, drop] = useDrop({ + accept: ItemTypes.LISTITEM, + hover(item: { id: string, index: number }) { + const dragIndex = item.index; + const hoverIndex = index; -const cardSource = { - beginDrag(props) { - return { - id: props.id, - index: props.index, - }; - }, -}; + // Don't replace items with themselves. + if (dragIndex === hoverIndex) { + return; + } -const cardTarget = { - hover(props, monitor) { - const dragIndex = monitor.getItem().index; - const hoverIndex = props.index; + // Time to actually perform the action + moveListItem(dragIndex, hoverIndex); - // Don't replace items with themselves. - if (dragIndex === hoverIndex) { - return; - } + // Note: we're mutating the item here! + // Generally it's better to avoid mutations, + // but it's good here for the sake of performance + // to avoid expensive index searches. + item.index = hoverIndex; + }, + }); - // Time to actually perform the action. - props.moveListItem(dragIndex, hoverIndex); + const [{ isDragging }, drag] = useDrag({ + type: ItemTypes.LISTITEM, + item: { id, index }, + collect: monitor => ({ + isDragging: monitor.isDragging(), + }), + }); - // Note: we're mutating the monitor item here! - // Generally it's better to avoid mutations, - // but it's good here for the sake of performance - // to avoid expensive index searches. - monitor.getItem().index = hoverIndex; - }, -}; - -class Index extends Component { - render() { - const { text, isDragging, connectDragSource, connectDropTarget } = this.props; - const opacity = isDragging ? 0 : 1; + drag(drop(ref)); - // $FlowFixMe[incompatible-extend] automated comment - return connectDropTarget(connectDragSource( - - - - - - - - - - , - )); - } -} + const opacity = isDragging ? 0 : 1; -export const DragDropListItemPlain = - DragSource( - ItemTypes.LISTITEM, - cardSource, - (connect, monitor) => ({ connectDragSource: connect.dragSource(), isDragging: monitor.isDragging() }), - )(DropTarget( - ItemTypes.LISTITEM, - cardTarget, - connect => ({ connectDropTarget: connect.dropTarget() }), - )(Index)); + return ( + + {text} + + + + + ); +}; export const DragDropListItem = withStyles(styles)(DragDropListItemPlain);