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

refactor: home page controller code cleanup #14

Open
wants to merge 4 commits into
base: development
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
421 changes: 59 additions & 362 deletions worklenz-backend/src/controllers/home-page-controller.ts

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions worklenz-backend/src/dtos/create-personal-task.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export class CreatePersonalTaskDto {
name: string|undefined = '';
color_code: string|undefined = '';
user_id: string|undefined = '';
}
1 change: 1 addition & 0 deletions worklenz-backend/src/dtos/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './create-personal-task.dto';
2 changes: 2 additions & 0 deletions worklenz-backend/src/interfaces/worklenz-request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,7 @@ import {Request} from "express";
import {IPassportSession} from "./passport-session";

export interface IWorkLenzRequest extends Request {
body: any;
query: any;
user?: IPassportSession;
}
1 change: 1 addition & 0 deletions worklenz-backend/src/services/projects/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './project.service';
69 changes: 69 additions & 0 deletions worklenz-backend/src/services/projects/project.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import database from "../../config/db";

export class ProjectService {

public static async getProjectsByTeam(team_id: string|undefined, user_id: string|undefined) {
const query = `
SELECT id, name, color_code
FROM projects
WHERE team_id = $1
AND is_member_of_project(projects.id, $2, $1)
`;
return await database.query(query, [team_id, user_id]);
}

public static async getProjects(team_id: string|undefined, user_id: string|undefined, current_view: string, filter: string) {

const isFavorites = current_view === "1" ? ` AND EXISTS(SELECT user_id FROM favorite_projects WHERE user_id = $2 AND project_id = projects.id)` : "";

const isArchived = filter === "2"
? ` AND EXISTS(SELECT user_id FROM archived_projects WHERE user_id = $2 AND project_id = projects.id)`
: ` AND NOT EXISTS(SELECT user_id FROM archived_projects WHERE user_id = $2 AND project_id = projects.id)`;

const query = `SELECT id,
name,
EXISTS(SELECT user_id
FROM favorite_projects
WHERE user_id = $2
AND project_id = projects.id) AS favorite,
EXISTS(SELECT user_id
FROM archived_projects
WHERE user_id = $2
AND project_id = projects.id) AS archived,
color_code,
(SELECT COUNT(*)
FROM tasks
WHERE archived IS FALSE
AND project_id = projects.id) AS all_tasks_count,
(SELECT COUNT(*)
FROM tasks
WHERE archived IS FALSE
AND project_id = projects.id
AND status_id IN (SELECT id
FROM task_statuses
WHERE project_id = projects.id
AND category_id IN
(SELECT id FROM sys_task_status_categories WHERE is_done IS TRUE))) AS completed_tasks_count,
(SELECT COUNT(*)
FROM project_members
WHERE project_id = projects.id) AS members_count,
(SELECT get_project_members(projects.id)) AS names,
(SELECT CASE
WHEN ((SELECT MAX(updated_at)
FROM tasks
WHERE archived IS FALSE
AND project_id = projects.id) >
updated_at)
THEN (SELECT MAX(updated_at)
FROM tasks
WHERE archived IS FALSE
AND project_id = projects.id)
ELSE updated_at END) AS updated_at
FROM projects
WHERE team_id = $1 ${isArchived} ${isFavorites} AND is_member_of_project(projects.id , $2
, $1)
ORDER BY updated_at DESC`;

return await database.query(query, [team_id, user_id]);
}
}
1 change: 1 addition & 0 deletions worklenz-backend/src/services/tasks/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './task.service';
266 changes: 266 additions & 0 deletions worklenz-backend/src/services/tasks/task.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,266 @@
import moment from "moment-timezone";
import momentTime from "moment-timezone";
import database from "../../config/db";
import {
TODAY_TAB,
UPCOMING_TAB,
OVERDUE_TAB,
NO_DUE_DATE_TAB,
ALL_TAB,
GROUP_BY_ASSIGN_BY_ME,
GROUP_BY_ASSIGNED_TO_ME
} from "../../shared/constants";
import {CreatePersonalTaskDto} from "../../dtos";

export class TaskService {

public static getTasksByGroupClosure(groupBy: string) {
switch (groupBy) {
case GROUP_BY_ASSIGN_BY_ME:
return `AND t.id IN (
SELECT task_id
FROM tasks_assignees
WHERE assigned_by = $2 AND team_id = $1)`;

case GROUP_BY_ASSIGNED_TO_ME:
default:
return `AND t.id IN (
SELECT task_id
FROM tasks_assignees
WHERE team_member_id = (SELECT id FROM team_members WHERE user_id = $2 AND team_id = $1))`;
}
}

public static getTasksByTabClosure(text: string) {
switch (text) {
case TODAY_TAB:
return `AND t.end_date::DATE = CURRENT_DATE::DATE`;
case UPCOMING_TAB:
return `AND t.end_date::DATE > CURRENT_DATE::DATE`;
case OVERDUE_TAB:
return `AND t.end_date::DATE < CURRENT_DATE::DATE`;
case NO_DUE_DATE_TAB:
return `AND t.end_date IS NULL`;
case ALL_TAB:
default:
return "";
}
}

public static async getTasksGroupByDate(currentTab: string, tasks: any[], timeZone: string, today: Date) {
const formatToday = moment(today).format("YYYY-MM-DD");

const tasksReturn = [];

if (currentTab === ALL_TAB) {
for (const task of tasks) {
tasksReturn.push(task);
}
}

if (currentTab === NO_DUE_DATE_TAB) {
for (const task of tasks) {
if (!task.end_date) {
tasksReturn.push(task);
}
}
}

if (currentTab === TODAY_TAB) {
for (const task of tasks) {
if (task.end_date) {
const taskEndDate = momentTime.tz(task.end_date, `${timeZone}`).format("YYYY-MM-DD");
if (moment(taskEndDate).isSame(formatToday)) {
tasksReturn.push(task);
}
}
}
}

if (currentTab === UPCOMING_TAB) {
for (const task of tasks) {
if (task.end_date) {
const taskEndDate = momentTime.tz(task.end_date, `${timeZone}`).format("YYYY-MM-DD");
if (moment(taskEndDate).isAfter(formatToday)) {
tasksReturn.push(task);
}
}
}
}

if (currentTab === OVERDUE_TAB) {
for (const task of tasks) {
if (task.end_date) {
const taskEndDate = momentTime.tz(task.end_date, `${timeZone}`).format("YYYY-MM-DD");
if (moment(taskEndDate).isBefore(formatToday)) {
tasksReturn.push(task);
}
}
}
}
return tasksReturn;
}

public static async createPersonalTask(data: CreatePersonalTaskDto) {
const query = `INSERT INTO personal_todo_list (name, color_code, user_id, index)
VALUES ($1, $2, $3, ((SELECT index FROM personal_todo_list ORDER BY index DESC LIMIT 1) + 1))
RETURNING id, name`;
return await database.query(query, [data.name, data.color_code, data.user_id]);
}

public static async getPersonalTasks(user_id: string|undefined) {
const query = `SELECT ptl.id,
ptl.name,
ptl.created_at,
FALSE AS is_task,
ptl.done,
ptl.updated_at
FROM personal_todo_list ptl
WHERE ptl.user_id = $1
AND done IS FALSE
ORDER BY ptl.updated_at DESC`;
return await database.query(query, [user_id]);
}

public static async getTaskCountsByGroup(tasks: any[], timeZone: string, today_: Date) {
let no_due_date = 0;
let today = 0;
let upcoming = 0;
let overdue = 0;

const total = tasks.length;

const formatToday = moment(today_).format("YYYY-MM-DD");

for (const task of tasks) {
if (!task.end_date) {
no_due_date = no_due_date + 1;
}
if (task.end_date) {
const taskEndDate = momentTime.tz(task.end_date, `${timeZone}`).format("YYYY-MM-DD");
if (moment(taskEndDate).isSame(formatToday)) {
today = today + 1;
}
if (moment(taskEndDate).isAfter(formatToday)) {
upcoming = upcoming + 1;
}
if (moment(taskEndDate).isBefore(formatToday)) {
overdue = overdue + 1;
}
}
}

return {
total,
today,
upcoming,
overdue,
no_due_date
};
}

public static async getTaskGroupBySingleDate(tasks: any, timeZone: string, selectedDate: string) {
const formatSelectedDate = moment(selectedDate).format("YYYY-MM-DD");

const tasksReturn = [];

for (const task of tasks) {
if (task.end_date) {
const taskEndDate = momentTime.tz(task.end_date, `${timeZone}`).format("YYYY-MM-DD");
if (moment(taskEndDate).isSame(formatSelectedDate)) {
tasksReturn.push(task);
}
}
}

return tasksReturn;

}

public static async getTaskCountsResult(groupByClosure: string, teamId: string, userId: string) {
const query = `SELECT COUNT(*) AS total,
COUNT(CASE WHEN t.end_date::DATE = CURRENT_DATE::DATE THEN 1 END) AS today,
COUNT(CASE WHEN t.end_date::DATE > CURRENT_DATE::DATE THEN 1 END) AS upcoming,
COUNT(CASE WHEN t.end_date::DATE < CURRENT_DATE::DATE THEN 1 END) AS overdue,
COUNT(CASE WHEN t.end_date::DATE IS NULL THEN 1 END) AS no_due_date
FROM tasks t
JOIN projects p ON t.project_id = p.id
WHERE t.archived IS FALSE
AND t.status_id NOT IN (SELECT id
FROM task_statuses
WHERE category_id NOT IN (SELECT id
FROM sys_task_status_categories
WHERE is_done IS FALSE))
${groupByClosure}`;

return await database.query(query, [teamId, userId]);
}

public static async getTasksResult(groupByClosure: string, currentTabClosure: string, teamId: string, userId: string) {
const query = `
SELECT t.id,
t.name,
t.project_id,
t.parent_task_id,
t.parent_task_id IS NOT NULL AS is_sub_task,
(SELECT name FROM tasks WHERE id = t.parent_task_id) AS parent_task_name,
t.status_id,
t.start_date,
t.end_date,
t.created_at,
p.team_id,
p.name AS project_name,
p.color_code AS project_color,
(SELECT id FROM task_statuses WHERE id = t.status_id) AS status,
(SELECT color_code
FROM sys_task_status_categories
WHERE id = (SELECT category_id FROM task_statuses WHERE id = t.status_id)) AS status_color,
TRUE AS is_task,
FALSE AS done,
t.updated_at,
(SELECT ARRAY_TO_JSON(ARRAY_AGG(ROW_TO_JSON(r)))
FROM (SELECT task_statuses.id AS id,
task_statuses.name AS name,
(SELECT color_code
FROM sys_task_status_categories
WHERE id = task_statuses.category_id)
FROM task_statuses
WHERE task_statuses.project_id = t.project_id) r) AS project_statuses
FROM tasks t
JOIN projects p ON t.project_id = p.id
WHERE t.archived IS FALSE
AND t.status_id NOT IN (SELECT id
FROM task_statuses
WHERE category_id NOT IN (SELECT id
FROM sys_task_status_categories
WHERE is_done IS FALSE))
${groupByClosure}
ORDER BY t.end_date ASC`;

return await database.query(query, [teamId, userId]);
}

public static async updatePersonalTask(id: string) {
const query = `
UPDATE personal_todo_list
SET done = TRUE
WHERE id = $1
RETURNING id
`;
return await database.query(query, [id]);
}

public static isValidGroup(groupBy: string) {
return groupBy === GROUP_BY_ASSIGNED_TO_ME
|| groupBy === GROUP_BY_ASSIGN_BY_ME;
}

public static isValidView(currentView: string) {
return currentView === ALL_TAB
|| currentView === TODAY_TAB
|| currentView === UPCOMING_TAB
|| currentView === OVERDUE_TAB
|| currentView === NO_DUE_DATE_TAB;
}

}
8 changes: 8 additions & 0 deletions worklenz-backend/src/shared/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,3 +131,11 @@ export const DATE_RANGES = {
LAST_QUARTER: "LAST_QUARTER",
ALL_TIME: "ALL_TIME"
};

export const GROUP_BY_ASSIGNED_TO_ME: string = "0";
export const GROUP_BY_ASSIGN_BY_ME: string = "1";
export const ALL_TAB: string = "All";
export const TODAY_TAB: string = "Today";
export const UPCOMING_TAB: string = "Upcoming";
export const OVERDUE_TAB: string = "Overdue";
export const NO_DUE_DATE_TAB: string = "NoDueDate";