bca52cb6fa
* fix filter button style * display completed todos * fix reward control position * begin to add edit modal * start adding settings to edit modal * add task saving, creating and deleting * fixes * add tags and repeat frequency for habits * clicking on links should not open the edit modal * checklist editing * repeatables and checklists * delete checklist items * add rewards price * update shrinkwrap * pin cwait
131 lines
3.8 KiB
JavaScript
131 lines
3.8 KiB
JavaScript
import { loadAsyncResource } from 'client/libs/asyncResource';
|
|
import axios from 'axios';
|
|
import compact from 'lodash/compact';
|
|
import omit from 'lodash/omit';
|
|
|
|
export function fetchUserTasks (store, forceLoad = false) {
|
|
return loadAsyncResource({
|
|
store,
|
|
path: 'tasks',
|
|
url: '/api/v3/tasks/user',
|
|
deserialize (response) {
|
|
// Wait for the user to be loaded before deserializing
|
|
// because user.tasksOrder is necessary
|
|
return store.dispatch('user:fetch').then((userResource) => {
|
|
return store.dispatch('tasks:order', [response.data.data, userResource.data.tasksOrder]);
|
|
});
|
|
},
|
|
forceLoad,
|
|
});
|
|
}
|
|
|
|
export async function fetchCompletedTodos (store, forceLoad = false) {
|
|
// Wait for the user to be loaded before deserializing
|
|
// because user.tasksOrder is necessary
|
|
await store.dispatch('tasks:fetchUserTasks');
|
|
|
|
const loadStatus = store.state.completedTodosStatus;
|
|
if (loadStatus === 'NOT_LOADED' || forceLoad) {
|
|
store.state.completedTodosStatus = 'LOADING';
|
|
|
|
const response = await axios.get('/api/v3/tasks/user?type=completedTodos');
|
|
const completedTodos = response.data.data;
|
|
const tasks = store.state.tasks.data;
|
|
// Remove existing completed todos
|
|
tasks.todos = tasks.todos.filter(t => !t.completed);
|
|
tasks.todos.push(...completedTodos);
|
|
|
|
store.state.completedTodosStatus = 'LOADED';
|
|
} else if (status === 'LOADED') {
|
|
return;
|
|
} else if (loadStatus === 'LOADING') {
|
|
const watcher = store.watch(state => state.completedTodosStatus, (newLoadingStatus) => {
|
|
watcher(); // remove the watcher
|
|
if (newLoadingStatus === 'LOADED') {
|
|
return;
|
|
} else {
|
|
throw new Error(); // TODO add reason?
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
export function order (store, [rawTasks, tasksOrder]) {
|
|
const tasks = {
|
|
habits: [],
|
|
dailys: [],
|
|
todos: [],
|
|
rewards: [],
|
|
};
|
|
|
|
rawTasks.forEach(task => {
|
|
tasks[`${task.type}s`].push(task);
|
|
});
|
|
|
|
Object.keys(tasks).forEach((type) => {
|
|
let tasksOfType = tasks[type];
|
|
|
|
const orderOfType = tasksOrder[type];
|
|
const orderedTasks = new Array(tasksOfType.length);
|
|
const unorderedTasks = []; // what we want to add later
|
|
|
|
tasksOfType.forEach((task, index) => {
|
|
const taskId = task._id;
|
|
const i = orderOfType[index] === taskId ? index : orderOfType.indexOf(taskId);
|
|
if (i === -1) {
|
|
unorderedTasks.push(task);
|
|
} else {
|
|
orderedTasks[i] = task;
|
|
}
|
|
});
|
|
|
|
tasks[type] = compact(orderedTasks).concat(unorderedTasks);
|
|
});
|
|
|
|
return tasks;
|
|
}
|
|
|
|
function sanitizeChecklist (task) {
|
|
if (task.checklist) {
|
|
task.checklist = task.checklist.filter((i) => {
|
|
return Boolean(i.text);
|
|
});
|
|
}
|
|
}
|
|
export async function create (store, createdTask) {
|
|
const type = `${createdTask.type}s`;
|
|
const list = store.state.tasks.data[type];
|
|
|
|
sanitizeChecklist(createdTask);
|
|
|
|
list.unshift(createdTask);
|
|
store.state.user.data.tasksOrder[type].unshift(createdTask._id);
|
|
const response = await axios.post('/api/v3/tasks/user', createdTask);
|
|
|
|
Object.assign(list[0], response.data.data);
|
|
}
|
|
|
|
export async function save (store, editedTask) {
|
|
const taskId = editedTask._id;
|
|
const type = editedTask.type;
|
|
const originalTask = store.state.tasks.data[`${type}s`].find(t => t._id === taskId);
|
|
|
|
sanitizeChecklist(editedTask);
|
|
|
|
Object.assign(originalTask, editedTask);
|
|
|
|
const taskDataToSend = omit(originalTask, ['history']);
|
|
const response = await axios.put(`/api/v3/tasks/${originalTask._id}`, taskDataToSend);
|
|
Object.assign(originalTask, response.data.data);
|
|
}
|
|
|
|
export async function destroy (store, task) {
|
|
const list = store.state.tasks.data[`${task.type}s`];
|
|
const taskIndex = list.findIndex(t => t._id === task._id);
|
|
|
|
if (taskIndex > -1) {
|
|
list.splice(taskIndex, 1);
|
|
}
|
|
|
|
await axios.delete(`/api/v3/tasks/${task._id}`);
|
|
} |