Skip to content

Commit 2fb4389

Browse files
committed
update projects controller with pagination
1 parent 6fd573d commit 2fb4389

1 file changed

Lines changed: 26 additions & 11 deletions

File tree

server/controllers/project.controller/getProjectsForUser.js

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,36 +10,51 @@ import { toApi as toApiProjectObject } from '../../domain-objects/Project';
1010
const createCoreHandler = (mapProjectsToResponse) => async (req, res) => {
1111
try {
1212
const { username } = req.params;
13-
const { page, limit } = req.query;
13+
const { page, limit, sortField, sortDir, q } = req.query;
1414

1515
if (!username) {
16-
res.status(422).json({ message: 'Username not provided' });
17-
return;
16+
return res.status(422).json({ message: 'Username not provided' });
1817
}
1918

2019
const user = await User.findByUsername(username);
2120

2221
if (!user) {
23-
res
22+
return res
2423
.status(404)
2524
.json({ message: 'User with that username does not exist.' });
26-
return;
2725
}
2826

2927
const canViewPrivate = req.user && req.user._id.equals(user._id);
30-
3128
const filter = { user: user._id };
29+
3230
if (!canViewPrivate) {
3331
filter.visibility = { $ne: 'Private' };
3432
}
3533

34+
if (q && q.trim()) {
35+
const term = q.trim();
36+
const escaped = term.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
37+
38+
filter.name = { $regex: escaped, $options: 'i' };
39+
}
40+
3641
const usePagination = page !== undefined && limit !== undefined;
3742

3843
const parsedPage = Math.max(parseInt(page, 10) || 1, 1);
3944
const parsedLimit = Math.min(Math.max(parseInt(limit, 10) || 10, 1), 100);
45+
const dir = sortDir === 'desc' ? -1 : 1;
46+
const allowedSortFields = new Set([
47+
'name',
48+
'createdAt',
49+
'updatedAt',
50+
'visibility'
51+
]);
52+
const safeSortField = allowedSortFields.has(sortField)
53+
? sortField
54+
: 'updatedAt';
4055

4156
const query = Project.find(filter)
42-
.sort('-createdAt')
57+
.sort({ [safeSortField]: dir, _id: dir })
4358
.select('name files id createdAt updatedAt visibility');
4459

4560
if (usePagination) {
@@ -56,18 +71,18 @@ const createCoreHandler = (mapProjectsToResponse) => async (req, res) => {
5671
projects: mapProjectsToResponse(projects),
5772
...(usePagination && {
5873
metadata: {
59-
currentPage: parsedPage || 1,
60-
totalPages: Math.ceil(totalProjects / parsedLimit) || 1,
74+
page: parsedPage,
75+
totalPages: Math.max(Math.ceil(totalProjects / parsedLimit), 1),
6176
totalProjects,
6277
limit: parsedLimit,
6378
hasPagination: true
6479
}
6580
})
6681
};
6782

68-
res.json(response);
83+
return res.json(response);
6984
} catch (error) {
70-
res.status(500).json({ message: 'Error fetching projects' });
85+
return res.status(500).json({ message: 'Error fetching projects' });
7186
}
7287
};
7388

0 commit comments

Comments
 (0)