feat: add tagging alerts and sorting on tags
This commit is contained in:
@@ -115,7 +115,7 @@ export async function ctaskRoutes(fastify: FastifyInstance) {
|
|||||||
const { field } = req.params as { field: string };
|
const { field } = req.params as { field: string };
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const uniqueValues = await getUniqueFields(field, "task", req.user);
|
const uniqueValues = await getUniqueFields(field, "ctasks", req.user);
|
||||||
return res.code(200).send(uniqueValues);
|
return res.code(200).send(uniqueValues);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return err;
|
return err;
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ const taskSchema = new mongoose.Schema({
|
|||||||
type: mongoose.Types.ObjectId,
|
type: mongoose.Types.ObjectId,
|
||||||
ref: "user",
|
ref: "user",
|
||||||
},
|
},
|
||||||
|
taggedUsers: Array,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const taskFields = Object.keys(taskSchema.paths).filter(
|
export const taskFields = Object.keys(taskSchema.paths).filter(
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ export async function createTask(
|
|||||||
content: input.note,
|
content: input.note,
|
||||||
},
|
},
|
||||||
task.pid,
|
task.pid,
|
||||||
|
"ctasks",
|
||||||
user
|
user
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -80,6 +81,25 @@ export async function listTasks(
|
|||||||
const sortObj = getSortObject(params, taskFields);
|
const sortObj = getSortObject(params, taskFields);
|
||||||
const filterObj = getFilterObject(params) || [];
|
const filterObj = getFilterObject(params) || [];
|
||||||
|
|
||||||
|
let taggedFilter = [];
|
||||||
|
if (sortObj.taggedUsers) {
|
||||||
|
taggedFilter = [
|
||||||
|
{
|
||||||
|
$addFields: {
|
||||||
|
taggedUsers: {
|
||||||
|
$filter: {
|
||||||
|
input: "$taggedUsers",
|
||||||
|
as: "user",
|
||||||
|
cond: { $eq: ["$$user.userId", user.userId] },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ $match: { "taggedUsers.0": { $exists: true } } },
|
||||||
|
{ $sort: { "taggedUsers.taggedAt": sortObj.taggedUsers } },
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
const taskList = await taskModel.aggregate([
|
const taskList = await taskModel.aggregate([
|
||||||
{
|
{
|
||||||
$match: {
|
$match: {
|
||||||
@@ -90,6 +110,7 @@ export async function listTasks(
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
...taggedFilter,
|
||||||
{
|
{
|
||||||
$lookup: {
|
$lookup: {
|
||||||
from: "users",
|
from: "users",
|
||||||
|
|||||||
@@ -8,9 +8,10 @@ export async function createNoteHandler(
|
|||||||
) {
|
) {
|
||||||
const { resourceId } = req.params as { resourceId: string };
|
const { resourceId } = req.params as { resourceId: string };
|
||||||
const input = req.body as CreateNoteInput;
|
const input = req.body as CreateNoteInput;
|
||||||
|
const resourceType = req.originalUrl.split("/")[3];
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const note = await createNote(input, resourceId, req.user);
|
const note = await createNote(input, resourceId, resourceType, req.user);
|
||||||
return res.code(201).send(note);
|
return res.code(201).send(note);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return err;
|
return err;
|
||||||
|
|||||||
@@ -1,12 +1,24 @@
|
|||||||
|
import { createAlert } from "../alert/alert.service";
|
||||||
import { AuthenticatedUser } from "../auth";
|
import { AuthenticatedUser } from "../auth";
|
||||||
import { generateId } from "../utils/id";
|
import { generateId } from "../utils/id";
|
||||||
|
import { extractExpressions, modelMap } from "../utils/tags";
|
||||||
import { CreateNoteInput, noteModel } from "./note.schema";
|
import { CreateNoteInput, noteModel } from "./note.schema";
|
||||||
|
|
||||||
export async function createNote(
|
export async function createNote(
|
||||||
input: CreateNoteInput,
|
input: CreateNoteInput,
|
||||||
resourceId: string,
|
resourceId: string,
|
||||||
|
resourceType: string,
|
||||||
user: AuthenticatedUser
|
user: AuthenticatedUser
|
||||||
) {
|
) {
|
||||||
|
const userIds = extractExpressions(input.content);
|
||||||
|
|
||||||
|
const taggedUsers = userIds.map((item) => {
|
||||||
|
return {
|
||||||
|
userId: item,
|
||||||
|
taggedAt: new Date(),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
const newNote = await noteModel.create({
|
const newNote = await noteModel.create({
|
||||||
tenantId: user.tenantId,
|
tenantId: user.tenantId,
|
||||||
pid: generateId(),
|
pid: generateId(),
|
||||||
@@ -16,6 +28,56 @@ export async function createNote(
|
|||||||
createdBy: user.userId,
|
createdBy: user.userId,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (
|
||||||
|
userIds.length > 0 &&
|
||||||
|
[
|
||||||
|
"permits",
|
||||||
|
"processed",
|
||||||
|
"rts",
|
||||||
|
"tasks",
|
||||||
|
"ctasks",
|
||||||
|
"payments",
|
||||||
|
"notifications",
|
||||||
|
].includes(resourceType)
|
||||||
|
) {
|
||||||
|
const model = modelMap[resourceType];
|
||||||
|
const obj = await model.findOne({ pid: resourceId });
|
||||||
|
|
||||||
|
console.log(obj.taggedUsers);
|
||||||
|
|
||||||
|
if (!obj.taggedUsers) {
|
||||||
|
await model.updateOne(
|
||||||
|
{ pid: resourceId },
|
||||||
|
{ $set: { taggedUsers: taggedUsers } }
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
for (const user of taggedUsers) {
|
||||||
|
const userIndex = obj.taggedUsers.findIndex(
|
||||||
|
(item) => item.userId == user.userId
|
||||||
|
);
|
||||||
|
console.log(userIndex);
|
||||||
|
if (userIndex != -1) obj.taggedUsers[userIndex].taggedAt = new Date();
|
||||||
|
else obj.taggedUsers.push(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
obj.markModified("taggedUsers");
|
||||||
|
await obj.save();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const id of userIds) {
|
||||||
|
if (id == user.userId) continue;
|
||||||
|
|
||||||
|
await createAlert(
|
||||||
|
user.tenantId,
|
||||||
|
"You are tagged in a note",
|
||||||
|
"user",
|
||||||
|
id,
|
||||||
|
resourceId,
|
||||||
|
resourceType
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return newNote.populate({ path: "createdBy", select: "pid name avatar" });
|
return newNote.populate({ path: "createdBy", select: "pid name avatar" });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ const notificationSchema = new mongoose.Schema({
|
|||||||
type: mongoose.Types.ObjectId,
|
type: mongoose.Types.ObjectId,
|
||||||
ref: "user",
|
ref: "user",
|
||||||
},
|
},
|
||||||
|
taggedUsers: Array,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const notificationFields = Object.keys(notificationSchema.paths).filter(
|
export const notificationFields = Object.keys(notificationSchema.paths).filter(
|
||||||
|
|||||||
@@ -77,6 +77,7 @@ export async function updateNotification(
|
|||||||
content: msg,
|
content: msg,
|
||||||
},
|
},
|
||||||
notifId,
|
notifId,
|
||||||
|
"notifications",
|
||||||
user
|
user
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -84,6 +85,7 @@ export async function updateNotification(
|
|||||||
await createNote(
|
await createNote(
|
||||||
{ content: msg },
|
{ content: msg },
|
||||||
updateNotificationResult.permitId,
|
updateNotificationResult.permitId,
|
||||||
|
"notifications",
|
||||||
user
|
user
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -123,6 +125,25 @@ export async function listNotifications(
|
|||||||
filterObj.push({ client: new mongoose.Types.ObjectId(user.orgId) });
|
filterObj.push({ client: new mongoose.Types.ObjectId(user.orgId) });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let taggedFilter = [];
|
||||||
|
if (sortObj.taggedUsers) {
|
||||||
|
taggedFilter = [
|
||||||
|
{
|
||||||
|
$addFields: {
|
||||||
|
taggedUsers: {
|
||||||
|
$filter: {
|
||||||
|
input: "$taggedUsers",
|
||||||
|
as: "user",
|
||||||
|
cond: { $eq: ["$$user.userId", user.userId] },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ $match: { "taggedUsers.0": { $exists: true } } },
|
||||||
|
{ $sort: { "taggedUsers.taggedAt": sortObj.taggedUsers } },
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
const pipeline: any = [
|
const pipeline: any = [
|
||||||
{
|
{
|
||||||
$match: { $and: [{ tenantId: user.tenantId }, ...filterObj] },
|
$match: { $and: [{ tenantId: user.tenantId }, ...filterObj] },
|
||||||
@@ -140,6 +161,7 @@ export async function listNotifications(
|
|||||||
|
|
||||||
pipeline.push(
|
pipeline.push(
|
||||||
...[
|
...[
|
||||||
|
...taggedFilter,
|
||||||
{
|
{
|
||||||
$lookup: {
|
$lookup: {
|
||||||
from: "users",
|
from: "users",
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ export async function paymentRoutes(fastify: FastifyInstance) {
|
|||||||
const { field } = req.params as { field: string };
|
const { field } = req.params as { field: string };
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const uniqueValues = await getUniqueFields(field, "payment", req.user);
|
const uniqueValues = await getUniqueFields(field, "payments", req.user);
|
||||||
return res.code(200).send(uniqueValues);
|
return res.code(200).send(uniqueValues);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return err;
|
return err;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { z } from 'zod';
|
import { z } from "zod";
|
||||||
import mongoose from 'mongoose';
|
import mongoose from "mongoose";
|
||||||
import { buildJsonSchemas } from 'fastify-zod';
|
import { buildJsonSchemas } from "fastify-zod";
|
||||||
import { pageMetadata, pageQueryParams } from '../pagination';
|
import { pageMetadata, pageQueryParams } from "../pagination";
|
||||||
|
|
||||||
const permitSchema = new mongoose.Schema({
|
const permitSchema = new mongoose.Schema({
|
||||||
tenantId: {
|
tenantId: {
|
||||||
@@ -16,7 +16,7 @@ const permitSchema = new mongoose.Schema({
|
|||||||
county: Object,
|
county: Object,
|
||||||
client: {
|
client: {
|
||||||
type: mongoose.Types.ObjectId,
|
type: mongoose.Types.ObjectId,
|
||||||
ref: 'organization',
|
ref: "organization",
|
||||||
},
|
},
|
||||||
clientData: Object,
|
clientData: Object,
|
||||||
permitDate: Date,
|
permitDate: Date,
|
||||||
@@ -34,7 +34,7 @@ const permitSchema = new mongoose.Schema({
|
|||||||
utility: String,
|
utility: String,
|
||||||
assignedTo: {
|
assignedTo: {
|
||||||
type: mongoose.Types.ObjectId,
|
type: mongoose.Types.ObjectId,
|
||||||
ref: 'user',
|
ref: "user",
|
||||||
},
|
},
|
||||||
link: String,
|
link: String,
|
||||||
address: Object,
|
address: Object,
|
||||||
@@ -52,7 +52,7 @@ const permitSchema = new mongoose.Schema({
|
|||||||
createdAt: Date,
|
createdAt: Date,
|
||||||
createdBy: {
|
createdBy: {
|
||||||
type: mongoose.Types.ObjectId,
|
type: mongoose.Types.ObjectId,
|
||||||
ref: 'user',
|
ref: "user",
|
||||||
},
|
},
|
||||||
newProcessingStatus: Array,
|
newProcessingStatus: Array,
|
||||||
newPayment: Array,
|
newPayment: Array,
|
||||||
@@ -71,12 +71,13 @@ const permitSchema = new mongoose.Schema({
|
|||||||
jobNumber: String,
|
jobNumber: String,
|
||||||
startDate: Date,
|
startDate: Date,
|
||||||
history: Array,
|
history: Array,
|
||||||
|
taggedUsers: Array,
|
||||||
}).index({ tenantId: 1, permitNumber: 1 }, { unique: true });
|
}).index({ tenantId: 1, permitNumber: 1 }, { unique: true });
|
||||||
|
|
||||||
export const permitFields = Object.keys(permitSchema.paths).filter(
|
export const permitFields = Object.keys(permitSchema.paths).filter(
|
||||||
(path) => path !== '__v'
|
(path) => path !== "__v"
|
||||||
);
|
);
|
||||||
export const permitModel = mongoose.model('permit', permitSchema);
|
export const permitModel = mongoose.model("permit", permitSchema);
|
||||||
|
|
||||||
const permitCore = {
|
const permitCore = {
|
||||||
permitNumber: z.string(),
|
permitNumber: z.string(),
|
||||||
@@ -161,5 +162,5 @@ export const { schemas: permitSchemas, $ref: $permit } = buildJsonSchemas(
|
|||||||
updatePermitInput,
|
updatePermitInput,
|
||||||
pageQueryParams,
|
pageQueryParams,
|
||||||
},
|
},
|
||||||
{ $id: 'permit' }
|
{ $id: "permit" }
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -72,10 +72,30 @@ export async function listPermits(
|
|||||||
filterObj.push({ client: new mongoose.Types.ObjectId(user.orgId) });
|
filterObj.push({ client: new mongoose.Types.ObjectId(user.orgId) });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let taggedFilter = [];
|
||||||
|
if (sortObj.taggedUsers) {
|
||||||
|
taggedFilter = [
|
||||||
|
{
|
||||||
|
$addFields: {
|
||||||
|
taggedUsers: {
|
||||||
|
$filter: {
|
||||||
|
input: "$taggedUsers",
|
||||||
|
as: "user",
|
||||||
|
cond: { $eq: ["$$user.userId", user.userId] },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ $match: { "taggedUsers.0": { $exists: true } } },
|
||||||
|
{ $sort: { "taggedUsers.taggedAt": sortObj.taggedUsers } },
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
const permitsList = await permitModel.aggregate([
|
const permitsList = await permitModel.aggregate([
|
||||||
{
|
{
|
||||||
$match: { $and: [{ tenantId: user.tenantId }, ...filterObj] },
|
$match: { $and: [{ tenantId: user.tenantId }, ...filterObj] },
|
||||||
},
|
},
|
||||||
|
...taggedFilter,
|
||||||
{
|
{
|
||||||
$lookup: {
|
$lookup: {
|
||||||
from: "users",
|
from: "users",
|
||||||
@@ -206,6 +226,7 @@ export async function updatePermit(
|
|||||||
content: msg,
|
content: msg,
|
||||||
},
|
},
|
||||||
permitId,
|
permitId,
|
||||||
|
"permits",
|
||||||
user
|
user
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import z from 'zod';
|
import z from "zod";
|
||||||
import mongoose from 'mongoose';
|
import mongoose from "mongoose";
|
||||||
import { pageQueryParams } from '../pagination';
|
import { pageQueryParams } from "../pagination";
|
||||||
import { buildJsonSchemas } from 'fastify-zod';
|
import { buildJsonSchemas } from "fastify-zod";
|
||||||
|
|
||||||
const processedSchema = new mongoose.Schema({
|
const processedSchema = new mongoose.Schema({
|
||||||
tenantId: {
|
tenantId: {
|
||||||
@@ -16,7 +16,7 @@ const processedSchema = new mongoose.Schema({
|
|||||||
county: Object,
|
county: Object,
|
||||||
client: {
|
client: {
|
||||||
type: mongoose.Types.ObjectId,
|
type: mongoose.Types.ObjectId,
|
||||||
ref: 'organization',
|
ref: "organization",
|
||||||
},
|
},
|
||||||
clientData: Object,
|
clientData: Object,
|
||||||
permitDate: Date,
|
permitDate: Date,
|
||||||
@@ -34,7 +34,7 @@ const processedSchema = new mongoose.Schema({
|
|||||||
utility: String,
|
utility: String,
|
||||||
assignedTo: {
|
assignedTo: {
|
||||||
type: mongoose.Types.ObjectId,
|
type: mongoose.Types.ObjectId,
|
||||||
ref: 'user',
|
ref: "user",
|
||||||
},
|
},
|
||||||
link: String,
|
link: String,
|
||||||
address: Object,
|
address: Object,
|
||||||
@@ -52,7 +52,7 @@ const processedSchema = new mongoose.Schema({
|
|||||||
createdAt: Date,
|
createdAt: Date,
|
||||||
createdBy: {
|
createdBy: {
|
||||||
type: mongoose.Types.ObjectId,
|
type: mongoose.Types.ObjectId,
|
||||||
ref: 'user',
|
ref: "user",
|
||||||
},
|
},
|
||||||
newProcessingStatus: Array,
|
newProcessingStatus: Array,
|
||||||
newPayment: Array,
|
newPayment: Array,
|
||||||
@@ -71,16 +71,17 @@ const processedSchema = new mongoose.Schema({
|
|||||||
jobNumber: String,
|
jobNumber: String,
|
||||||
transferDate: Date,
|
transferDate: Date,
|
||||||
history: Array,
|
history: Array,
|
||||||
|
taggedUsers: Array,
|
||||||
}).index({ tenantId: 1, permitNumber: 1 }, { unique: true });
|
}).index({ tenantId: 1, permitNumber: 1 }, { unique: true });
|
||||||
|
|
||||||
export const processedFields = Object.keys(processedSchema.paths).filter(
|
export const processedFields = Object.keys(processedSchema.paths).filter(
|
||||||
(path) => path !== '__v'
|
(path) => path !== "__v"
|
||||||
);
|
);
|
||||||
|
|
||||||
export const processedModel = mongoose.model(
|
export const processedModel = mongoose.model(
|
||||||
'processed',
|
"processed",
|
||||||
processedSchema,
|
processedSchema,
|
||||||
'processed'
|
"processed"
|
||||||
);
|
);
|
||||||
|
|
||||||
const updateProcessedInput = z.object({
|
const updateProcessedInput = z.object({
|
||||||
@@ -100,5 +101,5 @@ export const { schemas: processedSchemas, $ref: $processed } = buildJsonSchemas(
|
|||||||
pageQueryParams,
|
pageQueryParams,
|
||||||
updateProcessedInput,
|
updateProcessedInput,
|
||||||
},
|
},
|
||||||
{ $id: 'processed' }
|
{ $id: "processed" }
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ export async function updateProcessed(
|
|||||||
content: msg,
|
content: msg,
|
||||||
},
|
},
|
||||||
permitId,
|
permitId,
|
||||||
|
"processed",
|
||||||
user
|
user
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -70,6 +71,25 @@ export async function listProcessedPermits(
|
|||||||
filterObj.push({ client: new mongoose.Types.ObjectId(user.orgId) });
|
filterObj.push({ client: new mongoose.Types.ObjectId(user.orgId) });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let taggedFilter = [];
|
||||||
|
if (sortObj.taggedUsers) {
|
||||||
|
taggedFilter = [
|
||||||
|
{
|
||||||
|
$addFields: {
|
||||||
|
taggedUsers: {
|
||||||
|
$filter: {
|
||||||
|
input: "$taggedUsers",
|
||||||
|
as: "user",
|
||||||
|
cond: { $eq: ["$$user.userId", user.userId] },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ $match: { "taggedUsers.0": { $exists: true } } },
|
||||||
|
{ $sort: { "taggedUsers.taggedAt": sortObj.taggedUsers } },
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
const pipeline: any = [
|
const pipeline: any = [
|
||||||
{
|
{
|
||||||
$match: { $and: [{ tenantId: user.tenantId }, ...filterObj] },
|
$match: { $and: [{ tenantId: user.tenantId }, ...filterObj] },
|
||||||
@@ -91,6 +111,7 @@ export async function listProcessedPermits(
|
|||||||
|
|
||||||
pipeline.push(
|
pipeline.push(
|
||||||
...[
|
...[
|
||||||
|
...taggedFilter,
|
||||||
{
|
{
|
||||||
$lookup: {
|
$lookup: {
|
||||||
from: "users",
|
from: "users",
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ const rtsSchema = new mongoose.Schema({
|
|||||||
type: mongoose.Types.ObjectId,
|
type: mongoose.Types.ObjectId,
|
||||||
ref: "user",
|
ref: "user",
|
||||||
},
|
},
|
||||||
|
taggedUsers: Array,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const rtsFields = Object.keys(rtsSchema.paths).filter(
|
export const rtsFields = Object.keys(rtsSchema.paths).filter(
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ export async function createRts(
|
|||||||
...input,
|
...input,
|
||||||
tenantId: user.tenantId,
|
tenantId: user.tenantId,
|
||||||
pid: generateId(),
|
pid: generateId(),
|
||||||
client: defaultClient,
|
client: user.role == "client" ? defaultClient : input.client,
|
||||||
createdAt: new Date(),
|
createdAt: new Date(),
|
||||||
createdBy: user.userId ?? null,
|
createdBy: user.userId ?? null,
|
||||||
});
|
});
|
||||||
@@ -78,10 +78,30 @@ export async function listRts(
|
|||||||
filterObj.push({ client: new mongoose.Types.ObjectId(user.orgId) });
|
filterObj.push({ client: new mongoose.Types.ObjectId(user.orgId) });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let taggedFilter = [];
|
||||||
|
if (sortObj.taggedUsers) {
|
||||||
|
taggedFilter = [
|
||||||
|
{
|
||||||
|
$addFields: {
|
||||||
|
taggedUsers: {
|
||||||
|
$filter: {
|
||||||
|
input: "$taggedUsers",
|
||||||
|
as: "user",
|
||||||
|
cond: { $eq: ["$$user.userId", user.userId] },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ $match: { "taggedUsers.0": { $exists: true } } },
|
||||||
|
{ $sort: { "taggedUsers.taggedAt": sortObj.taggedUsers } },
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
const rtsList = await rtsModel.aggregate([
|
const rtsList = await rtsModel.aggregate([
|
||||||
{
|
{
|
||||||
$match: { $and: [{ tenantId: user.tenantId }, ...filterObj] },
|
$match: { $and: [{ tenantId: user.tenantId }, ...filterObj] },
|
||||||
},
|
},
|
||||||
|
...taggedFilter,
|
||||||
{
|
{
|
||||||
$lookup: {
|
$lookup: {
|
||||||
from: "organizations",
|
from: "organizations",
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ export async function listTaskHandler(req: FastifyRequest, res: FastifyReply) {
|
|||||||
const queryParams = req.query as PageQueryParams;
|
const queryParams = req.query as PageQueryParams;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const taskList = await listTasks(queryParams, req.user.tenantId);
|
const taskList = await listTasks(queryParams, req.user);
|
||||||
return res.code(200).send(taskList);
|
return res.code(200).send(taskList);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return err;
|
return err;
|
||||||
|
|||||||
@@ -128,7 +128,7 @@ export async function taskRoutes(fastify: FastifyInstance) {
|
|||||||
const { field } = req.params as { field: string };
|
const { field } = req.params as { field: string };
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const uniqueValues = await getUniqueFields(field, "task", req.user);
|
const uniqueValues = await getUniqueFields(field, "tasks", req.user);
|
||||||
return res.code(200).send(uniqueValues);
|
return res.code(200).send(uniqueValues);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return err;
|
return err;
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ const taskSchema = new mongoose.Schema({
|
|||||||
type: mongoose.Types.ObjectId,
|
type: mongoose.Types.ObjectId,
|
||||||
ref: "user",
|
ref: "user",
|
||||||
},
|
},
|
||||||
|
taggedUsers: Array,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const taskFields = Object.keys(taskSchema.paths).filter(
|
export const taskFields = Object.keys(taskSchema.paths).filter(
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ export async function createTask(
|
|||||||
content: input.note,
|
content: input.note,
|
||||||
},
|
},
|
||||||
task.pid,
|
task.pid,
|
||||||
|
"tasks",
|
||||||
user
|
user
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -80,16 +81,39 @@ export async function getTask(taskId: string, tenantId: string) {
|
|||||||
.populate({ path: "assignedTo", select: "pid name avatar" });
|
.populate({ path: "assignedTo", select: "pid name avatar" });
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function listTasks(params: PageQueryParams, tenantId: string) {
|
export async function listTasks(
|
||||||
|
params: PageQueryParams,
|
||||||
|
user: AuthenticatedUser
|
||||||
|
) {
|
||||||
const page = params.page || 1;
|
const page = params.page || 1;
|
||||||
const pageSize = params.pageSize || 10;
|
const pageSize = params.pageSize || 10;
|
||||||
const sortObj = getSortObject(params, taskFields);
|
const sortObj = getSortObject(params, taskFields);
|
||||||
const filterObj = getFilterObject(params) || [];
|
const filterObj = getFilterObject(params) || [];
|
||||||
|
|
||||||
|
let taggedFilter = [];
|
||||||
|
if (sortObj.taggedUsers) {
|
||||||
|
taggedFilter = [
|
||||||
|
{
|
||||||
|
$addFields: {
|
||||||
|
taggedUsers: {
|
||||||
|
$filter: {
|
||||||
|
input: "$taggedUsers",
|
||||||
|
as: "user",
|
||||||
|
cond: { $eq: ["$$user.userId", user.userId] },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ $match: { "taggedUsers.0": { $exists: true } } },
|
||||||
|
{ $sort: { "taggedUsers.taggedAt": sortObj.taggedUsers } },
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
const taskList = await taskModel.aggregate([
|
const taskList = await taskModel.aggregate([
|
||||||
{
|
{
|
||||||
$match: { $and: [{ tenantId: tenantId }, ...filterObj] },
|
$match: { $and: [{ tenantId: user.tenantId }, ...filterObj] },
|
||||||
},
|
},
|
||||||
|
...taggedFilter,
|
||||||
{
|
{
|
||||||
$lookup: {
|
$lookup: {
|
||||||
from: "users",
|
from: "users",
|
||||||
|
|||||||
@@ -1,33 +1,18 @@
|
|||||||
import { orgModel } from "./organization/organization.schema";
|
import { orgModel } from "./organization/organization.schema";
|
||||||
import { userModel } from "./user/user.schema";
|
import { userModel } from "./user/user.schema";
|
||||||
import { permitModel } from "./permit/permit.schema";
|
|
||||||
import { processedModel } from "./processed/processed.schema";
|
|
||||||
import { notificationModel } from "./notification/notification.schema";
|
|
||||||
import { rtsModel } from "./rts/rts.schema";
|
|
||||||
import { taskModel } from "./task/task.schema";
|
|
||||||
import { AuthenticatedUser } from "./auth";
|
import { AuthenticatedUser } from "./auth";
|
||||||
import { paymentModel } from "./payments/payment.schema";
|
import { modelMap } from "./utils/tags";
|
||||||
|
|
||||||
type Collection =
|
type Collection =
|
||||||
| "users"
|
| "users"
|
||||||
| "permits"
|
| "permits"
|
||||||
| "organizations"
|
| "orgs"
|
||||||
| "processed"
|
| "processed"
|
||||||
| "notifications"
|
| "notifications"
|
||||||
| "rts"
|
| "rts"
|
||||||
| "task"
|
| "tasks"
|
||||||
| "payment";
|
| "ctasks"
|
||||||
|
| "payments";
|
||||||
const modelMap = {
|
|
||||||
users: userModel,
|
|
||||||
permits: permitModel,
|
|
||||||
organizations: orgModel,
|
|
||||||
processed: processedModel,
|
|
||||||
notifications: notificationModel,
|
|
||||||
rts: rtsModel,
|
|
||||||
task: taskModel,
|
|
||||||
payment: paymentModel,
|
|
||||||
};
|
|
||||||
|
|
||||||
export async function getUniqueFields(
|
export async function getUniqueFields(
|
||||||
field: string,
|
field: string,
|
||||||
|
|||||||
28
src/utils/tags.ts
Normal file
28
src/utils/tags.ts
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
import mongoose from "mongoose";
|
||||||
|
import { userModel } from "../user/user.schema";
|
||||||
|
import { permitModel } from "../permit/permit.schema";
|
||||||
|
import { orgModel } from "../organization/organization.schema";
|
||||||
|
import { processedModel } from "../processed/processed.schema";
|
||||||
|
import { notificationModel } from "../notification/notification.schema";
|
||||||
|
import { rtsModel } from "../rts/rts.schema";
|
||||||
|
import { taskModel } from "../task/task.schema";
|
||||||
|
import { taskModel as ctaskModel } from "../ctask/ctask.schema";
|
||||||
|
import { paymentModel } from "../payments/payment.schema";
|
||||||
|
|
||||||
|
export function extractExpressions(input: string) {
|
||||||
|
return [...input.matchAll(/{{(.*?)}}/g)]
|
||||||
|
.map((match) => match[1].trim())
|
||||||
|
.filter((item) => mongoose.Types.ObjectId.isValid(item));
|
||||||
|
}
|
||||||
|
|
||||||
|
export const modelMap = {
|
||||||
|
users: userModel,
|
||||||
|
permits: permitModel,
|
||||||
|
orgs: orgModel,
|
||||||
|
processed: processedModel,
|
||||||
|
notifications: notificationModel,
|
||||||
|
rts: rtsModel,
|
||||||
|
ctasks: ctaskModel,
|
||||||
|
tasks: taskModel,
|
||||||
|
payments: paymentModel,
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user