Skip to content

Commit 7f2c49e

Browse files
Merge branch 'develop' into feature/search-improvement
2 parents ebb7353 + 3858c5c commit 7f2c49e

File tree

6 files changed

+97
-33
lines changed

6 files changed

+97
-33
lines changed

docs/swagger.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1743,6 +1743,11 @@ paths:
17431743
description: Filter by timeline template id
17441744
required: false
17451745
type: string
1746+
- name: isDefault
1747+
in: query
1748+
description: Filter by is default flag
1749+
required: false
1750+
type: boolean
17461751
responses:
17471752
'200':
17481753
description: OK
@@ -2587,6 +2592,9 @@ definitions:
25872592
timelineTemplateId:
25882593
type: string
25892594
format: UUID
2595+
isDefault:
2596+
type: boolean
2597+
default: false
25902598
required:
25912599
- typeId
25922600
- trackId

src/common/helper.js

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -87,24 +87,24 @@ function getPageLink (req, page) {
8787
*/
8888
function setResHeaders (req, res, result) {
8989
const totalPages = Math.ceil(result.total / result.perPage)
90-
if (result.page > 1) {
91-
res.set('X-Prev-Page', result.page - 1)
90+
if (parseInt(result.page, 10) > 1) {
91+
res.set('X-Prev-Page', parseInt(result.page, 10) - 1)
9292
}
93-
if (result.page < totalPages) {
94-
res.set('X-Next-Page', result.page + 1)
93+
if (parseInt(result.page, 10) < totalPages) {
94+
res.set('X-Next-Page', parseInt(result.page, 10) + 1)
9595
}
96-
res.set('X-Page', result.page)
96+
res.set('X-Page', parseInt(result.page, 10))
9797
res.set('X-Per-Page', result.perPage)
9898
res.set('X-Total', result.total)
9999
res.set('X-Total-Pages', totalPages)
100100
// set Link header
101101
if (totalPages > 0) {
102102
let link = `<${getPageLink(req, 1)}>; rel="first", <${getPageLink(req, totalPages)}>; rel="last"`
103-
if (result.page > 1) {
104-
link += `, <${getPageLink(req, result.page - 1)}>; rel="prev"`
103+
if (parseInt(result.page, 10) > 1) {
104+
link += `, <${getPageLink(req, parseInt(result.page, 10) - 1)}>; rel="prev"`
105105
}
106-
if (result.page < totalPages) {
107-
link += `, <${getPageLink(req, result.page + 1)}>; rel="next"`
106+
if (parseInt(result.page, 10) < totalPages) {
107+
link += `, <${getPageLink(req, parseInt(result.page, 10) + 1)}>; rel="next"`
108108
}
109109
res.set('Link', link)
110110
}

src/models/ChallengeTimelineTemplate.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ const schema = new Schema({
2323
timelineTemplateId: {
2424
type: String,
2525
required: true
26+
},
27+
isDefault: {
28+
type: Boolean,
29+
required: false
2630
}
2731
},
2832
{

src/scripts/seed/ChallengeTimelineTemplate.json

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,96 +3,112 @@
33
"id": "6a29fccb-81ab-49f8-905d-0db0e840881a",
44
"trackId": "5fa04185-041f-49a6-bfd1-fe82533cd6c8",
55
"typeId": "927abff4-7af9-4145-8ba1-577c16e64e2e",
6-
"timelineTemplateId": "7ebf1c69-f62f-4d3a-bdfb-fe9ddb56861c"
6+
"timelineTemplateId": "7ebf1c69-f62f-4d3a-bdfb-fe9ddb56861c",
7+
"isDefault": false
78
},
89
{
910
"id": "edd528d7-b2d6-48e4-80ab-cfccc3cfb6cb",
1011
"trackId": "5fa04185-041f-49a6-bfd1-fe82533cd6c8",
1112
"typeId": "927abff4-7af9-4145-8ba1-577c16e64e2e",
12-
"timelineTemplateId": "d4201ca4-8437-4d63-9957-3f7708184b07"
13+
"timelineTemplateId": "d4201ca4-8437-4d63-9957-3f7708184b07",
14+
"isDefault": true
1315
},
1416
{
1517
"id": "4a59472b-0743-4dae-9739-1f5b327e1255",
1618
"trackId": "5fa04185-041f-49a6-bfd1-fe82533cd6c8",
1719
"typeId": "927abff4-7af9-4145-8ba1-577c16e64e2e",
18-
"timelineTemplateId": "2d0807fa-ece1-4328-a260-76f5f6b559e0"
20+
"timelineTemplateId": "2d0807fa-ece1-4328-a260-76f5f6b559e0",
21+
"isDefault": false
1922
},
2023
{
2124
"id": "fccd933a-34c3-497f-850e-00d6f499e703",
2225
"trackId": "5fa04185-041f-49a6-bfd1-fe82533cd6c8",
2326
"typeId": "dc876fa4-ef2d-4eee-b701-b555fcc6544c",
24-
"timelineTemplateId": "0a0fed34-cb5a-47f5-b0cb-6e2ee7de8dcb"
27+
"timelineTemplateId": "0a0fed34-cb5a-47f5-b0cb-6e2ee7de8dcb",
28+
"isDefault": true
2529
},
2630
{
2731
"id": "26de5868-f405-46d6-bf82-f3966b2a382d",
2832
"trackId": "5fa04185-041f-49a6-bfd1-fe82533cd6c8",
2933
"typeId": "ecd58c69-238f-43a4-a4bb-d172719b9f31",
30-
"timelineTemplateId": "53a307ce-b4b3-4d6f-b9a1-3741a58f77e6"
34+
"timelineTemplateId": "53a307ce-b4b3-4d6f-b9a1-3741a58f77e6",
35+
"isDefault": true
3136
},
3237
{
3338
"id": "4df06ca4-367f-4768-93b4-94ba18625983",
3439
"trackId": "9b6fc876-f4d9-4ccb-9dfd-419247628825",
3540
"typeId": "927abff4-7af9-4145-8ba1-577c16e64e2e",
36-
"timelineTemplateId": "7ebf1c69-f62f-4d3a-bdfb-fe9ddb56861c"
41+
"timelineTemplateId": "7ebf1c69-f62f-4d3a-bdfb-fe9ddb56861c",
42+
"isDefault": true
3743
},
3844
{
3945
"id": "140b24d5-5259-4449-bc1f-3780f3b01555",
4046
"trackId": "9b6fc876-f4d9-4ccb-9dfd-419247628825",
4147
"typeId": "dc876fa4-ef2d-4eee-b701-b555fcc6544c",
42-
"timelineTemplateId": "0a0fed34-cb5a-47f5-b0cb-6e2ee7de8dcb"
48+
"timelineTemplateId": "0a0fed34-cb5a-47f5-b0cb-6e2ee7de8dcb",
49+
"isDefault": true
4350
},
4451
{
4552
"id": "3cd4e42f-141f-4118-950c-fb815569fb34",
4653
"trackId": "9b6fc876-f4d9-4ccb-9dfd-419247628825",
4754
"typeId": "ecd58c69-238f-43a4-a4bb-d172719b9f31",
48-
"timelineTemplateId": "53a307ce-b4b3-4d6f-b9a1-3741a58f77e6"
55+
"timelineTemplateId": "53a307ce-b4b3-4d6f-b9a1-3741a58f77e6",
56+
"isDefault": true
4957
},
5058
{
5159
"id": "87ab69d5-09ec-45ef-b3d1-f6f6f1fdf2f3",
5260
"trackId": "c0f5d461-8219-4c14-878a-c3a3f356466d",
5361
"typeId": "927abff4-7af9-4145-8ba1-577c16e64e2e",
54-
"timelineTemplateId": "7ebf1c69-f62f-4d3a-bdfb-fe9ddb56861c"
62+
"timelineTemplateId": "7ebf1c69-f62f-4d3a-bdfb-fe9ddb56861c",
63+
"isDefault": true
5564
},
5665
{
5766
"id": "9e4da450-d29a-44e6-aa80-26d9d5798637",
5867
"trackId": "c0f5d461-8219-4c14-878a-c3a3f356466d",
5968
"typeId": "927abff4-7af9-4145-8ba1-577c16e64e2e",
60-
"timelineTemplateId": "6969125a-a12f-4b89-8de6-e66b0056f36b"
69+
"timelineTemplateId": "6969125a-a12f-4b89-8de6-e66b0056f36b",
70+
"isDefault": false
6171
},
6272
{
6373
"id": "92207659-e2e3-4578-85d5-02a36f384907",
6474
"trackId": "c0f5d461-8219-4c14-878a-c3a3f356466d",
6575
"typeId": "dc876fa4-ef2d-4eee-b701-b555fcc6544c",
66-
"timelineTemplateId": "0a0fed34-cb5a-47f5-b0cb-6e2ee7de8dcb"
76+
"timelineTemplateId": "0a0fed34-cb5a-47f5-b0cb-6e2ee7de8dcb",
77+
"isDefault": true
6778
},
6879
{
6980
"id": "ab235f79-6606-41b2-afaf-4956824fcbcc",
7081
"trackId": "c0f5d461-8219-4c14-878a-c3a3f356466d",
7182
"typeId": "ecd58c69-238f-43a4-a4bb-d172719b9f31",
72-
"timelineTemplateId": "53a307ce-b4b3-4d6f-b9a1-3741a58f77e6"
83+
"timelineTemplateId": "53a307ce-b4b3-4d6f-b9a1-3741a58f77e6",
84+
"isDefault": true
7385
},
7486
{
7587
"id": "1be20f5f-9356-49cf-b3df-a7be8099b5d9",
7688
"trackId": "36e6a8d0-7e1e-4608-a673-64279d99c115",
7789
"typeId": "927abff4-7af9-4145-8ba1-577c16e64e2e",
78-
"timelineTemplateId": "7ebf1c69-f62f-4d3a-bdfb-fe9ddb56861c"
90+
"timelineTemplateId": "7ebf1c69-f62f-4d3a-bdfb-fe9ddb56861c",
91+
"isDefault": true
7992
},
8093
{
8194
"id": "71b5e844-9847-43b0-aa66-9bcc620704b3",
8295
"trackId": "36e6a8d0-7e1e-4608-a673-64279d99c115",
8396
"typeId": "927abff4-7af9-4145-8ba1-577c16e64e2e",
84-
"timelineTemplateId": "f1bcb2c7-3ee4-4fb5-8d0b-efe52c015963"
97+
"timelineTemplateId": "f1bcb2c7-3ee4-4fb5-8d0b-efe52c015963",
98+
"isDefault": false
8599
},
86100
{
87101
"id": "00660d04-1e84-467b-a450-281cb4ec4137",
88102
"trackId": "36e6a8d0-7e1e-4608-a673-64279d99c115",
89103
"typeId": "dc876fa4-ef2d-4eee-b701-b555fcc6544c",
90-
"timelineTemplateId": "0a0fed34-cb5a-47f5-b0cb-6e2ee7de8dcb"
104+
"timelineTemplateId": "0a0fed34-cb5a-47f5-b0cb-6e2ee7de8dcb",
105+
"isDefault": true
91106
},
92107
{
93108
"id": "68ae6341-f571-4be1-9d86-44773c294538",
94109
"trackId": "36e6a8d0-7e1e-4608-a673-64279d99c115",
95110
"typeId": "ecd58c69-238f-43a4-a4bb-d172719b9f31",
96-
"timelineTemplateId": "53a307ce-b4b3-4d6f-b9a1-3741a58f77e6"
111+
"timelineTemplateId": "53a307ce-b4b3-4d6f-b9a1-3741a58f77e6",
112+
"isDefault": true
97113
}
98114
]

src/services/ChallengeService.js

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,14 @@ async function searchChallenges (currentUser, criteria) {
175175
// Parse and use metadata key
176176
if (!_.isUndefined(criteria[key])) {
177177
const metaKey = key.split('meta.')[1]
178-
boolQuery.push({ match_phrase: { [`metadata.${metaKey}`]: criteria[key] } })
178+
boolQuery.push({
179+
bool: {
180+
must: [
181+
{ match_phrase: { 'metadata.name': metaKey } },
182+
{ match_phrase: { 'metadata.value': _.toString(criteria[key]) } }
183+
]
184+
}
185+
})
179186
}
180187
}
181188
})
@@ -807,7 +814,8 @@ async function createChallenge (currentUser, challenge, userToken) {
807814
if (challenge.typeId && challenge.trackId) {
808815
const [challengeTimelineTemplate] = await ChallengeTimelineTemplateService.searchChallengeTimelineTemplates({
809816
typeId: challenge.typeId,
810-
trackId: challenge.trackId
817+
trackId: challenge.trackId,
818+
isDefault: true
811819
})
812820
if (!challengeTimelineTemplate) {
813821
throw new errors.BadRequestError(`The selected trackId ${challenge.trackId} and typeId: ${challenge.typeId} does not have a default timeline template. Please provide a timelineTemplateId`)

src/services/ChallengeTimelineTemplateService.js

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,38 @@ const constants = require('../../app-constants')
1616
* @returns {Array} the search result
1717
*/
1818
async function searchChallengeTimelineTemplates (criteria) {
19-
const list = await helper.scan('ChallengeTimelineTemplate')
20-
const records = _.filter(list, e => (!criteria.typeId || criteria.typeId === e.typeId) &&
21-
(!criteria.timelineTemplateId || criteria.timelineTemplateId === e.timelineTemplateId))
19+
let records = await helper.scan('ChallengeTimelineTemplate')
20+
if (criteria.typeId) records = _.filter(records, e => (criteria.typeId === e.typeId))
21+
if (criteria.trackId) records = _.filter(records, e => (criteria.trackId === e.trackId))
22+
if (criteria.timelineTemplateId) records = _.filter(records, e => (criteria.timelineTemplateId === e.timelineTemplateId))
23+
if (!_.isUndefined(criteria.isDefault)) records = _.filter(records, e => (e.isDefault === (criteria.isDefault === 'true')))
2224
return records
2325
}
2426

2527
searchChallengeTimelineTemplates.schema = {
2628
criteria: Joi.object().keys({
2729
typeId: Joi.optionalId(),
2830
trackId: Joi.optionalId(),
29-
timelineTemplateId: Joi.optionalId()
31+
timelineTemplateId: Joi.optionalId(),
32+
isDefault: Joi.boolean()
3033
})
3134
}
3235

36+
/**
37+
* Unset existing default timeline template in order to create a new one
38+
* @param {String} typeId the type ID
39+
* @param {String} trackId the track ID
40+
*/
41+
async function unsetDefaultTimelineTemplate (typeId, trackId) {
42+
const records = await searchChallengeTimelineTemplates({ typeId, trackId, isDefault: true })
43+
if (records.length === 0) {
44+
return
45+
}
46+
for (const record of records) {
47+
await fullyUpdateChallengeTimelineTemplate(record.id, { ...record, isDefault: false })
48+
}
49+
}
50+
3351
/**
3452
* Create challenge type timeline template.
3553
* @param {Object} data the data to create challenge type timeline template
@@ -46,6 +64,10 @@ async function createChallengeTimelineTemplate (data) {
4664
await helper.getById('ChallengeTrack', data.trackId)
4765
await helper.getById('TimelineTemplate', data.timelineTemplateId)
4866

67+
if (data.isDefault) {
68+
await unsetDefaultTimelineTemplate(data.typeId, data.trackId)
69+
}
70+
4971
const ret = await helper.create('ChallengeTimelineTemplate', _.assign({ id: uuid() }, data))
5072
// post bus event
5173
await helper.postBusEvent(constants.Topics.ChallengeTimelineTemplateCreated, ret)
@@ -56,7 +78,8 @@ createChallengeTimelineTemplate.schema = {
5678
data: Joi.object().keys({
5779
typeId: Joi.id(),
5880
trackId: Joi.id(),
59-
timelineTemplateId: Joi.id()
81+
timelineTemplateId: Joi.id(),
82+
isDefault: Joi.boolean().default(false).required()
6083
}).required()
6184
}
6285

@@ -84,7 +107,8 @@ async function fullyUpdateChallengeTimelineTemplate (challengeTimelineTemplateId
84107

85108
if (record.typeId === data.typeId &&
86109
record.trackId === data.trackId &&
87-
record.timelineTemplateId === data.timelineTemplateId) {
110+
record.timelineTemplateId === data.timelineTemplateId &&
111+
record.isDefault === data.isDefault) {
88112
// no change
89113
return record
90114
}
@@ -99,6 +123,10 @@ async function fullyUpdateChallengeTimelineTemplate (challengeTimelineTemplateId
99123
await helper.getById('ChallengeTrack', data.trackId)
100124
await helper.getById('TimelineTemplate', data.timelineTemplateId)
101125

126+
if (data.isDefault) {
127+
await unsetDefaultTimelineTemplate(data.typeId, data.trackId)
128+
}
129+
102130
const ret = await helper.update(record, data)
103131
// post bus event
104132
await helper.postBusEvent(constants.Topics.ChallengeTimelineTemplateUpdated, ret)

0 commit comments

Comments
 (0)