Skip to content

Commit a30524d

Browse files
committed
fix incorrect numbers
1 parent c4b2a89 commit a30524d

File tree

3 files changed

+42
-5
lines changed

3 files changed

+42
-5
lines changed

backend/actions/Task/getTasks.js

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ const GetTasksParams = new Archetype({
1414

1515
const ALL_STATUSES = ['pending', 'in_progress', 'succeeded', 'failed', 'cancelled', 'unknown'];
1616

17+
/** Status keys for statusCounts (same shape as getTaskOverview). */
18+
const STATUS_COUNT_KEYS = ['pending', 'succeeded', 'failed', 'cancelled'];
19+
1720
/** Max documents per request to avoid excessive memory and response size. */
1821
const MAX_LIMIT = 2000;
1922

@@ -62,6 +65,8 @@ module.exports = ({ db }) => async function getTasks(params) {
6265
const { Task } = db.models;
6366
const match = buildMatch(params);
6467

68+
const defaultCounts = STATUS_COUNT_KEYS.map(s => ({ k: s, v: 0 }));
69+
6570
const pipeline = [
6671
{ $match: match },
6772
{
@@ -72,14 +77,29 @@ module.exports = ({ db }) => async function getTasks(params) {
7277
{ $limit: limit },
7378
{ $project: TASK_PROJECT_STAGE }
7479
],
75-
count: [{ $count: 'total' }]
80+
count: [{ $count: 'total' }],
81+
statusCounts: [
82+
{ $group: { _id: { $ifNull: ['$status', 'unknown'] }, count: { $sum: 1 } } },
83+
{ $group: { _id: null, counts: { $push: { k: '$_id', v: '$count' } } } },
84+
{
85+
$project: {
86+
statusCounts: {
87+
$arrayToObject: {
88+
$concatArrays: [{ $literal: defaultCounts }, '$counts']
89+
}
90+
}
91+
}
92+
},
93+
{ $replaceRoot: { newRoot: '$statusCounts' } }
94+
]
7695
}
7796
}
7897
];
7998

8099
const [result] = await Task.aggregate(pipeline);
81100
const tasks = result.tasks || [];
82101
const numDocs = (result.count && result.count[0] && result.count[0].total) || 0;
102+
const statusCounts = result.statusCounts?.[0] ?? {};
83103

84-
return { tasks, numDocs };
104+
return { tasks, numDocs, statusCounts };
85105
};

frontend/src/task-by-name/task-by-name.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@ module.exports = app => app.component('task-by-name', {
4343
pageSize: 50,
4444
numDocs: 0,
4545
pageSizeOptions: PAGE_SIZE_OPTIONS,
46-
_loadId: 0
46+
_loadId: 0,
47+
_lastQueryFilters: null
4748
}),
4849
computed: {
4950
taskName() {
@@ -129,11 +130,12 @@ module.exports = app => app.component('task-by-name', {
129130
if (statusFromQuery) params.status = statusFromQuery;
130131
this._lastQueryFilters = `${dateRange}|${statusFromQuery ?? ''}`;
131132
try {
132-
const { tasks, numDocs } = await api.Task.getTasks(params);
133+
const { tasks, numDocs, statusCounts } = await api.Task.getTasks(params);
133134
if (loadId !== this._loadId) return;
134135
this.numDocs = numDocs ?? tasks.length;
135136
this.taskGroup = buildTaskGroup(this.taskName, tasks);
136137
this.taskGroup.totalCount = this.numDocs;
138+
if (statusCounts) this.taskGroup.statusCounts = statusCounts;
137139
this.status = 'loaded';
138140
} catch (err) {
139141
if (loadId !== this._loadId) return;

test/Task.getTasks.test.js

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,13 @@ describe('Task.getTasks()', function() {
3030
await Task.deleteMany();
3131
});
3232

33-
it('returns empty tasks and numDocs 0 when no documents', async function() {
33+
it('returns empty tasks, numDocs 0, and statusCounts when no documents', async function() {
3434
const res = await actions.Task.getTasks({});
3535
assert.strictEqual(Array.isArray(res.tasks), true);
3636
assert.strictEqual(res.tasks.length, 0);
3737
assert.strictEqual(res.numDocs, 0);
38+
assert.strictEqual(typeof res.statusCounts, 'object');
39+
assert.ok(res.statusCounts.pending === 0 || res.statusCounts.pending === undefined);
3840
});
3941

4042
it('returns tasks with projected shape (id, parameters from payload)', async function() {
@@ -200,6 +202,19 @@ describe('Task.getTasks()', function() {
200202
assert.strictEqual(res.numDocs, 6);
201203
});
202204

205+
it('returns statusCounts for matching documents', async function() {
206+
await Task.insertMany([
207+
{ name: 'a', status: 'succeeded', scheduledAt: new Date() },
208+
{ name: 'b', status: 'succeeded', scheduledAt: new Date() },
209+
{ name: 'c', status: 'failed', scheduledAt: new Date() }
210+
]);
211+
const res = await actions.Task.getTasks({});
212+
assert.strictEqual(res.statusCounts.succeeded, 2);
213+
assert.strictEqual(res.statusCounts.failed, 1);
214+
assert.strictEqual(res.statusCounts.pending, 0);
215+
assert.strictEqual(res.statusCounts.cancelled, 0);
216+
});
217+
203218
it('returns numDocs as total matching count when using pagination', async function() {
204219
const base = new Date('2025-01-01T12:00:00Z');
205220
await Task.insertMany([

0 commit comments

Comments
 (0)