Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

In the dispatch panel, add selection with SHIFT/MAJ key in unassigned tasks + ESC press shortcut to unselect all #4772

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions assets/css/utils.scss
Original file line number Diff line number Diff line change
Expand Up @@ -86,3 +86,9 @@ li > a.text-danger // very specific selector for bootstrap dropdown
{
color: $red;
}

.no-select {
-webkit-user-select: none; /* Safari */
-ms-user-select: none; /* IE 10 and IE 11 */
user-select: none; /* Standard syntax */
}
9 changes: 7 additions & 2 deletions js/app/dashboard/components/RightPanel.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ import {
loadOrganizations,
loadVehicles,
loadTrailers,
loadWarehouses
loadWarehouses,
selectTasksByIds
} from '../redux/actions'
import { UnassignedTasks } from './UnassignedTasks'
import { UnassignedTours } from './UnassignedTours'
Expand Down Expand Up @@ -80,8 +81,12 @@ const DashboardApp = ({ loadingAnim }) => {
generateOrders(date)
}, [date]);

const unselectAll = () => {
dispatch(selectTasksByIds([]))
}

return (
<div className="dashboard__aside-container">
<div className="dashboard__aside-container" onKeyDown={ (e) => e.keyCode === 27 && unselectAll() }>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

=== 27 create a const instead for a magic number

<DragDropContext
// https://github.com/atlassian/@hello-pangea/dnd/blob/master/docs/patterns/multi-drag.md
onDragStart={ (result) => dispatch(handleDragStart(result)) }
Expand Down
2 changes: 1 addition & 1 deletion js/app/dashboard/components/SearchInput.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ class SearchInput extends React.Component {
q: '',
results: [],
})
this.searchRef.blur()
this.searchRef.blur && this.searchRef.blur()
}
}

Expand Down
39 changes: 35 additions & 4 deletions js/app/dashboard/components/Task.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,16 @@ import _ from 'lodash'
import { Draggable } from "@hello-pangea/dnd"


import { setCurrentTask, toggleTask, selectTask } from '../redux/actions'
import { selectSettings, selectVisibleTaskIds } from '../redux/selectors'
import { setCurrentTask, toggleTask, selectTask, selectTasksByIds } from '../redux/actions'
import { selectSettings, selectStandaloneTasks, selectVisibleTaskIds } from '../redux/selectors'
import { selectSelectedDate, selectTasksWithColor } from '../../coopcycle-frontend-js/logistics/redux'

import { addressAsText } from '../utils'
import TaskEta from './TaskEta'
import { getTaskPackages, getTaskVolumeUnits, selectTaskById } from '../../../shared/src/logistics/redux/selectors'
import { formatVolumeUnits, formatWeight } from '../redux/utils'
import { toast } from 'react-toastify'
import i18next from 'i18next'

moment.locale($('html').attr('lang'))

Expand Down Expand Up @@ -187,8 +189,33 @@ class Task extends React.Component {
const multiple = (e.ctrlKey || e.metaKey)
this.timer = setTimeout(() => {
if (!this.prevent) {
const { toggleTask, task } = this.props
toggleTask(task, multiple)
if (e.shiftKey && this.props.selectedTasks.length > 0) {
if (this.props.task.isAssigned) {
toast.warn(i18next.t("ADMIN_DASHBOARD_ONLY_UNASSIGNED_WITH_SHIFT"))
} else {
const standaloneTaskIds = this.props.standaloneTasks.map(t => t['@id'])
const taskPosition = standaloneTaskIds.findIndex(id => id === this.props.task['@id'])

const latestSelectedTaskId = this.props.selectedTasks.slice(-1).at(0)
const latestSelectedTaskPosition = standaloneTaskIds.findIndex(id => id === latestSelectedTaskId)

const startIndex = taskPosition > latestSelectedTaskPosition ? latestSelectedTaskPosition : taskPosition
const endIndex = taskPosition > latestSelectedTaskPosition ? taskPosition + 1 : latestSelectedTaskPosition + 1

const toSelect = taskPosition > latestSelectedTaskPosition ? [...this.props.selectedTasks, ...standaloneTaskIds.slice(startIndex, endIndex)] : standaloneTaskIds.slice(startIndex, endIndex)

this.props.selectTasksByIds(
_.intersection(
this.props.visibleTaskIds, // user wants only to select tasks visible to theirs ^^
toSelect
)
)
}
e.preventDefault()
} else {
const { toggleTask, task } = this.props
toggleTask(task, multiple)
}
}
this.prevent = false
}, 250)
Expand All @@ -213,6 +240,7 @@ class Task extends React.Component {
const { color, task, selected, isVisible, date, showWeightAndVolumeUnit } = this.props

const classNames = [
'no-select',
'list-group-item',
'list-group-item--' + task.type.toLowerCase(),
'list-group-item--' + task.status.toLowerCase(),
Expand Down Expand Up @@ -335,9 +363,11 @@ function mapStateToProps(state, ownProps) {
task: task,
selectedTasks: selectedTasks,
selected: -1 !== selectedTasks.indexOf(task['@id']),
standaloneTasks: selectStandaloneTasks(state),
color,
date: selectSelectedDate(state),
isVisible: _.includes(visibleTaskIds, task['@id']),
visibleTaskIds: visibleTaskIds,
showWeightAndVolumeUnit: showWeightAndVolumeUnit
}
}
Expand All @@ -347,6 +377,7 @@ function mapDispatchToProps (dispatch) {
setCurrentTask: (task) => dispatch(setCurrentTask(task)),
toggleTask: (task, multiple) => dispatch(toggleTask(task, multiple)),
selectTask: (task) => dispatch(selectTask(task)),
selectTasksByIds: (taskIds) => dispatch(selectTasksByIds(taskIds)),
}
}

Expand Down
4 changes: 3 additions & 1 deletion js/app/dashboard/components/UnassignedTasks.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import Alert from '../../components/core/Alert'

const StandaloneTasks = ({tasks, offset}) => {
// waiting for https://github.com/coopcycle/coopcycle-web/issues/4196 to resolve to bring this code back
// takes into account manual sorting of issues
// handle manual sorting of tasks into the unassigned column
// return _.map(unassignedTasksIdsOrder, (taskId, index) => {
// const task = tasks.find(t => t['@id'] === taskId)
// if (task) {
Expand Down Expand Up @@ -91,6 +91,8 @@ export const UnassignedTasks = ({ isGeneratingOrdersForRecurrenceRules }) => {
const unassignedTasksIdsOrder = useSelector(selectOrderOfUnassignedTasks)
const unassignedTasksLoading = useSelector(selectUnassignedTasksLoading)

// waiting for https://github.com/coopcycle/coopcycle-web/issues/4196 to resolve to bring this code back to life
// handle manual sorting of tasks into the unassigned column
useEffect(() => {
const tasksToAppend = _.filter(standaloneTasks, t => !unassignedTasksIdsOrder.includes(t['@id']))
const tasksToAppendIds = tasksToAppend.map(t => t['@id'])
Expand Down
1 change: 1 addition & 0 deletions js/app/i18n/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@
"ADMIN_DASHBOARD_FILTERS_SHOW_ALL": "Show all",
"ADMIN_DASHBOARD_FILTERS_HIDE": "Hide",
"ADMIN_DASHBOARD_HIDE_SHOW_ON_MAP": "Hide/show on map",
"ADMIN_DASHBOARD_ONLY_UNASSIGNED_WITH_SHIFT": "Only unassigned tasks column handle shift selection",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can mention that a user can use command key on macos / Ctrl? on windows to select individual tasks. I tested it works for both unassigned and assigned tasks

"ADMIN_DASHBOARD_FILTERS_INCIDENT_REPORTED_TASKS": "Tasks with incident reports",
"ONLY_SHOW_THESE": "Only show these",
"ONLY_THIS_FILTER": "This filter exclusively",
Expand Down
1 change: 1 addition & 0 deletions js/app/i18n/locales/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@
"ADMIN_DASHBOARD_FILTERS_INCIDENT_REPORTED_TASKS": "Tâches avec des rapports d'incident",
"ONLY_SHOW_THESE": "Montrer uniquement ceux-ci",
"ONLY_THIS_FILTER": "Ce filtre exclusivement",
"ADMIN_DASHBOARD_ONLY_UNASSIGNED_WITH_SHIFT": "Seule la colonne non-assignées supporte la sélection avec MAJ",
"ADMIN_DASHBOARD_TASK_CAPTION_SHORT": "Tâche #{{id}}",
"ADMIN_DASHBOARD_TASK_TIME_RANGE": "Entre {{after}} et {{before}}",
"ADMIN_DASHBOARD_TASK_ASSIGNED_TO": "Assignée à {{username}}",
Expand Down
Loading