@outliant/sunrise-utils 1.1.7 → 1.1.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +20 -0
- package/helpers/isEmailValid.js +9 -0
- package/helpers/projectFilter/criticalPathFilter.js +5 -3
- package/helpers/projectFilter/projectFieldFilter.js +3 -2
- package/helpers/projectFilter/projectFilter.js +4 -3
- package/helpers/projectFilter/regionFilter.js +4 -2
- package/helpers/projectFilter/tagFilter.js +5 -3
- package/helpers/sortScript.js +34 -1
- package/helpers/splitString.js +6 -0
- package/helpers/taskFilter/criticalPathFilter.js +3 -1
- package/helpers/taskFilter/daysToComplete.js +220 -0
- package/helpers/taskFilter/index.js +22 -1
- package/helpers/taskFilter/onHoldFilter.js +3 -1
- package/helpers/taskFilter/ownerFilter.js +3 -1
- package/helpers/taskFilter/regionFilter.js +3 -1
- package/helpers/taskFilter/statusFilter.js +3 -1
- package/helpers/taskFilter/taskFieldFilter.js +3 -1
- package/lib/taskPipeline.js +55 -24
- package/lib/usersPipeline.js +34 -2
- package/package.json +1 -1
- package/test/helpers/taskFilter/daysToComplete.spec.js +160 -0
- package/test/lib/taskPipeline.spec.js +69 -56
package/CHANGELOG.md
CHANGED
|
@@ -4,9 +4,29 @@ All notable changes to this project will be documented in this file. Dates are d
|
|
|
4
4
|
|
|
5
5
|
Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
6
6
|
|
|
7
|
+
#### [1.1.9](https://github.com/outliant/sunrise-utils/compare/1.1.8...1.1.9)
|
|
8
|
+
|
|
9
|
+
- Task/task new columns #85ztbmnkf [`#14`](https://github.com/outliant/sunrise-utils/pull/14)
|
|
10
|
+
- chore: add filter for days to complete [`f2fdf97`](https://github.com/outliant/sunrise-utils/commit/f2fdf977c6b5c5f22c17b3fffb7a6a2024a3c38c)
|
|
11
|
+
- chore: add test [`847deb3`](https://github.com/outliant/sunrise-utils/commit/847deb3d2eebba343b865bb69cb6dc642096160d)
|
|
12
|
+
- chore: fix test [`ad49d34`](https://github.com/outliant/sunrise-utils/commit/ad49d3451ff523426672528f42f65f77f2d05c5f)
|
|
13
|
+
|
|
14
|
+
#### [1.1.8](https://github.com/outliant/sunrise-utils/compare/1.1.7...1.1.8)
|
|
15
|
+
|
|
16
|
+
> 29 September 2023
|
|
17
|
+
|
|
18
|
+
- chore: use split string helper [`#13`](https://github.com/outliant/sunrise-utils/pull/13)
|
|
19
|
+
- chore: update logic for user pipeline [`#12`](https://github.com/outliant/sunrise-utils/pull/12)
|
|
20
|
+
- chore(release): 1.1.8 [`aa38c1a`](https://github.com/outliant/sunrise-utils/commit/aa38c1abac2d22fddb329fc18e071881b15837b3)
|
|
21
|
+
- chore: update users pipeline [`c0de2e6`](https://github.com/outliant/sunrise-utils/commit/c0de2e6bbacbeb1b8b96597473679f7f2424880e)
|
|
22
|
+
- chore: fix unit test [`84b880d`](https://github.com/outliant/sunrise-utils/commit/84b880d39497aa03257869702ecd0aa9f05b1d77)
|
|
23
|
+
|
|
7
24
|
#### [1.1.7](https://github.com/outliant/sunrise-utils/compare/1.1.6...1.1.7)
|
|
8
25
|
|
|
26
|
+
> 26 September 2023
|
|
27
|
+
|
|
9
28
|
- chore: update users pipeline [`#11`](https://github.com/outliant/sunrise-utils/pull/11)
|
|
29
|
+
- chore(release): 1.1.7 [`056a962`](https://github.com/outliant/sunrise-utils/commit/056a962aedcd0f9ee8e71cca2d1003db01a69057)
|
|
10
30
|
- chore: remove map [`6c6972b`](https://github.com/outliant/sunrise-utils/commit/6c6972b89bd60cb44bb48613ad206b785e1f1771)
|
|
11
31
|
- chore: use buildProjectFilter [`0cae6ce`](https://github.com/outliant/sunrise-utils/commit/0cae6ce4ca13dc56b98e9b98a6c6cff9881824c2)
|
|
12
32
|
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
const isEmailValid = (email) => {
|
|
2
|
+
// The regular expression to match a valid email address.
|
|
3
|
+
const regex = /^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z]+$/;
|
|
4
|
+
|
|
5
|
+
// Return true if the string matches the regular expression, false otherwise.
|
|
6
|
+
return regex.test(email);
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
module.exports = isEmailValid;
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
const splitString = require('../splitString');
|
|
2
|
+
|
|
1
3
|
module.exports = (filter) => {
|
|
2
4
|
switch (filter.condition) {
|
|
3
5
|
case 'is_equal':
|
|
@@ -21,7 +23,7 @@ module.exports.isEqual = (filter) => {
|
|
|
21
23
|
let value = filter.value;
|
|
22
24
|
|
|
23
25
|
if (typeof value === 'string') {
|
|
24
|
-
value = value
|
|
26
|
+
value = splitString(value);
|
|
25
27
|
}
|
|
26
28
|
|
|
27
29
|
return {
|
|
@@ -43,7 +45,7 @@ module.exports.containsAny = (filter) => {
|
|
|
43
45
|
let value = filter.value;
|
|
44
46
|
|
|
45
47
|
if (typeof value === 'string') {
|
|
46
|
-
value = value
|
|
48
|
+
value = splitString(value);
|
|
47
49
|
}
|
|
48
50
|
|
|
49
51
|
return {
|
|
@@ -65,7 +67,7 @@ module.exports.containsNone = (filter) => {
|
|
|
65
67
|
let value = filter.value;
|
|
66
68
|
|
|
67
69
|
if (typeof value === 'string') {
|
|
68
|
-
value = value
|
|
70
|
+
value = splitString(value);
|
|
69
71
|
}
|
|
70
72
|
|
|
71
73
|
return {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
const moment = require('moment');
|
|
2
2
|
const { escapeElasticQuery } = require('../es');
|
|
3
|
+
const splitString = require('../splitString');
|
|
3
4
|
|
|
4
5
|
function getContainsMappingValue(filter) {
|
|
5
6
|
if (['text', 'textarea'].includes(filter.field_type)) {
|
|
@@ -162,7 +163,7 @@ module.exports.isAnyOf = (filter) => {
|
|
|
162
163
|
let value = filter.value;
|
|
163
164
|
|
|
164
165
|
if (typeof value === 'string') {
|
|
165
|
-
value = value
|
|
166
|
+
value = splitString(value);
|
|
166
167
|
}
|
|
167
168
|
|
|
168
169
|
if (filter.field_id) {
|
|
@@ -356,7 +357,7 @@ module.exports.isEqual = (filter) => {
|
|
|
356
357
|
let value = filter.value;
|
|
357
358
|
|
|
358
359
|
if (typeof value === 'string') {
|
|
359
|
-
value = value
|
|
360
|
+
value = splitString(value);
|
|
360
361
|
}
|
|
361
362
|
|
|
362
363
|
mappingValue = {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
const moment = require('moment');
|
|
2
2
|
const { escapeElasticQuery } = require('../es');
|
|
3
|
+
const splitString = require('../splitString');
|
|
3
4
|
|
|
4
5
|
module.exports = (filter) => {
|
|
5
6
|
switch (filter.condition) {
|
|
@@ -127,7 +128,7 @@ module.exports.isEqual = (filter) => {
|
|
|
127
128
|
|
|
128
129
|
if (filter.field_type === 'checkbox') {
|
|
129
130
|
const value = typeof filter.value === 'string'
|
|
130
|
-
? filter.value
|
|
131
|
+
? splitString(filter.value)
|
|
131
132
|
: filter.value;
|
|
132
133
|
|
|
133
134
|
const should = [];
|
|
@@ -160,7 +161,7 @@ module.exports.isEqual = (filter) => {
|
|
|
160
161
|
|
|
161
162
|
return {
|
|
162
163
|
term: {
|
|
163
|
-
|
|
164
|
+
[filter.type]: {
|
|
164
165
|
value: filter.value
|
|
165
166
|
}
|
|
166
167
|
}
|
|
@@ -383,7 +384,7 @@ module.exports.isNotEqual = (filter) => {
|
|
|
383
384
|
|
|
384
385
|
if (filter.field_type === 'checkbox') {
|
|
385
386
|
const value = typeof filter.value === 'string'
|
|
386
|
-
? filter.value
|
|
387
|
+
? splitString(filter.value)
|
|
387
388
|
: filter.value;
|
|
388
389
|
|
|
389
390
|
const should = [];
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
const splitString = require('../splitString');
|
|
2
|
+
|
|
1
3
|
module.exports = (filter) => {
|
|
2
4
|
switch (filter.condition) {
|
|
3
5
|
case 'contains_any':
|
|
@@ -15,7 +17,7 @@ module.exports.containsAny = (filter) => {
|
|
|
15
17
|
let value = filter.value;
|
|
16
18
|
|
|
17
19
|
if (typeof value === 'string') {
|
|
18
|
-
value = value
|
|
20
|
+
value = splitString(value);
|
|
19
21
|
}
|
|
20
22
|
|
|
21
23
|
return {
|
|
@@ -37,7 +39,7 @@ module.exports.containsNone = (filter) => {
|
|
|
37
39
|
let value = filter.value;
|
|
38
40
|
|
|
39
41
|
if (typeof value === 'string') {
|
|
40
|
-
value = value
|
|
42
|
+
value = splitString(value);
|
|
41
43
|
}
|
|
42
44
|
|
|
43
45
|
return {
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
const splitString = require('../splitString');
|
|
2
|
+
|
|
1
3
|
module.exports = (filter) => {
|
|
2
4
|
switch (filter.condition) {
|
|
3
5
|
case 'contains_any':
|
|
@@ -18,7 +20,7 @@ module.exports.containsAny = (filter) => {
|
|
|
18
20
|
let value = filter.value;
|
|
19
21
|
|
|
20
22
|
if (typeof value === 'string') {
|
|
21
|
-
value = value
|
|
23
|
+
value = splitString(value);
|
|
22
24
|
}
|
|
23
25
|
|
|
24
26
|
return {
|
|
@@ -40,7 +42,7 @@ module.exports.containsNone = (filter) => {
|
|
|
40
42
|
let value = filter.value;
|
|
41
43
|
|
|
42
44
|
if (typeof value === 'string') {
|
|
43
|
-
value = value
|
|
45
|
+
value = splitString(value);
|
|
44
46
|
}
|
|
45
47
|
|
|
46
48
|
return {
|
|
@@ -62,7 +64,7 @@ module.exports.containsAll = (filter) => {
|
|
|
62
64
|
let value = filter.value;
|
|
63
65
|
|
|
64
66
|
if (typeof value === 'string') {
|
|
65
|
-
value = value
|
|
67
|
+
value = splitString(value);
|
|
66
68
|
}
|
|
67
69
|
|
|
68
70
|
return {
|
package/helpers/sortScript.js
CHANGED
|
@@ -210,7 +210,7 @@ module.exports.criticalPathStage = (order) => {
|
|
|
210
210
|
if (stageIndex != null) {
|
|
211
211
|
return stageIndex;
|
|
212
212
|
}
|
|
213
|
-
|
|
213
|
+
|
|
214
214
|
return 9999999;
|
|
215
215
|
} catch (Exception err) {
|
|
216
216
|
return 9999999;
|
|
@@ -318,6 +318,39 @@ module.exports.projectFieldNumeric = (order, value) => {
|
|
|
318
318
|
};
|
|
319
319
|
};
|
|
320
320
|
|
|
321
|
+
module.exports.daysToComplete = (order) => {
|
|
322
|
+
return {
|
|
323
|
+
_script: {
|
|
324
|
+
type: 'number',
|
|
325
|
+
script: {
|
|
326
|
+
lang: 'painless',
|
|
327
|
+
source: `
|
|
328
|
+
try {
|
|
329
|
+
def isEmptyReadyAt = doc.containsKey('ready_at') && doc['ready_at'].empty;
|
|
330
|
+
def isEmptyCompletedAt = doc.containsKey('completed_at') && doc['completed_at'].empty;
|
|
331
|
+
|
|
332
|
+
if (isEmptyReadyAt || isEmptyCompletedAt) {
|
|
333
|
+
return -999999;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
def readyAt = doc['ready_at'].value.toInstant().toEpochMilli();
|
|
337
|
+
def completedAt = doc['completed_at'].value.toInstant().toEpochMilli();
|
|
338
|
+
|
|
339
|
+
if (readyAt == null || completedAt == null) {
|
|
340
|
+
return -999999;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
return completedAt - readyAt;
|
|
344
|
+
} catch (Exception err) {
|
|
345
|
+
return -999999;
|
|
346
|
+
}
|
|
347
|
+
`
|
|
348
|
+
},
|
|
349
|
+
order
|
|
350
|
+
}
|
|
351
|
+
};
|
|
352
|
+
};
|
|
353
|
+
|
|
321
354
|
module.exports.projectFieldText = (order, value) => {
|
|
322
355
|
return {
|
|
323
356
|
_script: {
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
const splitString = require('../splitString');
|
|
2
|
+
|
|
1
3
|
module.exports = (filter) => {
|
|
2
4
|
switch (filter.condition) {
|
|
3
5
|
case 'is_empty':
|
|
@@ -106,7 +108,7 @@ module.exports.isAnyOf = (filter) => {
|
|
|
106
108
|
let value = filter.value;
|
|
107
109
|
|
|
108
110
|
if (typeof value === 'string') {
|
|
109
|
-
value = value
|
|
111
|
+
value = splitString(value);
|
|
110
112
|
}
|
|
111
113
|
|
|
112
114
|
return {
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
const _ = require('lodash');
|
|
2
|
+
|
|
3
|
+
const commonOperatorTemplate = (conditionCallback) => {
|
|
4
|
+
const condition = conditionCallback({
|
|
5
|
+
daysToComplete: 'daysToComplete',
|
|
6
|
+
value: 'params.value',
|
|
7
|
+
secondValue: 'params.second_value'
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
return `
|
|
11
|
+
try {
|
|
12
|
+
def isEmptyReadyAt = doc.containsKey('ready_at') && doc['ready_at'].empty;
|
|
13
|
+
def isEmptyCompletedAt = doc.containsKey('completed_at') && doc['completed_at'].empty;
|
|
14
|
+
|
|
15
|
+
if (isEmptyReadyAt || isEmptyCompletedAt) {
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
def readyAt = doc['ready_at'].value.toInstant().toEpochMilli();
|
|
20
|
+
def completedAt = doc['completed_at'].value.toInstant().toEpochMilli();
|
|
21
|
+
|
|
22
|
+
if (readyAt == null || completedAt == null) {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
def daysToComplete = (completedAt - readyAt) / (1000 * 3600 * 24);
|
|
27
|
+
|
|
28
|
+
return ${condition}
|
|
29
|
+
} catch (Exception err) {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
`;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
module.exports = (filter) => {
|
|
36
|
+
filter.value = _.parseInt(filter.value);
|
|
37
|
+
filter.second_value = _.parseInt(filter.second_value);
|
|
38
|
+
|
|
39
|
+
switch (filter.condition) {
|
|
40
|
+
case 'is_equal':
|
|
41
|
+
return module.exports.isEqual(filter);
|
|
42
|
+
case 'not_equal':
|
|
43
|
+
return module.exports.isNotEqual(filter);
|
|
44
|
+
case 'less_than':
|
|
45
|
+
return module.exports.lessThan(filter);
|
|
46
|
+
case 'less_than_or_equal':
|
|
47
|
+
return module.exports.lessThanOrEqual(filter);
|
|
48
|
+
case 'greater_than':
|
|
49
|
+
return module.exports.greaterThan(filter);
|
|
50
|
+
case 'greater_than_or_equal':
|
|
51
|
+
return module.exports.greaterThanOrEqual(filter);
|
|
52
|
+
case 'between':
|
|
53
|
+
return module.exports.between(filter);
|
|
54
|
+
case 'is_empty':
|
|
55
|
+
return module.exports.isEmpty(filter);
|
|
56
|
+
case 'is_not_empty':
|
|
57
|
+
return module.exports.isNotEmpty(filter);
|
|
58
|
+
default:
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
module.exports.isEqual = (filter) => {
|
|
64
|
+
return {
|
|
65
|
+
script: {
|
|
66
|
+
script: {
|
|
67
|
+
source: commonOperatorTemplate(({ daysToComplete, value }) => {
|
|
68
|
+
return `${daysToComplete} == ${value}`;
|
|
69
|
+
}),
|
|
70
|
+
lang: "painless",
|
|
71
|
+
params: {
|
|
72
|
+
value: filter.value,
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
module.exports.isNotEqual = (filter) => {
|
|
81
|
+
return {
|
|
82
|
+
script: {
|
|
83
|
+
script: {
|
|
84
|
+
source: commonOperatorTemplate(({ daysToComplete, value }) => {
|
|
85
|
+
return `${daysToComplete} != ${value}`;
|
|
86
|
+
}),
|
|
87
|
+
lang: "painless",
|
|
88
|
+
params: {
|
|
89
|
+
value: filter.value,
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
module.exports.greaterThan = (filter) => {
|
|
98
|
+
return {
|
|
99
|
+
script: {
|
|
100
|
+
script: {
|
|
101
|
+
source: commonOperatorTemplate(({ daysToComplete, value }) => {
|
|
102
|
+
return `${daysToComplete} > ${value}`;
|
|
103
|
+
}),
|
|
104
|
+
lang: "painless",
|
|
105
|
+
params: {
|
|
106
|
+
value: filter.value,
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
module.exports.greaterThanOrEqual = (filter) => {
|
|
114
|
+
return {
|
|
115
|
+
script: {
|
|
116
|
+
script: {
|
|
117
|
+
source: commonOperatorTemplate(({ daysToComplete, value }) => {
|
|
118
|
+
return `${daysToComplete} >= ${value}`;
|
|
119
|
+
}),
|
|
120
|
+
lang: "painless",
|
|
121
|
+
params: {
|
|
122
|
+
value: filter.value,
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
module.exports.lessThan = (filter) => {
|
|
130
|
+
return {
|
|
131
|
+
script: {
|
|
132
|
+
script: {
|
|
133
|
+
source: commonOperatorTemplate(({ daysToComplete, value }) => {
|
|
134
|
+
return `${daysToComplete} < ${value}`;
|
|
135
|
+
}),
|
|
136
|
+
lang: "painless",
|
|
137
|
+
params: {
|
|
138
|
+
value: filter.value,
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
module.exports.lessThanOrEqual = (filter) => {
|
|
146
|
+
return {
|
|
147
|
+
script: {
|
|
148
|
+
script: {
|
|
149
|
+
source: commonOperatorTemplate(({ daysToComplete, value }) => {
|
|
150
|
+
return `${daysToComplete} <= ${value}`;
|
|
151
|
+
}),
|
|
152
|
+
lang: "painless",
|
|
153
|
+
params: {
|
|
154
|
+
value: filter.value,
|
|
155
|
+
second_value: filter.second_value
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
module.exports.between = (filter) => {
|
|
163
|
+
return {
|
|
164
|
+
script: {
|
|
165
|
+
script: {
|
|
166
|
+
source: commonOperatorTemplate(({ daysToComplete, value, secondValue }) => {
|
|
167
|
+
return `
|
|
168
|
+
${daysToComplete} >= ${value} &&
|
|
169
|
+
${daysToComplete} <= ${secondValue}
|
|
170
|
+
`;
|
|
171
|
+
}),
|
|
172
|
+
lang: "painless",
|
|
173
|
+
params: {
|
|
174
|
+
value: filter.value,
|
|
175
|
+
second_value: filter.second_value
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
};
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
module.exports.isEmpty = () => {
|
|
183
|
+
return {
|
|
184
|
+
script: {
|
|
185
|
+
script: {
|
|
186
|
+
source: `
|
|
187
|
+
try {
|
|
188
|
+
def isEmptyReadyAt = doc.containsKey('ready_at') && doc['ready_at'].empty;
|
|
189
|
+
def isEmptyCompletedAt = doc.containsKey('completed_at') && doc['completed_at'].empty;
|
|
190
|
+
|
|
191
|
+
return isEmptyReadyAt || isEmptyCompletedAt;
|
|
192
|
+
} catch (Exception err) {
|
|
193
|
+
return false;
|
|
194
|
+
}
|
|
195
|
+
`,
|
|
196
|
+
lang: "painless"
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
};
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
module.exports.isNotEmpty = () => {
|
|
203
|
+
return {
|
|
204
|
+
script: {
|
|
205
|
+
script: {
|
|
206
|
+
source: `
|
|
207
|
+
try {
|
|
208
|
+
def isEmptyReadyAt = doc.containsKey('ready_at') && doc['ready_at'].empty;
|
|
209
|
+
def isEmptyCompletedAt = doc.containsKey('completed_at') && doc['completed_at'].empty;
|
|
210
|
+
|
|
211
|
+
return !isEmptyReadyAt && !isEmptyCompletedAt;
|
|
212
|
+
} catch (Exception err) {
|
|
213
|
+
return false;
|
|
214
|
+
}
|
|
215
|
+
`,
|
|
216
|
+
lang: "painless"
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
};
|
|
220
|
+
};
|
|
@@ -5,9 +5,11 @@ const buildRegionFilter = require('./regionFilter');
|
|
|
5
5
|
const buildTaskFieldFilter = require('./taskFieldFilter');
|
|
6
6
|
const buildCriticalPathFilter = require('./criticalPathFilter');
|
|
7
7
|
const buildOnHoldFilter = require('./onHoldFilter');
|
|
8
|
+
const buildDaysToCompleteFilter = require('./daysToComplete');
|
|
8
9
|
const buildAgeColorFilter = require('./buildAgeColorFilter');
|
|
9
10
|
const buildProjectFieldFilter = require('../projectFilter/projectFieldFilter');
|
|
10
11
|
const { PROJECT_BANNERS } = require('../../constants');
|
|
12
|
+
const splitString = require('../splitString');
|
|
11
13
|
|
|
12
14
|
module.exports.taskStatusOptions = [
|
|
13
15
|
{
|
|
@@ -65,6 +67,18 @@ module.exports.defaultCustomColumns = [
|
|
|
65
67
|
type: 'ready_at',
|
|
66
68
|
field_type: 'date'
|
|
67
69
|
},
|
|
70
|
+
{
|
|
71
|
+
name: 'Days to Complete',
|
|
72
|
+
value: 'days_to_complete',
|
|
73
|
+
type: 'days_to_complete',
|
|
74
|
+
field_type: 'number'
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
name: 'Pending Date',
|
|
78
|
+
value: 'pending_date',
|
|
79
|
+
type: 'pending_date',
|
|
80
|
+
field_type: 'date'
|
|
81
|
+
},
|
|
68
82
|
{
|
|
69
83
|
name: 'Project ID',
|
|
70
84
|
value: 'project_id',
|
|
@@ -221,17 +235,24 @@ module.exports.buildTaskPipelineFilter = (filter) => {
|
|
|
221
235
|
return buildCriticalPathFilter(filter);
|
|
222
236
|
case 'on_hold':
|
|
223
237
|
return buildOnHoldFilter(filter);
|
|
238
|
+
case 'days_to_complete':
|
|
239
|
+
return buildDaysToCompleteFilter(filter);
|
|
224
240
|
// Always expected as is_equal condition
|
|
225
241
|
case 'path_age':
|
|
226
242
|
return buildPathAgeFilter(filter);
|
|
227
243
|
case 'task_age':
|
|
228
244
|
return buildAgeColorFilter(filter);
|
|
245
|
+
case 'pending_date':
|
|
246
|
+
return buildTaskFieldFilter({
|
|
247
|
+
...filter,
|
|
248
|
+
type: 'ready_at'
|
|
249
|
+
});
|
|
229
250
|
// Always expected as is_equal condition with array of task template ids
|
|
230
251
|
case 'task_templates':
|
|
231
252
|
let value = filter.value;
|
|
232
253
|
|
|
233
254
|
if (typeof value === 'string') {
|
|
234
|
-
value = value
|
|
255
|
+
value = splitString(value);
|
|
235
256
|
}
|
|
236
257
|
|
|
237
258
|
return {
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
const splitString = require('../splitString');
|
|
2
|
+
|
|
1
3
|
module.exports = (filter) => {
|
|
2
4
|
switch (filter.condition) {
|
|
3
5
|
case 'is_empty':
|
|
@@ -79,7 +81,7 @@ module.exports.isAnyOf = (filter) => {
|
|
|
79
81
|
let value = filter.value;
|
|
80
82
|
|
|
81
83
|
if (typeof value === 'string') {
|
|
82
|
-
value = value
|
|
84
|
+
value = splitString(value);
|
|
83
85
|
}
|
|
84
86
|
|
|
85
87
|
const should = [];
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
const { validate: isUuid } = require('uuid');
|
|
2
2
|
|
|
3
|
+
const splitString = require('../splitString');
|
|
4
|
+
|
|
3
5
|
module.exports = (filter) => {
|
|
4
6
|
switch (filter.condition) {
|
|
5
7
|
case 'is_empty':
|
|
@@ -101,7 +103,7 @@ module.exports.isAnyOf = (filter) => {
|
|
|
101
103
|
let value = filter.value;
|
|
102
104
|
|
|
103
105
|
if (typeof value === 'string') {
|
|
104
|
-
value = value
|
|
106
|
+
value = splitString(value);
|
|
105
107
|
}
|
|
106
108
|
|
|
107
109
|
const should = [];
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
const splitString = require('../splitString');
|
|
2
|
+
|
|
1
3
|
module.exports = (filter) => {
|
|
2
4
|
switch (filter.condition) {
|
|
3
5
|
case 'is_empty':
|
|
@@ -45,7 +47,7 @@ module.exports.isEqual = (filter) => {
|
|
|
45
47
|
let value = filter.value;
|
|
46
48
|
|
|
47
49
|
if (typeof value === 'string') {
|
|
48
|
-
value = value
|
|
50
|
+
value = splitString(value);
|
|
49
51
|
}
|
|
50
52
|
|
|
51
53
|
return {
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
const splitString = require('../splitString');
|
|
2
|
+
|
|
1
3
|
module.exports = (filter) => {
|
|
2
4
|
switch (filter.condition) {
|
|
3
5
|
case 'is_empty':
|
|
@@ -142,7 +144,7 @@ module.exports.isAnyOf = (filter) => {
|
|
|
142
144
|
let value = filter.value;
|
|
143
145
|
|
|
144
146
|
if (typeof value === 'string') {
|
|
145
|
-
value = value
|
|
147
|
+
value = splitString(value);
|
|
146
148
|
}
|
|
147
149
|
|
|
148
150
|
const should = [];
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
const moment = require('moment');
|
|
2
2
|
|
|
3
|
+
const splitString = require('../splitString');
|
|
4
|
+
|
|
3
5
|
module.exports = (filter) => {
|
|
4
6
|
switch (filter.condition) {
|
|
5
7
|
case 'contains_any':
|
|
@@ -97,7 +99,7 @@ module.exports.isAnyOf = (filter) => {
|
|
|
97
99
|
let value = filter.value;
|
|
98
100
|
|
|
99
101
|
if (typeof value === 'string') {
|
|
100
|
-
value = value
|
|
102
|
+
value = splitString(value);
|
|
101
103
|
}
|
|
102
104
|
|
|
103
105
|
return {
|
package/lib/taskPipeline.js
CHANGED
|
@@ -98,30 +98,61 @@ class TaskPipeline {
|
|
|
98
98
|
} else {
|
|
99
99
|
sortByMultiple.forEach((s, i) => {
|
|
100
100
|
const sort = sortMultiple[i] || 'desc';
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
101
|
+
|
|
102
|
+
switch (true) {
|
|
103
|
+
case s === 'region':
|
|
104
|
+
taskPipelinesSort.push(sortScript.region(sort));
|
|
105
|
+
break;
|
|
106
|
+
|
|
107
|
+
case s === 'owner' :
|
|
108
|
+
case s === 'completed_by' :
|
|
109
|
+
taskPipelinesSort.push(sortScript.owner(sort));
|
|
110
|
+
break;
|
|
111
|
+
|
|
112
|
+
case s === 'status':
|
|
113
|
+
taskPipelinesSort.push(sortScript.status(sort));
|
|
114
|
+
break;
|
|
115
|
+
|
|
116
|
+
case s === 'critical_path_stage':
|
|
117
|
+
taskPipelinesSort.push(sortScript.criticalPathStage(sort));
|
|
118
|
+
break;
|
|
119
|
+
|
|
120
|
+
case s === 'project_id':
|
|
121
|
+
taskPipelinesSort.push(sortScript.projectId(sort));
|
|
122
|
+
break;
|
|
123
|
+
|
|
124
|
+
case s === 'ready_at':
|
|
125
|
+
taskPipelinesSort.push(sortScript.readyAt(sort));
|
|
126
|
+
break;
|
|
127
|
+
|
|
128
|
+
case s === 'pending_date':
|
|
129
|
+
taskPipelinesSort.push({
|
|
130
|
+
ready_at: { order: sort, missing: '_last' }
|
|
131
|
+
});
|
|
132
|
+
break;
|
|
133
|
+
|
|
134
|
+
case s === 'days_to_complete':
|
|
135
|
+
taskPipelinesSort.push(sortScript.daysToComplete(sort));
|
|
136
|
+
break;
|
|
137
|
+
|
|
138
|
+
case s === 'was_marked_incomplete':
|
|
139
|
+
taskPipelinesSort.push(sortScript.wasMarkedIncomplete(sort));
|
|
140
|
+
break;
|
|
141
|
+
|
|
142
|
+
case s === 'last_comment_date':
|
|
143
|
+
taskPipelinesSort.push(sortScript.lastCommentDate(sort));
|
|
144
|
+
break;
|
|
145
|
+
|
|
146
|
+
case isUuid(s):
|
|
147
|
+
taskPipelinesSort.push(sortScript.projectFieldNumeric(sort, s));
|
|
148
|
+
taskPipelinesSort.push(sortScript.projectFieldText(sort, s));
|
|
149
|
+
break;
|
|
150
|
+
|
|
151
|
+
default:
|
|
152
|
+
taskPipelinesSort.push({
|
|
153
|
+
[s]: { order: sort, missing: '_last' }
|
|
154
|
+
});
|
|
155
|
+
break;
|
|
125
156
|
}
|
|
126
157
|
});
|
|
127
158
|
}
|
package/lib/usersPipeline.js
CHANGED
|
@@ -1,12 +1,44 @@
|
|
|
1
1
|
const sortScript = require('../helpers/users/sortScript');
|
|
2
2
|
const buildProjectFilter = require('../helpers/projectFilter/projectFilter');
|
|
3
|
+
const isEmailValid = require('../helpers/isEmailValid');
|
|
3
4
|
|
|
4
5
|
// customer filters
|
|
5
6
|
const buildStatusFilter = require('../helpers/users/filters/status');
|
|
6
7
|
|
|
7
8
|
class UsersPipeline {
|
|
8
|
-
buildFiltersQuery(
|
|
9
|
-
|
|
9
|
+
buildFiltersQuery (
|
|
10
|
+
organizationId,
|
|
11
|
+
filters,
|
|
12
|
+
search
|
|
13
|
+
) {
|
|
14
|
+
const mustQuery = [
|
|
15
|
+
{
|
|
16
|
+
term: {
|
|
17
|
+
organizationId: {
|
|
18
|
+
value: organizationId
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
];
|
|
23
|
+
|
|
24
|
+
if (search) {
|
|
25
|
+
if (isEmailValid(search)) {
|
|
26
|
+
mustQuery.push({
|
|
27
|
+
match: {
|
|
28
|
+
email: search
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
} else {
|
|
32
|
+
mustQuery.push(
|
|
33
|
+
{
|
|
34
|
+
query_string: {
|
|
35
|
+
fields: ['name.raw', 'email.raw'],
|
|
36
|
+
query: `*${search}*`,
|
|
37
|
+
default_operator: 'AND'
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
}
|
|
10
42
|
|
|
11
43
|
for (const filter of filters) {
|
|
12
44
|
switch (filter.type) {
|
package/package.json
CHANGED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/* eslint-env node, mocha */
|
|
4
|
+
const { expect } = require('chai');
|
|
5
|
+
|
|
6
|
+
// To test
|
|
7
|
+
const daysToComplete = require('../../../helpers/taskFilter/daysToComplete');
|
|
8
|
+
|
|
9
|
+
describe('taskFilter/daysToComplete', function () {
|
|
10
|
+
const commonInput = {
|
|
11
|
+
field_id: '',
|
|
12
|
+
type: 'days_to_complete',
|
|
13
|
+
field_type: 'number',
|
|
14
|
+
value: 1,
|
|
15
|
+
second_value: 5
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const filters = [
|
|
19
|
+
{
|
|
20
|
+
input: {
|
|
21
|
+
...commonInput,
|
|
22
|
+
condition: 'not_equal'
|
|
23
|
+
},
|
|
24
|
+
expected: {
|
|
25
|
+
script: {
|
|
26
|
+
script: {
|
|
27
|
+
source: "\n try {\n def isEmptyReadyAt = doc.containsKey('ready_at') && doc['ready_at'].empty;\n def isEmptyCompletedAt = doc.containsKey('completed_at') && doc['completed_at'].empty;\n\n if (isEmptyReadyAt || isEmptyCompletedAt) {\n return false;\n }\n\n def readyAt = doc['ready_at'].value.toInstant().toEpochMilli();\n def completedAt = doc['completed_at'].value.toInstant().toEpochMilli();\n\n if (readyAt == null || completedAt == null) {\n return false;\n }\n\n def daysToComplete = (completedAt - readyAt) / (1000 * 3600 * 24);\n\n return daysToComplete != params.value\n } catch (Exception err) {\n return false;\n }\n ",
|
|
28
|
+
lang: "painless",
|
|
29
|
+
params: {
|
|
30
|
+
value: 1
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
input: {
|
|
38
|
+
...commonInput,
|
|
39
|
+
condition: 'less_than'
|
|
40
|
+
},
|
|
41
|
+
expected: {
|
|
42
|
+
script: {
|
|
43
|
+
script: {
|
|
44
|
+
source: "\n try {\n def isEmptyReadyAt = doc.containsKey('ready_at') && doc['ready_at'].empty;\n def isEmptyCompletedAt = doc.containsKey('completed_at') && doc['completed_at'].empty;\n\n if (isEmptyReadyAt || isEmptyCompletedAt) {\n return false;\n }\n\n def readyAt = doc['ready_at'].value.toInstant().toEpochMilli();\n def completedAt = doc['completed_at'].value.toInstant().toEpochMilli();\n\n if (readyAt == null || completedAt == null) {\n return false;\n }\n\n def daysToComplete = (completedAt - readyAt) / (1000 * 3600 * 24);\n\n return daysToComplete < params.value\n } catch (Exception err) {\n return false;\n }\n ",
|
|
45
|
+
lang: "painless",
|
|
46
|
+
params: {
|
|
47
|
+
value: 1
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
input: {
|
|
55
|
+
...commonInput,
|
|
56
|
+
condition: 'less_than_or_equal'
|
|
57
|
+
},
|
|
58
|
+
expected: {
|
|
59
|
+
script: {
|
|
60
|
+
script: {
|
|
61
|
+
source: "\n try {\n def isEmptyReadyAt = doc.containsKey('ready_at') && doc['ready_at'].empty;\n def isEmptyCompletedAt = doc.containsKey('completed_at') && doc['completed_at'].empty;\n\n if (isEmptyReadyAt || isEmptyCompletedAt) {\n return false;\n }\n\n def readyAt = doc['ready_at'].value.toInstant().toEpochMilli();\n def completedAt = doc['completed_at'].value.toInstant().toEpochMilli();\n\n if (readyAt == null || completedAt == null) {\n return false;\n }\n\n def daysToComplete = (completedAt - readyAt) / (1000 * 3600 * 24);\n\n return daysToComplete <= params.value\n } catch (Exception err) {\n return false;\n }\n ",
|
|
62
|
+
lang: "painless",
|
|
63
|
+
params: {
|
|
64
|
+
value: 1,
|
|
65
|
+
second_value: 5
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
input: {
|
|
73
|
+
...commonInput,
|
|
74
|
+
condition: 'greater_than'
|
|
75
|
+
},
|
|
76
|
+
expected: {
|
|
77
|
+
script: {
|
|
78
|
+
script: {
|
|
79
|
+
source: "\n try {\n def isEmptyReadyAt = doc.containsKey('ready_at') && doc['ready_at'].empty;\n def isEmptyCompletedAt = doc.containsKey('completed_at') && doc['completed_at'].empty;\n\n if (isEmptyReadyAt || isEmptyCompletedAt) {\n return false;\n }\n\n def readyAt = doc['ready_at'].value.toInstant().toEpochMilli();\n def completedAt = doc['completed_at'].value.toInstant().toEpochMilli();\n\n if (readyAt == null || completedAt == null) {\n return false;\n }\n\n def daysToComplete = (completedAt - readyAt) / (1000 * 3600 * 24);\n\n return daysToComplete > params.value\n } catch (Exception err) {\n return false;\n }\n ",
|
|
80
|
+
lang: "painless",
|
|
81
|
+
params: {
|
|
82
|
+
value: 1
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
input: {
|
|
90
|
+
...commonInput,
|
|
91
|
+
condition: 'greater_than_or_equal'
|
|
92
|
+
},
|
|
93
|
+
expected: {
|
|
94
|
+
script: {
|
|
95
|
+
script: {
|
|
96
|
+
source: "\n try {\n def isEmptyReadyAt = doc.containsKey('ready_at') && doc['ready_at'].empty;\n def isEmptyCompletedAt = doc.containsKey('completed_at') && doc['completed_at'].empty;\n\n if (isEmptyReadyAt || isEmptyCompletedAt) {\n return false;\n }\n\n def readyAt = doc['ready_at'].value.toInstant().toEpochMilli();\n def completedAt = doc['completed_at'].value.toInstant().toEpochMilli();\n\n if (readyAt == null || completedAt == null) {\n return false;\n }\n\n def daysToComplete = (completedAt - readyAt) / (1000 * 3600 * 24);\n\n return daysToComplete >= params.value\n } catch (Exception err) {\n return false;\n }\n ",
|
|
97
|
+
lang: "painless",
|
|
98
|
+
params: {
|
|
99
|
+
value: 1
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
input: {
|
|
107
|
+
...commonInput,
|
|
108
|
+
condition: 'between'
|
|
109
|
+
},
|
|
110
|
+
expected: {
|
|
111
|
+
script: {
|
|
112
|
+
script: {
|
|
113
|
+
source: "\n try {\n def isEmptyReadyAt = doc.containsKey('ready_at') && doc['ready_at'].empty;\n def isEmptyCompletedAt = doc.containsKey('completed_at') && doc['completed_at'].empty;\n\n if (isEmptyReadyAt || isEmptyCompletedAt) {\n return false;\n }\n\n def readyAt = doc['ready_at'].value.toInstant().toEpochMilli();\n def completedAt = doc['completed_at'].value.toInstant().toEpochMilli();\n\n if (readyAt == null || completedAt == null) {\n return false;\n }\n\n def daysToComplete = (completedAt - readyAt) / (1000 * 3600 * 24);\n\n return \n daysToComplete >= params.value &&\n daysToComplete <= params.second_value\n \n } catch (Exception err) {\n return false;\n }\n ",
|
|
114
|
+
lang: "painless",
|
|
115
|
+
params: {
|
|
116
|
+
value: 1,
|
|
117
|
+
second_value: 5
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
input: {
|
|
125
|
+
...commonInput,
|
|
126
|
+
condition: 'is_empty'
|
|
127
|
+
},
|
|
128
|
+
expected: {
|
|
129
|
+
script: {
|
|
130
|
+
script: {
|
|
131
|
+
source: "\n try {\n def isEmptyReadyAt = doc.containsKey('ready_at') && doc['ready_at'].empty;\n def isEmptyCompletedAt = doc.containsKey('completed_at') && doc['completed_at'].empty;\n\n return isEmptyReadyAt || isEmptyCompletedAt;\n } catch (Exception err) {\n return false;\n }\n ",
|
|
132
|
+
lang: "painless"
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
input: {
|
|
139
|
+
...commonInput,
|
|
140
|
+
condition: 'is_not_empty'
|
|
141
|
+
},
|
|
142
|
+
expected: {
|
|
143
|
+
script: {
|
|
144
|
+
script: {
|
|
145
|
+
source: "\n try {\n def isEmptyReadyAt = doc.containsKey('ready_at') && doc['ready_at'].empty;\n def isEmptyCompletedAt = doc.containsKey('completed_at') && doc['completed_at'].empty;\n\n return !isEmptyReadyAt && !isEmptyCompletedAt;\n } catch (Exception err) {\n return false;\n }\n ",
|
|
146
|
+
lang: "painless"
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
];
|
|
152
|
+
|
|
153
|
+
filters.forEach((filter) => {
|
|
154
|
+
it(filter.input.condition, (done) => {
|
|
155
|
+
expect(daysToComplete(filter.input)).to.deep.equal(filter.expected);
|
|
156
|
+
|
|
157
|
+
done();
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
});
|
|
@@ -257,123 +257,136 @@ describe('taskPipeline', function () {
|
|
|
257
257
|
}
|
|
258
258
|
]
|
|
259
259
|
);
|
|
260
|
+
|
|
260
261
|
expect(sort).to.deep.equal([
|
|
261
262
|
{
|
|
262
263
|
_script: {
|
|
263
|
-
type:
|
|
264
|
+
type: "number",
|
|
264
265
|
script: {
|
|
265
|
-
lang:
|
|
266
|
-
source:
|
|
267
|
-
|
|
268
|
-
|
|
266
|
+
lang: "painless",
|
|
267
|
+
source: "\n if (params.starredTaskIds.contains(doc._id.value)) {\n return 1;\n } else {\n return 0;\n }\n ",
|
|
268
|
+
params: {
|
|
269
|
+
starredTaskIds: [
|
|
270
|
+
"task-1",
|
|
271
|
+
"task-2"
|
|
272
|
+
]
|
|
273
|
+
}
|
|
269
274
|
},
|
|
270
|
-
order:
|
|
275
|
+
order: "desc"
|
|
276
|
+
}
|
|
277
|
+
},
|
|
278
|
+
{
|
|
279
|
+
region_name: {
|
|
280
|
+
order: "asc"
|
|
271
281
|
}
|
|
272
282
|
},
|
|
273
|
-
{ region_name: { order: 'asc' } },
|
|
274
283
|
{
|
|
275
284
|
_script: {
|
|
276
|
-
type:
|
|
285
|
+
type: "string",
|
|
277
286
|
script: {
|
|
278
|
-
lang:
|
|
279
|
-
source:
|
|
280
|
-
"\n try {\n String owner = doc['owner'].value;\n\n if (owner != '' && owner != null) {\n return owner.toLowerCase();\n }\n } catch (Exception err) {}\n\n return '';\n "
|
|
287
|
+
lang: "painless",
|
|
288
|
+
source: "\n try {\n String owner = doc['owner'].value;\n\n if (owner != '' && owner != null) {\n return owner.toLowerCase();\n }\n } catch (Exception err) {}\n\n return '';\n "
|
|
281
289
|
},
|
|
282
|
-
order:
|
|
290
|
+
order: "asc"
|
|
283
291
|
}
|
|
284
292
|
},
|
|
285
293
|
{
|
|
286
294
|
_script: {
|
|
287
|
-
type:
|
|
295
|
+
type: "string",
|
|
288
296
|
script: {
|
|
289
|
-
lang:
|
|
290
|
-
source:
|
|
291
|
-
"\n try {\n String owner = doc['owner'].value;\n\n if (owner != '' && owner != null) {\n return owner.toLowerCase();\n }\n } catch (Exception err) {}\n\n return '';\n "
|
|
297
|
+
lang: "painless",
|
|
298
|
+
source: "\n try {\n String owner = doc['owner'].value;\n\n if (owner != '' && owner != null) {\n return owner.toLowerCase();\n }\n } catch (Exception err) {}\n\n return '';\n "
|
|
292
299
|
},
|
|
293
|
-
order:
|
|
300
|
+
order: "asc"
|
|
294
301
|
}
|
|
295
302
|
},
|
|
296
303
|
{
|
|
297
304
|
_script: {
|
|
298
|
-
type:
|
|
305
|
+
type: "string",
|
|
299
306
|
script: {
|
|
300
|
-
lang:
|
|
301
|
-
source:
|
|
302
|
-
"\n try {\n boolean isReady = doc['is_ready'].value;\n boolean isComplete = doc['is_complete'].value;\n\n if (isReady == true) {\n if (isComplete == true) {\n return 'completed';\n }\n\n return 'pending';\n }\n\n return 'new';\n } catch (Exception err) {\n return '';\n }\n "
|
|
307
|
+
lang: "painless",
|
|
308
|
+
source: "\n try {\n boolean isReady = doc['is_ready'].value;\n boolean isComplete = doc['is_complete'].value;\n\n if (isReady == true) {\n if (isComplete == true) {\n return 'completed';\n }\n\n return 'pending';\n }\n\n return 'new';\n } catch (Exception err) {\n return '';\n }\n "
|
|
303
309
|
},
|
|
304
|
-
order:
|
|
310
|
+
order: "desc"
|
|
305
311
|
}
|
|
306
312
|
},
|
|
307
313
|
{
|
|
308
314
|
_script: {
|
|
309
|
-
type:
|
|
315
|
+
type: "number",
|
|
310
316
|
script: {
|
|
311
|
-
lang:
|
|
312
|
-
source:
|
|
313
|
-
"\n try {\n def stageIndex = doc['critical_path.stage_index'].value;\n if (stageIndex != null) {\n return stageIndex;\n }\n \n return 9999999;\n } catch (Exception err) {\n return 9999999;\n }\n "
|
|
317
|
+
lang: "painless",
|
|
318
|
+
source: "\n try {\n def stageIndex = doc['critical_path.stage_index'].value;\n if (stageIndex != null) {\n return stageIndex;\n }\n\n return 9999999;\n } catch (Exception err) {\n return 9999999;\n }\n "
|
|
314
319
|
},
|
|
315
|
-
order:
|
|
320
|
+
order: "desc"
|
|
316
321
|
}
|
|
317
322
|
},
|
|
318
323
|
{
|
|
319
324
|
_script: {
|
|
320
|
-
type:
|
|
325
|
+
type: "number",
|
|
321
326
|
script: {
|
|
322
|
-
lang:
|
|
323
|
-
source:
|
|
324
|
-
"\n def projectNumber = params._source.project_id;\n projectNumber = /[^0-9]/.matcher(projectNumber).replaceAll('');\n return Integer.parseInt(projectNumber);\n "
|
|
327
|
+
lang: "painless",
|
|
328
|
+
source: "\n def projectNumber = params._source.project_id;\n projectNumber = /[^0-9]/.matcher(projectNumber).replaceAll('');\n return Integer.parseInt(projectNumber);\n "
|
|
325
329
|
},
|
|
326
|
-
order:
|
|
330
|
+
order: "desc"
|
|
327
331
|
}
|
|
328
332
|
},
|
|
329
333
|
{
|
|
330
334
|
_script: {
|
|
331
|
-
type:
|
|
335
|
+
type: "number",
|
|
332
336
|
script: {
|
|
333
|
-
lang:
|
|
334
|
-
source:
|
|
335
|
-
"\n try {\n boolean isReady = doc['is_ready'].value;\n boolean isComplete = doc['is_complete'].value;\n\n if (isReady == true && isComplete == true && doc.containsKey('completed_at') && !doc['completed_at'].empty) {\n return doc['completed_at'].value.millis;\n } else if (isReady == true && doc.containsKey('ready_at') && !doc['ready_at'].empty) {\n return doc['ready_at'].value.millis;\n }\n\n return doc['created_at'].value.millis;\n } catch (Exception err) {\n return 0;\n }\n "
|
|
337
|
+
lang: "painless",
|
|
338
|
+
source: "\n try {\n boolean isReady = doc['is_ready'].value;\n boolean isComplete = doc['is_complete'].value;\n\n if (isReady == true && isComplete == true && doc.containsKey('completed_at') && !doc['completed_at'].empty) {\n return doc['completed_at'].value.millis;\n } else if (isReady == true && doc.containsKey('ready_at') && !doc['ready_at'].empty) {\n return doc['ready_at'].value.millis;\n }\n\n return doc['created_at'].value.millis;\n } catch (Exception err) {\n return 0;\n }\n "
|
|
336
339
|
},
|
|
337
|
-
order:
|
|
340
|
+
order: "desc"
|
|
338
341
|
}
|
|
339
342
|
},
|
|
340
343
|
{
|
|
341
344
|
_script: {
|
|
342
|
-
type:
|
|
345
|
+
type: "number",
|
|
343
346
|
script: {
|
|
344
|
-
lang:
|
|
345
|
-
source:
|
|
346
|
-
"\n return doc['was_marked_incomplete'].empty\n ? 0\n : doc['was_marked_incomplete'].value ? 1 : 0;\n "
|
|
347
|
+
lang: "painless",
|
|
348
|
+
source: "\n return doc['was_marked_incomplete'].empty\n ? 0\n : doc['was_marked_incomplete'].value ? 1 : 0;\n "
|
|
347
349
|
},
|
|
348
|
-
order:
|
|
350
|
+
order: "desc"
|
|
351
|
+
}
|
|
352
|
+
},
|
|
353
|
+
{
|
|
354
|
+
"last_comment_data.created_at": {
|
|
355
|
+
order: "desc"
|
|
349
356
|
}
|
|
350
357
|
},
|
|
351
|
-
{ 'last_comment_data.created_at': { order: 'desc' } },
|
|
352
358
|
{
|
|
353
359
|
_script: {
|
|
354
|
-
type:
|
|
360
|
+
type: "number",
|
|
355
361
|
script: {
|
|
356
|
-
lang:
|
|
357
|
-
source:
|
|
358
|
-
|
|
359
|
-
|
|
362
|
+
lang: "painless",
|
|
363
|
+
source: "\n try {\n def fields = params._source.fields;\n\n for (int i=0; i<fields.size(); i++) {\n if (fields[i].id.equals(params.value)) {\n if (fields[i].number != null) {\n return fields[i].number;\n } else {\n return -999999;\n }\n }\n }\n\n return -999999;\n } catch (Exception err) {\n return -999999;\n }\n ",
|
|
364
|
+
params: {
|
|
365
|
+
value: "38d423bf-fc24-4183-b8b7-15420c89e318"
|
|
366
|
+
}
|
|
360
367
|
},
|
|
361
|
-
order:
|
|
368
|
+
order: "desc"
|
|
362
369
|
}
|
|
363
370
|
},
|
|
364
371
|
{
|
|
365
372
|
_script: {
|
|
366
|
-
type:
|
|
373
|
+
type: "string",
|
|
367
374
|
script: {
|
|
368
|
-
lang:
|
|
369
|
-
source:
|
|
370
|
-
|
|
371
|
-
|
|
375
|
+
lang: "painless",
|
|
376
|
+
source: "\n try {\n String textInfo = '';\n def fields = params._source.fields;\n\n for (int i=0; i<fields.size(); i++) {\n if (fields[i].id.equals(params.value)) {\n\n if (fields[i].number != null) {\n return '';\n }\n\n textInfo = fields[i].text == null ? '' : fields[i].text;\n if (fields[i].containsKey('computedText')) {\n textInfo = fields[i].computedText == null ? textInfo : fields[i].computedText;\n }\n }\n }\n\n return textInfo;\n } catch (Exception err) {\n return '';\n }\n ",
|
|
377
|
+
params: {
|
|
378
|
+
value: "38d423bf-fc24-4183-b8b7-15420c89e318"
|
|
379
|
+
}
|
|
372
380
|
},
|
|
373
|
-
order:
|
|
381
|
+
order: "desc"
|
|
374
382
|
}
|
|
375
383
|
},
|
|
376
|
-
{
|
|
384
|
+
{
|
|
385
|
+
id: {
|
|
386
|
+
order: "desc",
|
|
387
|
+
missing: "_last"
|
|
388
|
+
}
|
|
389
|
+
}
|
|
377
390
|
]);
|
|
378
391
|
done();
|
|
379
392
|
});
|