{"size": 3166, "ext": "js", "max_stars_repo_path": "src/components/TaskList.js", "max_stars_repo_name": "smaspe/taskman", "max_stars_repo_stars_event_min_datetime": "2019-09-09T16:30:46.000Z", "max_stars_repo_stars_event_max_datetime": "2021-11-15T21:43:24.000Z", "max_issues_repo_path": "src/components/TaskList.js", "max_issues_repo_name": "smaspe/taskman", "max_issues_repo_issues_event_min_datetime": "2018-06-10T02:09:45.000Z", "max_issues_repo_issues_event_max_datetime": "2018-07-08T05:59:54.000Z", "max_forks_repo_path": "src/components/TaskList.js", "max_forks_repo_name": "smaspe/taskman", "max_forks_repo_forks_event_min_datetime": "2019-08-30T03:31:17.000Z", "max_forks_repo_forks_event_max_datetime": "2021-07-22T14:02:14.000Z"}
{"max_stars_count": 8, "max_issues_count": 19, "max_forks_count": 3, "avg_line_length": 35.5730337079, "max_line_length": 101, "alphanum_fraction": 0.5925457991}
import React from 'react';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import { SortableContainer, arrayMove } from 'react-sortable-hoc';
import Task from './Task';
import { setEditTask, saveTask, TaskStatus } from '../actions';
import moment from 'moment';
import { insert } from '../tools/orderIndex';
import { taskSort } from '../db';
import TaskListHeader from './TaskListHeader';
import EditTask from './EditTask';
import { CSSTransitionGroup } from 'react-transition-group'

const TaskList = SortableContainer(({ taskList, edit, setTaskStatus, editTask }) => {
    const tasks = taskList.map((task, index) => {
        if (edit && edit.task_id === task.task_id) {
            return <EditTask task={edit} key={'edit' + edit.task_id} index={index} />;
        }
        return <Task task={task}
            setTaskStatus={status => setTaskStatus(task, status)}
            editTask={() => editTask(task)}
            key={task.task_id} index={index} />
    });
    return (
        <div className="task_list shadow">
            <TaskListHeader />
            <CSSTransitionGroup
                transitionEnterTimeout={1}
                transitionLeave={false}
                transitionName="edit">
                {tasks}
            </CSSTransitionGroup>
        </div>

    );
});

const mapStateToProps = state => {
    return {
        taskList: Object.values(state.tasks).filter(task => {
            if (!state.filter.completed) {
                if (task.status === TaskStatus.COMPLETED) {
                    return false;
                }
            }
            if (!state.filter.snoozed) {
                if (task.snoozeUntil && task.snoozeUntil.isAfter(moment())) {
                    return false;
                }
            }
            return true;
        }).sort(taskSort),
        edit: state.edit,
        // Used by SortableContainer
        useDragHandle: false,
        pressDelay: 200
    }
};

const mapDispatchToProps = (dispatch) => {
    return {
        // TODO move those 2 to Task directly
        setTaskStatus: (task, status) => dispatch(saveTask({ ...task, status })),
        editTask: task => dispatch(setEditTask(task)),
        saveTask: bindActionCreators(saveTask, dispatch)
    }
}

const mergeProps = (stateProps, dispatchProps) => ({
    ...stateProps,
    ...dispatchProps,
    // Called by SortableContainer directly
    onSortEnd: ({ oldIndex, newIndex }) => {
        if (oldIndex === newIndex) {
            return;
        }
        // Find the new index of the task, update the task, dispatch the save action
        // TODO find the indices without actually performing the move, that's expensive for no reason
        const newList = arrayMove(stateProps.taskList, oldIndex, newIndex);
        const before = (newIndex > 0) ? newList[newIndex - 1].order : null;
        const after = (newIndex < (newList.length - 1)) ? newList[newIndex + 1].order : null;
        newList[newIndex].order = insert(before, after);

        dispatchProps.saveTask(newList[newIndex]);
    },
})

export default connect(mapStateToProps, mapDispatchToProps, mergeProps)(TaskList);
