Add filters.

This commit is contained in:
Cameron Redmore 2025-04-26 11:26:38 +01:00
parent a136b717bf
commit 8ad2c6ef53
4 changed files with 207 additions and 23 deletions

View file

@ -10,10 +10,62 @@ const MsgReader = reader.default;
const prisma = new PrismaClient(); // Instantiate Prisma Client
const router = express.Router();
// Helper function to fetch distinct values
const getDistinctValues = async(field, res) =>
{
try
{
const values = await prisma.mantisIssue.findMany({
distinct: [field],
select: {
[field]: true,
},
where: { // Exclude null values if necessary
NOT: {
[field]: ''
}
},
orderBy: {
[field]: 'asc',
},
});
res.json(values.map(item => item[field]));
}
catch (error)
{
console.error(`Error fetching distinct ${field} values:`, error.message);
res.status(500).json({ error: `Failed to fetch distinct ${field} values` });
}
};
// GET /mantis/filters/statuses - Fetch unique status values
router.get('/filters/statuses', async(req, res) =>
{
await getDistinctValues('status', res);
});
// GET /mantis/filters/priorities - Fetch unique priority values
router.get('/filters/priorities', async(req, res) =>
{
await getDistinctValues('priority', res);
});
// GET /mantis/filters/severities - Fetch unique severity values
router.get('/filters/severities', async(req, res) =>
{
await getDistinctValues('severity', res);
});
// GET /mantis/filters/reporters - Fetch unique reporter usernames
router.get('/filters/reporters', async(req, res) =>
{
await getDistinctValues('reporterUsername', res);
});
// GET /mantis - Fetch multiple Mantis issues with filtering and pagination
router.get('/', async(req, res) =>
{
const { page = 1, limit = 10, status, priority, severity, reporterUsername, search } = req.query;
const { page = 1, limit = 10, status, priority, severity, reporterUsername, search, sortBy = 'updatedAt', sortOrder = 'desc' } = req.query; // Add sortBy and sortOrder
const pageNum = parseInt(page, 10);
const limitNum = parseInt(limit, 10);
@ -29,6 +81,7 @@ router.get('/', async(req, res) =>
where.OR = [
{ title: { contains: search, mode: 'insensitive' } },
{ description: { contains: search, mode: 'insensitive' } },
{ comments: { some: { comment: { contains: search, mode: 'insensitive' } } } }, // Search in comments
];
// If the search term is a number, treat it as an ID
@ -39,6 +92,16 @@ router.get('/', async(req, res) =>
}
}
// Validate sortOrder
const validSortOrder = ['asc', 'desc'].includes(sortOrder) ? sortOrder : 'desc';
// Define allowed sort fields to prevent arbitrary sorting
const allowedSortFields = ['id', 'title', 'status', 'priority', 'severity', 'reporterUsername', 'createdAt', 'updatedAt'];
const validSortBy = allowedSortFields.includes(sortBy) ? sortBy : 'updatedAt';
const orderBy = {};
orderBy[validSortBy] = validSortOrder;
try
{
let [issues, totalCount] = await prisma.$transaction([
@ -46,9 +109,7 @@ router.get('/', async(req, res) =>
where,
skip,
take: limitNum,
orderBy: {
updatedAt: 'desc', // Default sort order
},
orderBy: orderBy, // Use dynamic orderBy
// You might want to include related data like comments count later
// include: { _count: { select: { comments: true } } }
}),
@ -83,9 +144,7 @@ router.get('/', async(req, res) =>
where,
skip,
take: limitNum,
orderBy: {
updatedAt: 'desc', // Default sort order
},
orderBy: orderBy, // Use dynamic orderBy here as well
});
if (issues.length === 0)