From a67303087ab496321eb5b9069ee0ae6d0f67a983 Mon Sep 17 00:00:00 2001 From: Roland Bernard <rolbernard@unibz.it> Date: Sat, 1 May 2021 20:13:40 +0200 Subject: [PATCH] Added comment creation/updating API paths --- server/src/v1/comment.ts | 156 ++++++++++++++++++++++++++++++++++- server/src/v1/task.ts | 174 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 329 insertions(+), 1 deletion(-) diff --git a/server/src/v1/comment.ts b/server/src/v1/comment.ts index 664dea1..f7739b9 100644 --- a/server/src/v1/comment.ts +++ b/server/src/v1/comment.ts @@ -1,13 +1,167 @@ import express from 'express'; +import { v4 as uuid, validate } from 'uuid'; -import { requireVerification } from './auth'; +import database from '../database'; +import { requireVerification, Token } from './auth'; +import { isOfType } from '../util'; const comment = express(); comment.use(requireVerification); +interface AddCommentBody { + task: string; + text: string; + token: Token; +} +comment.post('/', async (req, res) => { + if (isOfType<AddCommentBody>(req.body, [['task', 'string'], ['text', 'string']])) { + try { + const task_id = req.body.task; + if (validate(task_id)) { + const comment_id = uuid(); + const task = await database('team_members') + .innerJoin('team_projects', 'team_members.team_id', 'team_projects.team_id') + .innerJoin('tasks', 'team_projects.project_id', 'tasks.project_id') + .select({ id: 'tasks.id' }) + .where({ + 'team_members.user_id': req.body.token.id, + 'tasks.id': task_id, + }); + if (task.length >= 1) { + await database('comments').insert({ + id: comment_id, + task_id: task_id, + user_id: req.body.token.id, + text: req.body.text, + created: new Date(), + edited: new Date(), + }); + res.status(200).json({ + status: 'success', + id: comment_id, + }); + } else { + res.status(404).json({ + status: 'error', + message: 'task not found', + }); + } + } else { + res.status(400).json({ + status: 'error', + message: 'malformed uuid', + }); + } + } catch (e) { + res.status(400).json({ + status: 'error', + message: 'failed to create comment', + }); + } + } else { + res.status(400).json({ + status: 'error', + message: 'missing request fields', + }); + } +}); + +interface UpdateCommentBody { + text?: string; + token: Token; +} + +comment.put('/:uuid', async (req, res) => { + if (isOfType<UpdateCommentBody>(req.body, [])) { + try { + const comment_id = req.params.uuid; + if (validate(comment_id)) { + const comment = await database('comments') + .update({ + text: req.body.text, + edited: new Date(), + }) + .where({ + 'comments.user_id': req.body.token.id, + 'comments.id': comment_id, + }); + if (comment >= 1) { + res.status(200).json({ + status: 'success', + }); + } else { + res.status(404).json({ + status: 'error', + message: 'comment not found', + }); + } + } else { + res.status(400).json({ + status: 'error', + message: 'malformed uuid', + }); + } + } catch (e) { + res.status(400).json({ + status: 'error', + message: 'failed to update comment', + }); + } + } else { + res.status(400).json({ + status: 'error', + message: 'missing request fields', + }); + } +}); + +comment.get('/:uuid', async (req, res) => { + try { + const comment_id = req.params.uuid; + if (validate(comment_id)) { + const comment = await database('team_members') + .innerJoin('team_projects', 'team_members.team_id', 'team_projects.team_id') + .innerJoin('tasks', 'team_projects.project_id', 'tasks.project_id') + .innerJoin('comments', 'tasks.id', 'comments.task_id') + .select({ + id: 'comments.id', + task: 'comments.task_id', + user: 'comments.user_id', + text: 'comments.text', + created: 'comments.created', + edited: 'comments.edited', + }) + .where({ + 'team_members.user_id': req.body.token.id, + 'comments.id': comment_id, + }); + if (comment.length >= 1) { + res.status(200).json({ + status: 'success', + comment: comment[0], + }); + } else { + res.status(404).json({ + status: 'error', + message: 'comment not found', + }); + } + } else { + res.status(400).json({ + status: 'error', + message: 'malformed uuid', + }); + } + } catch (e) { + res.status(400).json({ + status: 'error', + message: 'failed to update comment', + }); + } +}); export default comment; diff --git a/server/src/v1/task.ts b/server/src/v1/task.ts index 4b13037..c849bbd 100644 --- a/server/src/v1/task.ts +++ b/server/src/v1/task.ts @@ -33,6 +33,7 @@ export interface Task { export function generateFromFlatResult(results: any[]): Task[] { const grouped_tasks: Record<string, Task> = { }; + const to_remove: Array<string> = []; for (const row of results) { if (!grouped_tasks[row.id]) { grouped_tasks[row.id] = { @@ -75,6 +76,12 @@ export function generateFromFlatResult(results: any[]): Task[] { grouped_tasks[row.id].dependentcies.push(row.dependentcy); } } + if (row.dependentcy_status && row.dependentcy_status !== 'closed') { + to_remove.push(row.id); + } + } + for (const remove of to_remove) { + delete grouped_tasks[remove]; } return Object.values(grouped_tasks); } @@ -83,6 +90,173 @@ const task = express(); task.use(requireVerification); +task.get('/', async (req, res) => { + try { + const tasks = await database('team_members') + .innerJoin('team_projects', 'team_members.team_id', 'team_projects.team_id') + .innerJoin('tasks', 'team_projects.project_id', 'tasks.project_id') + .leftJoin('task_requirements', 'tasks.id', 'task_requirements.task_id') + .leftJoin('task_dependencies', 'tasks.id', 'task_dependencies.task_id') + .leftJoin('task_assignees', 'tasks.id', 'task_assignees.task_id') + .select({ + id: 'tasks.id', + project: 'tasks.project_id', + name: 'tasks.name', + text: 'tasks.text', + icon: 'tasks.icon', + status: 'tasks.status', + priority: 'tasks.priority', + created: 'tasks.created', + edited: 'tasks.edited', + requirement_role: 'task_requirements.role_id', + requirement_time: 'task_requirements.time', + assigned_user: 'task_assignees.user_id', + assigned_time: 'task_assignees.time', + dependentcy: 'task_dependencies.requires_id', + }) + .where({ + 'team_members.user_id': req.body.token.id, + }); + res.status(200).json({ + status: 'success', + tasks: generateFromFlatResult(tasks), + }); + } catch (e) { + res.status(400).json({ + status: 'error', + message: 'failed get tasks', + }); + } +}); + +task.get('/open', async (req, res) => { + try { + const tasks = await database('team_members') + .innerJoin('team_projects', 'team_members.team_id', 'team_projects.team_id') + .innerJoin('tasks', 'team_projects.project_id', 'tasks.project_id') + .leftJoin('task_requirements', 'tasks.id', 'task_requirements.task_id') + .leftJoin('task_dependencies', 'tasks.id', 'task_dependencies.task_id') + .leftJoin('task_assignees', 'tasks.id', 'task_assignees.task_id') + .select({ + id: 'tasks.id', + project: 'tasks.project_id', + name: 'tasks.name', + text: 'tasks.text', + icon: 'tasks.icon', + status: 'tasks.status', + priority: 'tasks.priority', + created: 'tasks.created', + edited: 'tasks.edited', + requirement_role: 'task_requirements.role_id', + requirement_time: 'task_requirements.time', + assigned_user: 'task_assignees.user_id', + assigned_time: 'task_assignees.time', + dependentcy: 'task_dependencies.requires_id', + }) + .where({ + 'team_members.user_id': req.body.token.id, + 'tasks.status': 'open', + }); + res.status(200).json({ + status: 'success', + tasks: generateFromFlatResult(tasks), + }); + } catch (e) { + res.status(400).json({ + status: 'error', + message: 'failed get tasks', + }); + } +}); + +task.get('/possible', async (req, res) => { + try { + const tasks = await database('team_members') + .innerJoin('team_projects', 'team_members.team_id', 'team_projects.team_id') + .innerJoin('tasks', 'team_projects.project_id', 'tasks.project_id') + .leftJoin('task_requirements', 'tasks.id', 'task_requirements.task_id') + .leftJoin('task_dependencies', 'tasks.id', 'task_dependencies.task_id') + .leftJoin({ 'require': 'tasks' }, 'task_dependencies.requires_id', 'require.id') + .leftJoin('task_assignees', 'tasks.id', 'task_assignees.task_id') + .select({ + id: 'tasks.id', + project: 'tasks.project_id', + name: 'tasks.name', + text: 'tasks.text', + icon: 'tasks.icon', + status: 'tasks.status', + priority: 'tasks.priority', + created: 'tasks.created', + edited: 'tasks.edited', + requirement_role: 'task_requirements.role_id', + requirement_time: 'task_requirements.time', + assigned_user: 'task_assignees.user_id', + assigned_time: 'task_assignees.time', + dependentcy: 'task_dependencies.requires_id', + dependentcy_status: 'require.status', + }) + .where({ + 'team_members.user_id': req.body.token.id, + 'tasks.status': 'open', + }); + res.status(200).json({ + status: 'success', + tasks: generateFromFlatResult(tasks), + }); + } catch (e) { + console.log(e); + res.status(400).json({ + status: 'error', + message: 'failed get tasks', + }); + } +}); + +task.get('/:uuid/comments', async (req, res) => { + try { + const id = req.params.uuid; + if (validate(id)) { + const comments = await database('team_members') + .innerJoin('team_projects', 'team_members.team_id', 'team_projects.team_id') + .innerJoin('tasks', 'team_projects.project_id', 'tasks.project_id') + .innerJoin('comments', 'tasks.id', 'comments.task_id') + .select({ + id: 'comments.id', + task: 'comments.task_id', + user: 'comments.user_id', + text: 'comments.text', + created: 'comments.created', + edited: 'comments.edited', + }) + .where({ + 'team_members.user_id': req.body.token.id, + 'tasks.id': id, + }); + if (task.length >= 1) { + res.status(200).json({ + status: 'success', + comments: comments, + }); + } else { + res.status(404).json({ + status: 'error', + message: 'task not found', + }); + } + } else { + res.status(400).json({ + status: 'error', + message: 'malformed uuid', + }); + } + } catch (e) { + res.status(400).json({ + status: 'error', + message: 'failed get comments', + }); + } +}); + task.get('/:uuid', async (req, res) => { try { const id = req.params.uuid; -- GitLab