Initial commit: Angular frontend and Expressjs backend

This commit is contained in:
chamikaJ
2024-05-17 09:32:30 +05:30
parent eb0a0d77d6
commit 298ca6beeb
3548 changed files with 193558 additions and 3 deletions

View File

@@ -0,0 +1,163 @@
import { IWorkLenzRequest } from "../interfaces/worklenz-request";
import { IWorkLenzResponse } from "../interfaces/worklenz-response";
import db from "../config/db";
import { humanFileSize, log_error, smallId } from "../shared/utils";
import { ServerResponse } from "../models/server-response";
import {
createPresignedUrlWithClient,
deleteObject,
getAvatarKey,
getKey,
getRootDir,
uploadBase64,
uploadBuffer
} from "../shared/s3";
import WorklenzControllerBase from "./worklenz-controller-base";
import HandleExceptions from "../decorators/handle-exceptions";
const {S3_URL} = process.env;
if (!S3_URL) {
log_error("Invalid S3_URL. Please check .env file.");
}
export default class AttachmentController extends WorklenzControllerBase {
@HandleExceptions()
public static async createTaskAttachment(req: IWorkLenzRequest, res: IWorkLenzResponse): Promise<IWorkLenzResponse> {
const { file, file_name, task_id, project_id, size, type } = req.body;
const q = `
INSERT INTO task_attachments (name, task_id, team_id, project_id, uploaded_by, size, type)
VALUES ($1, $2, $3, $4, $5, $6, $7)
RETURNING id, name, size, type, created_at, CONCAT($8::TEXT, '/', team_id, '/', project_id, '/', id, '.', type) AS url;
`;
const result = await db.query(q, [
file_name,
task_id,
req.user?.team_id,
project_id,
req.user?.id,
size,
type,
`${S3_URL}/${getRootDir()}`
]);
const [data] = result.rows;
const s3Url = await uploadBase64(file, getKey(req.user?.team_id as string, project_id, data.id, data.type));
if (!data?.id || !s3Url)
return res.status(200).send(new ServerResponse(false, null, "Attachment upload failed"));
data.size = humanFileSize(data.size);
return res.status(200).send(new ServerResponse(true, data));
}
@HandleExceptions()
public static async createAvatarAttachment(req: IWorkLenzRequest, res: IWorkLenzResponse): Promise<IWorkLenzResponse> {
const { type, buffer } = req.body;
const s3Url = await uploadBuffer(buffer as Buffer, type, getAvatarKey(req.user?.id as string, type));
if (!s3Url)
return res.status(200).send(new ServerResponse(false, null, "Avatar upload failed"));
const q = "UPDATE users SET avatar_url = $2, updated_at = CURRENT_TIMESTAMP WHERE id = $1 RETURNING avatar_url;";
const result = await db.query(q, [req.user?.id, `${s3Url}?v=${smallId(4)}`]);
const [data] = result.rows;
if (!data)
return res.status(200).send(new ServerResponse(false, null, "Avatar upload failed"));
return res.status(200).send(new ServerResponse(true, { url: data.avatar_url }, "Avatar updated."));
}
@HandleExceptions()
public static async get(req: IWorkLenzRequest, res: IWorkLenzResponse): Promise<IWorkLenzResponse> {
const q = `
SELECT id,
name,
size,
CONCAT($2::TEXT, '/', team_id, '/', project_id, '/', id, '.', type) AS url,
type,
created_at
FROM task_attachments
WHERE task_id = $1;
`;
const result = await db.query(q, [req.params.id, `${S3_URL}/${getRootDir()}`]);
for (const item of result.rows)
item.size = humanFileSize(item.size);
return res.status(200).send(new ServerResponse(true, result.rows));
}
@HandleExceptions()
public static async getByProjectId(req: IWorkLenzRequest, res: IWorkLenzResponse): Promise<IWorkLenzResponse> {
const { size, offset } = this.toPaginationOptions(req.query, "name");
const q = `
SELECT ROW_TO_JSON(rec) AS attachments
FROM (SELECT COUNT(*) AS total,
(SELECT COALESCE(ARRAY_TO_JSON(ARRAY_AGG(ROW_TO_JSON(t))), '[]'::JSON)
FROM (SELECT task_attachments.id,
task_attachments.name,
CONCAT((SELECT key FROM projects WHERE id = task_attachments.project_id), '-',
(SELECT task_no FROM tasks WHERE id = task_attachments.task_id)) AS task_key,
size,
CONCAT($2::TEXT, '/', task_attachments.team_id, '/', task_attachments.project_id, '/',task_attachments.id,'.',type) AS url,
task_attachments.type,
task_attachments.created_at,
t.name AS task_name,
(SELECT name FROM users WHERE id = task_attachments.uploaded_by) AS uploader_name
FROM task_attachments
LEFT JOIN tasks t ON task_attachments.task_id = t.id
WHERE task_attachments.project_id = $1
ORDER BY created_at DESC
LIMIT $3 OFFSET $4)t) AS data
FROM task_attachments
LEFT JOIN tasks t ON task_attachments.task_id = t.id
WHERE task_attachments.project_id = $1) rec;
`;
const result = await db.query(q, [req.params.id, `${S3_URL}/${getRootDir()}`, size, offset]);
const [data] = result.rows;
for (const item of data?.attachments.data || [])
item.size = humanFileSize(item.size);
return res.status(200).send(new ServerResponse(true, data?.attachments || this.paginatedDatasetDefaultStruct));
}
@HandleExceptions()
public static async deleteById(req: IWorkLenzRequest, res: IWorkLenzResponse): Promise<IWorkLenzResponse> {
const q = `DELETE
FROM task_attachments
WHERE id = $1
RETURNING CONCAT($2::TEXT, '/', team_id, '/', project_id, '/', id, '.', type) AS key;`;
const result = await db.query(q, [req.params.id, getRootDir()]);
const [data] = result.rows;
if (data?.key)
void deleteObject(data.key);
return res.status(200).send(new ServerResponse(true, result.rows));
}
@HandleExceptions()
public static async download(req: IWorkLenzRequest, res: IWorkLenzResponse): Promise<IWorkLenzResponse> {
const q = `SELECT CONCAT($2::TEXT, '/', team_id, '/', project_id, '/', id, '.', type) AS key
FROM task_attachments
WHERE id = $1;`;
const result = await db.query(q, [req.query.id, getRootDir()]);
const [data] = result.rows;
if (data?.key) {
const url = await createPresignedUrlWithClient(data.key, req.query.file as string);
return res.status(200).send(new ServerResponse(true, url));
}
return res.status(200).send(new ServerResponse(true, null));
}
}