Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ uploads
globalConfig.json
coverage
tls
.history
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "hawk.api",
"version": "1.1.28",
"version": "1.1.29",
"main": "index.ts",
"license": "UNLICENSED",
"scripts": {
Expand Down
67 changes: 46 additions & 21 deletions src/models/eventsFactory.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ const { ObjectID } = require('mongodb');
* @property {boolean} [starred] - if true, events with 'starred' mark should be included to the output
* @property {boolean} [resolved] - if true, events with 'resolved' should be included to the output
* @property {boolean} [ignored] - if true, events with 'ignored' mark should be included to the output
* @property {string|number} [dateFrom]
* @property {string|number} [dateTo]
*/

/**
Expand Down Expand Up @@ -149,8 +151,8 @@ class EventsFactory extends Factory {
* @param {Number} limit - events count limitations
* @param {Number} skip - certain number of documents to skip
* @param {'BY_DATE' | 'BY_COUNT'} sort - events sort order
* @param {EventsFilters} filters - marks by which events should be filtered
* @param {String} search - Search query
* @param {EventsFilters} filters - filter object
* @param {String} search - search query
*
* @return {RecentEventSchema[]}
*/
Expand Down Expand Up @@ -231,13 +233,40 @@ class EventsFactory extends Factory {
}
: {};

const matchFilter = filters
? Object.fromEntries(
Object
.entries(filters)
.map(([mark, exists]) => [`event.marks.${mark}`, { $exists: exists } ])
)
: {};
const matchFilter = {
...searchFilter,
};

['starred', 'resolved', 'ignored'].forEach((mark) => {
if (typeof filters[mark] === 'boolean') {
matchFilter[`event.marks.${mark}`] = { $exists: filters[mark] };
}
});

// Filter by date (groupingTimestamp)
if (filters.dateFrom || filters.dateTo) {
matchFilter.groupingTimestamp = {};

if (filters.dateFrom) {
const from = typeof filters.dateFrom === 'string'
? Math.floor(new Date(filters.dateFrom).getTime() / 1000)
: filters.dateFrom;

matchFilter.groupingTimestamp.$gte = from;
}

if (filters.dateTo) {
const to = typeof filters.dateTo === 'string'
? Math.floor(new Date(filters.dateTo).getTime() / 1000)
: filters.dateTo;

matchFilter.groupingTimestamp.$lte = to;
}

if (Object.keys(matchFilter.groupingTimestamp).length === 0) {
delete matchFilter.groupingTimestamp;
}
}

pipeline.push(
{
Expand All @@ -252,10 +281,7 @@ class EventsFactory extends Factory {
$unwind: '$event',
},
{
$match: {
...matchFilter,
...searchFilter,
},
$match: matchFilter,
},
{ $skip: skip },
{ $limit: limit },
Expand All @@ -272,17 +298,16 @@ class EventsFactory extends Factory {
);

const cursor = this.getCollection(this.TYPES.DAILY_EVENTS).aggregate(pipeline);

const result = (await cursor.toArray()).shift();

/**
* aggregation can return empty array so that
* result can be undefined
*
* for that we check result existence
*
* extra field `projectId` needs to satisfy GraphQL query
*/
* aggregation can return empty array so that
* result can be undefined
*
* for that we check result existence
*
* extra field `projectId` needs to satisfy GraphQL query
*/
if (result && result.events) {
result.events.forEach(event => {
event.projectId = this.projectId;
Expand Down
25 changes: 21 additions & 4 deletions src/typeDefs/project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,29 @@ Events filters input type
"""
input EventsFiltersInput {
"""
If True, includes events with resolved mark to the output
If true, includes events with resolved mark
"""
resolved: Boolean

"""
If True, includes events with starred mark to the output
If true, includes events with starred mark
"""
starred: Boolean

"""
If True, includes events with ignored mark to the output
If true, includes events with ignored mark
"""
ignored: Boolean

"""
Include events with groupingTimestamp >= dateFrom (ISO or timestamp in seconds)
"""
dateFrom: Timestamp

"""
Include events with groupingTimestamp <= dateTo (ISO or timestamp in seconds)
"""
dateTo: Timestamp
}

"""
Expand Down Expand Up @@ -122,12 +134,17 @@ type Project {
"Events sort order"
sort: EventsSortOrder = lastRepetitionTime

"Event marks by which events should be sorted"
"""
Filters for narrowing down the event results:
- By marks (e.g., starred, resolved)
- By date range (dateFrom / dateTo)
"""
filters: EventsFiltersInput

"Search query"
search: String
): RecentEvents

"""
Return events that occurred after a certain timestamp
"""
Expand Down