Skip to content

Commit

Permalink
Merge pull request #68 from FLiotta/client-server/add-task-indexes
Browse files Browse the repository at this point in the history
Add Index to tasks and position functionality
  • Loading branch information
FLiotta authored Oct 8, 2020
2 parents 9035ae8 + 191632b commit 232517c
Show file tree
Hide file tree
Showing 11 changed files with 110 additions and 23 deletions.
31 changes: 28 additions & 3 deletions client/src/actions/board.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import TasksService from '../services/tasksService';
import PrioritiesService from '../services/prioritiesService';
import { IRootReducer } from '../reducers/rootReducer';
import { IList } from '../interfaces/List';
import ListService from '../services/listsService';

const prioritiesService = new PrioritiesService();
const taskService = new TasksService();
Expand All @@ -26,7 +27,31 @@ export const FETCH_PRIORITIES: string = '[BOARD] FETCH PRIORITIES';
export const EDIT_LIST_TITLE: string = '[BOARD] EDIT LIST TITLE';
export const UPDATE_TASK_TITLE: string = '[BOARD] UPDATE_TASK_TITLE';
export const SET_LISTS: string = '[BOARD] SET_LISTS';
export const SORT_LIST: string = '[BOARD] SORT_LIST';
export const ORDER_TASKS: string = '[BOARD] ORDER_TASKS';

export const sortList = (listId: number, taskId: number, index: number, destinationIndex: number) => {
return (dispatch, getState) => {
const state: IRootReducer = getState();
const list: any = new Object(state.board.lists.find(list => list.id === listId));

const [task] = list.tasks.splice(index, 1);
list.tasks.splice(destinationIndex, 0, task);

const order = list.tasks.map(task => task.id);

return listsService.sortTasks(listId, order)
.then(({ data }) => {
dispatch({
type: ORDER_TASKS,
payload: {
listId,
tasks: list.tasks
}
})
})
}
}
export const editListTitle = (listId: number, title: string) => {
return dispatch => listsService.editTitle(listId, title)
.then(({ data }) => {
Expand Down Expand Up @@ -123,17 +148,17 @@ export const addTask = (taskTitle: string, listId: number) => {
});
}

export const moveTask = (originListId: number, destinyListId: number, taskId: number) => {
export const moveTask = (originListId: number, destinyListId: number, taskId: number, destinationIndex: number) => {
return (dispatch, getState) => {
const state: IRootReducer = getState();
const previousListsState: IList[] = state.board.lists;

dispatch({
type: MOVE_TASK,
payload: { destinyListId, originListId, taskId },
payload: { destinyListId, originListId, taskId, destinationIndex },
});

taskService.updateList(taskId, destinyListId)
taskService.updateList(taskId, destinyListId, destinationIndex)
.then(resp => { })
.catch(e => {
cogoToast.error(`There was a problem updating your task.`, { position: 'bottom-right' });
Expand Down
2 changes: 0 additions & 2 deletions client/src/components/List/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@ const List = ({ id, title, tasks, onDelete, editListTitle }: IProps): JSX.Elemen
const [deleteModalOpen, setDeleteModalOpen] = useState(false);

const handleDelete = (callback) => {
// TODO
// Dispatch and delete list
onDelete()
setDeleteModalOpen(false);

Expand Down
1 change: 1 addition & 0 deletions client/src/interfaces/Task.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ export interface ITask {
description?: string,
priority?: string,
list: number,
position: number,
};
13 changes: 10 additions & 3 deletions client/src/pages/Board/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
resetState,
fetchPriorities,
deleteList,
sortList,
} from '../../actions/board';
import List from '../../components/List';
import CreateList from '../../components/CreateList';
Expand All @@ -22,12 +23,13 @@ import { AxiosPromise } from 'axios';

interface IProps {
fetchBoard(boardId: number): AxiosPromise,
moveTask(originListId: number, destinationListId: number, taskId: number): void,
moveTask(originListId: number, destinationListId: number, taskId: number, destinationIndex: number): void,
board: IBoard,
match: any,
resetState(): void,
fetchPriorities(): void
deleteList(listId: number): void,
sortList(listId: number, taskId: number, index:number, destinationIndex: number): void,
};

const Board = ({
Expand All @@ -38,6 +40,7 @@ const Board = ({
resetState,
fetchPriorities,
deleteList,
sortList,
}: IProps): JSX.Element => {
const [isLoading, setIsLoading] = useState(true);

Expand All @@ -54,13 +57,16 @@ const Board = ({
}, []);

const onDragEnd = (e: any): void => {
console.log(e);
const { draggableId, destination, source } = e;
const originListId = parseInt(source.droppableId);
const destinationListId = parseInt(destination.droppableId);
const taskId = parseInt(draggableId);

if (originListId != destinationListId) {
moveTask(originListId, destinationListId, taskId);
moveTask(originListId, destinationListId, taskId, destination.index);
} else {
sortList(originListId, taskId, source.index, destination.index);
}
}

Expand Down Expand Up @@ -98,7 +104,8 @@ const mapDispatchToProps = dispatch => ({
fetchBoard: (boardId): AxiosPromise => dispatch(fetchBoard(boardId)),
resetState: () => dispatch(resetState()),
deleteList: (listId: number) => dispatch(deleteList(listId)),
moveTask: (originListId, destinationListId, taskId) => dispatch(moveTask(originListId, destinationListId, taskId)),
sortList: (listId: number, taskId: number,index: number, destinationIndex: number) => dispatch(sortList(listId, taskId, index, destinationIndex)),
moveTask: (originListId, destinationListId, taskId, destinationIndex) => dispatch(moveTask(originListId, destinationListId, taskId, destinationIndex)),
})

export default withRouter(connect(mapStateToProps, mapDispatchToProps)(Board));
15 changes: 14 additions & 1 deletion client/src/reducers/board.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
EDIT_LIST_TITLE,
UPDATE_TASK_TITLE,
SET_LISTS,
ORDER_TASKS,
} from '../actions/board';

export interface IBoardReducer extends IBoard { };
Expand All @@ -38,6 +39,14 @@ export default (state: IBoardReducer = defaultState, action) => {
...state,
priorities: action.payload,
};
case ORDER_TASKS:
return {
...state,
lists: state.lists.map(list => ({
...list,
tasks: list.id == action.payload.listId ? action.payload.tasks : list.tasks
}))
}
case EDIT_LIST_TITLE:
return {
...state,
Expand Down Expand Up @@ -87,7 +96,11 @@ export default (state: IBoardReducer = defaultState, action) => {
if (list.id === action.payload.originListId) {
parsed_list.tasks = parsed_list.tasks.filter(i_task => i_task.id !== action.payload.taskId);
} else if (list.id === action.payload.destinyListId) {
parsed_list.tasks = [...parsed_list.tasks, task];
parsed_list.tasks.splice(action.payload.destinationIndex, 0, task);

parsed_list.tasks.forEach((task, i) => {
task.position = i;
});
}

return parsed_list;
Expand Down
4 changes: 4 additions & 0 deletions client/src/services/listsService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ class ListService extends ApiService {
editTitle(listId: number, title: string): AxiosPromise {
return this.patch(`/lists/${listId}/title`, { title });
}

sortTasks(listId: number, order: number[]): AxiosPromise {
return this.post(`/lists/${listId}/sort`, { order });
}
}

export default ListService;
4 changes: 2 additions & 2 deletions client/src/services/tasksService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ class TasksService extends ApiService {
return this.delete(`/tasks/${taskId}`);
}

updateList(taskId: number, listId: number) {
return this.patch(`/tasks/${taskId}/list`, { listId });
updateList(taskId: number, listId: number, position: number) {
return this.patch(`/tasks/${taskId}/list`, { listId, position });
}

updateDescription(taskId: number, description: string) {
Expand Down
3 changes: 2 additions & 1 deletion server/app/models.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from sqlalchemy import Column, Integer, ForeignKey, Text
from sqlalchemy import Column, Integer, ForeignKey, Text, Sequence
from sqlalchemy.orm import relationship
from .db import db
import datetime
Expand Down Expand Up @@ -54,6 +54,7 @@ class Tasks(db.Model):
uid = Column(Text)
createdAt = Column('createdat', Integer)
description = Column(Text)
position = Column(Integer, Sequence('tasks_position_seq'))

def __init__(self, user_id, list_id, title, uid, description='', priority_id=1):
self.user_id = user_id
Expand Down
13 changes: 10 additions & 3 deletions server/app/routes/board_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
from ..models import Boards, Lists
from ..middlewares import protected_route
from uuid import uuid4
from operator import itemgetter

board = Blueprint('board', __name__)

# General boards creation and fetching endpoints
Expand All @@ -24,6 +26,7 @@ def get_boards():

return jsonify(result), 200


@board.route('/boards', methods=['POST'])
@protected_route
def new_board():
Expand Down Expand Up @@ -63,15 +66,19 @@ def get_board(board_id):
board_lists = []

for list_ in board.lists:
board_lists.append({
temp_list = {
"id": list_.id,
"title": list_.title,
"tasks": list(map(lambda t: {
'id': t.id,
'title': t.title,
'priority': t.priority.value if t.priority else None
'priority': t.priority.value if t.priority else None,
'position': t.position,
}, list_.tasks))
})
}

temp_list["tasks"] = sorted(temp_list["tasks"], key=itemgetter('position'))
board_lists.append(temp_list)

response = {
'id': board.id,
Expand Down
25 changes: 24 additions & 1 deletion server/app/routes/list_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,14 @@ def delete_list(list_id):
if result is not None:
if result.user_id != user_id:
return jsonify(msg="You can't perform this action."), 403

db.session.delete(result)
db.session.commit()

return jsonify(msg="List and all its tasks deleted."), 200
return jsonify(msg="List not found"), 404


@list_.route('/lists/<list_id>/title', methods=['PATCH'])
@protected_route
def edit_list_title(list_id):
Expand All @@ -64,6 +65,7 @@ def edit_list_title(list_id):

return jsonify(msg="Title updated"), 200


@list_.route('/lists/<list_id>/task', methods=['POST'])
@protected_route
def new_list_task(list_id):
Expand Down Expand Up @@ -92,3 +94,24 @@ def new_list_task(list_id):
'priority': new_task.priority.value,
}
}), 200


@list_.route('/lists/<list_id>/sort', methods=['POST'])
@protected_route
def sort_list_tasks(list_id):
req_data = request.get_json()
user_id = g.user.get('id')
order = req_data.get('order')

if order is None:
return jsonify(msg="Missing params"), 400

requested_tasks = Tasks.query.filter_by(
list_id=list_id, user_id=user_id).all()

for task in requested_tasks:
task.position = order.index(task.id)

db.session.commit()

return jsonify(msg="Tasks sorted"), 200
22 changes: 15 additions & 7 deletions server/app/routes/task_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,19 +50,27 @@ def delete_task(task_id):
@protected_route
def update_task_list(task_id):
req_data = request.get_json()
list_id = req_data.get('listId')
list_id = int(req_data.get('listId'))
new_position = int(req_data.get('position'))
user_id = g.user.get('id')

if list_id is None or task_id is None:
if list_id is None or task_id is None or new_position is None:
return jsonify(msg="Missing params"), 400

requested_list = Lists.query.filter_by(id=list_id).first()
tasks = Tasks.query.filter((Tasks.list_id==list_id) | (Tasks.id==task_id)).order_by(Tasks.position).all()

if requested_list.user_id != user_id:
return jsonify(msg="You can't perform this action."), 403
temp_task = None

requested_task = Tasks.query.filter_by(id=task_id).first()
requested_task.list_id = list_id
for i in range(len(tasks)):
if tasks[i].id == int(task_id):
tasks[i].list_id = list_id
temp_task = tasks.pop(i)
break

tasks.insert(new_position, temp_task)

for i, task in enumerate(tasks):
task.position = i

db.session.commit()

Expand Down

0 comments on commit 232517c

Please sign in to comment.