@outliant/sunrise-utils 1.1.13 → 1.1.15

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 CHANGED
@@ -4,10 +4,25 @@ 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.15](https://github.com/outliant/sunrise-utils/compare/1.1.14...1.1.15)
8
+
9
+ - chore: update common filter import #85ztm47dj [`#21`](https://github.com/outliant/sunrise-utils/pull/21)
10
+
11
+ #### [1.1.14](https://github.com/outliant/sunrise-utils/compare/1.1.13...1.1.14)
12
+
13
+ > 12 December 2023
14
+
15
+ - chore: add Is None Of field condition #85ztm47dj [`#20`](https://github.com/outliant/sunrise-utils/pull/20)
16
+ - chore: add Is None Of field condition (WIP) #85ztm47dj [`8005104`](https://github.com/outliant/sunrise-utils/commit/8005104a15eaf5102fe3672f1a9da5d03128ba4b)
17
+ - chore(release): 1.1.14 [`a5eab66`](https://github.com/outliant/sunrise-utils/commit/a5eab66b6260353e13abc095d4f2ffdff70c020b)
18
+
7
19
  #### [1.1.13](https://github.com/outliant/sunrise-utils/compare/1.1.12...1.1.13)
8
20
 
21
+ > 8 November 2023
22
+
9
23
  - chore: change equal condition [`#18`](https://github.com/outliant/sunrise-utils/pull/18)
10
24
  - chore: update isPaused filter [`99d882d`](https://github.com/outliant/sunrise-utils/commit/99d882d74cb7fb6d7aba3048a2328343017ca512)
25
+ - chore(release): 1.1.13 [`998c753`](https://github.com/outliant/sunrise-utils/commit/998c753cd70aad1cf9f55e392a812bf40d74a602)
11
26
 
12
27
  #### [1.1.12](https://github.com/outliant/sunrise-utils/compare/1.1.11...1.1.12)
13
28
 
@@ -0,0 +1,36 @@
1
+ const splitString = require('./splitString');
2
+
3
+ /**
4
+ * Creates a filter condition for "is_none_of" based on the provided filter and filterBuilder function.
5
+ *
6
+ * @param {Object} filter - The filter object.
7
+ * @param {Function} filterBuilder - The function to build filters.
8
+ * @returns {Object|null} The constructed filter condition or null if input is invalid.
9
+ */
10
+ module.exports.isNoneOf = (filter, filterBuilder) => {
11
+ if (
12
+ !filter ||
13
+ !filter.value ||
14
+ !filterBuilder ||
15
+ typeof filterBuilder !== 'function'
16
+ ) {
17
+ return null;
18
+ }
19
+
20
+ const value = typeof filter.value === 'string'
21
+ ? splitString(filter.value)
22
+ : filter.value;
23
+
24
+ if (!value || value && value.length === 0) {
25
+ return null;
26
+ }
27
+
28
+ return {
29
+ bool: {
30
+ must_not: value.map(x => filterBuilder({
31
+ ...filter,
32
+ value: x
33
+ }))
34
+ }
35
+ };
36
+ };
@@ -1,4 +1,5 @@
1
1
  const splitString = require('../splitString');
2
+ const { isNoneOf } = require('../common');
2
3
 
3
4
  module.exports = (filter) => {
4
5
  switch (filter.condition) {
@@ -9,6 +10,11 @@ module.exports = (filter) => {
9
10
  case 'contains_none':
10
11
  case 'not_equal':
11
12
  return module.exports.containsNone(filter);
13
+ case 'is_none_of':
14
+ return isNoneOf(
15
+ filter,
16
+ module.exports.isEqual
17
+ );
12
18
  case 'greater_than_or_equal':
13
19
  return module.exports.greaterThanOrEqual(filter);
14
20
  case 'less_than_or_equal':
@@ -1,6 +1,7 @@
1
1
  const moment = require('moment');
2
2
  const { escapeElasticQuery } = require('../es');
3
3
  const splitString = require('../splitString');
4
+ const { isNoneOf } = require('../common');
4
5
 
5
6
  function getContainsMappingValue(filter) {
6
7
  if (['text', 'textarea'].includes(filter.field_type)) {
@@ -44,6 +45,11 @@ module.exports = (filter) => {
44
45
  return module.exports.isEqual(filter);
45
46
  case 'not_equal':
46
47
  return module.exports.isNotEqual(filter);
48
+ case 'is_none_of':
49
+ return isNoneOf(
50
+ filter,
51
+ module.exports.isEqual
52
+ );
47
53
  case 'before':
48
54
  case 'less_than':
49
55
  return module.exports.isBefore(filter);
@@ -1,6 +1,7 @@
1
1
  const moment = require('moment');
2
2
  const { escapeElasticQuery } = require('../es');
3
3
  const splitString = require('../splitString');
4
+ const { isNoneOf } = require('../common');
4
5
 
5
6
  module.exports = (filter) => {
6
7
  switch (filter.condition) {
@@ -8,6 +9,11 @@ module.exports = (filter) => {
8
9
  return module.exports.isEqual(filter);
9
10
  case 'not_equal':
10
11
  return module.exports.isNotEqual(filter);
12
+ case 'is_none_of':
13
+ return isNoneOf(
14
+ filter,
15
+ module.exports.isEqual
16
+ );
11
17
  case 'before':
12
18
  case 'less_than':
13
19
  return module.exports.isBefore(filter);
@@ -429,4 +435,4 @@ module.exports.isNotEqual = (filter) => {
429
435
  must_not: [mappingValue]
430
436
  }
431
437
  };
432
- };
438
+ };
@@ -1,4 +1,5 @@
1
1
  const splitString = require('../splitString');
2
+ const { isNoneOf } = require('../common');
2
3
 
3
4
  module.exports = (filter) => {
4
5
  switch (filter.condition) {
@@ -8,6 +9,11 @@ module.exports = (filter) => {
8
9
  case 'contains_none':
9
10
  case 'not_equal':
10
11
  return module.exports.containsNone(filter);
12
+ case 'is_none_of':
13
+ return isNoneOf(
14
+ filter,
15
+ module.exports.containsAny
16
+ );
11
17
  default:
12
18
  return null;
13
19
  }
@@ -55,4 +61,4 @@ module.exports.containsNone = (filter) => {
55
61
  })
56
62
  }
57
63
  };
58
- };
64
+ };
@@ -1,4 +1,5 @@
1
1
  const splitString = require('../splitString');
2
+ const { isNoneOf } = require('../common');
2
3
 
3
4
  module.exports = (filter) => {
4
5
  switch (filter.condition) {
@@ -11,6 +12,11 @@ module.exports = (filter) => {
11
12
  case 'is_equal':
12
13
  case 'contains':
13
14
  return module.exports.containsAll(filter);
15
+ case 'is_none_of':
16
+ return isNoneOf(
17
+ filter,
18
+ module.exports.containsAll
19
+ );
14
20
  default:
15
21
  return null;
16
22
  }
@@ -1,4 +1,5 @@
1
1
  const splitString = require('../splitString');
2
+ const { isNoneOf } = require('../common');
2
3
 
3
4
  module.exports = (filter) => {
4
5
  switch (filter.condition) {
@@ -12,6 +13,11 @@ module.exports = (filter) => {
12
13
  return module.exports.isNotEqual(filter);
13
14
  case 'is_any_of':
14
15
  return module.exports.isAnyOf(filter);
16
+ case 'is_none_of':
17
+ return isNoneOf(
18
+ filter,
19
+ module.exports.isEqual
20
+ );
15
21
  default:
16
22
  return null;
17
23
  }
@@ -1,4 +1,5 @@
1
1
  const splitString = require('../splitString');
2
+ const { isNoneOf } = require('../common');
2
3
 
3
4
  module.exports = (filter) => {
4
5
  switch (filter.condition) {
@@ -12,6 +13,11 @@ module.exports = (filter) => {
12
13
  return module.exports.isNotEqual(filter);
13
14
  case 'is_any_of':
14
15
  return module.exports.isAnyOf(filter); // if is any, means all tasks that have value
16
+ case 'is_none_of':
17
+ return isNoneOf(
18
+ filter,
19
+ module.exports.isEqual
20
+ );
15
21
  default:
16
22
  return null;
17
23
  }
@@ -119,4 +125,4 @@ module.exports.isAnyOf = (filter) => {
119
125
  should
120
126
  }
121
127
  };
122
- };
128
+ };
@@ -1,4 +1,5 @@
1
1
  const splitString = require('../splitString');
2
+ const { isNoneOf } = require('../common');
2
3
 
3
4
  module.exports = (filter) => {
4
5
  switch (filter.condition) {
@@ -12,6 +13,11 @@ module.exports = (filter) => {
12
13
  return module.exports.isNotEqual(filter);
13
14
  case 'is_any_of':
14
15
  return module.exports.isAnyOf(filter); // if is any, means all tasks that have value
16
+ case 'is_none_of':
17
+ return isNoneOf(
18
+ filter,
19
+ module.exports.isEqual
20
+ );
15
21
  default:
16
22
  return null;
17
23
  }
@@ -100,4 +106,4 @@ module.exports.isAnyOf = (filter) => {
100
106
  should
101
107
  }
102
108
  };
103
- };
109
+ };
@@ -1,6 +1,7 @@
1
1
  const { validate: isUuid } = require('uuid');
2
2
 
3
3
  const splitString = require('../splitString');
4
+ const { isNoneOf } = require('../common');
4
5
 
5
6
  module.exports = (filter) => {
6
7
  switch (filter.condition) {
@@ -14,6 +15,11 @@ module.exports = (filter) => {
14
15
  return module.exports.isNotEqual(filter);
15
16
  case 'is_any_of':
16
17
  return module.exports.isAnyOf(filter);
18
+ case 'is_none_of':
19
+ return isNoneOf(
20
+ filter,
21
+ module.exports.isEqual
22
+ );
17
23
  default:
18
24
  return null;
19
25
  }
@@ -1,4 +1,5 @@
1
1
  const splitString = require('../splitString');
2
+ const { isNoneOf } = require('../common');
2
3
 
3
4
  module.exports = (filter) => {
4
5
  switch (filter.condition) {
@@ -8,6 +9,11 @@ module.exports = (filter) => {
8
9
  return module.exports.isNotEmpty();
9
10
  case 'is_equal':
10
11
  return module.exports.isEqual(filter);
12
+ case 'is_none_of':
13
+ return isNoneOf(
14
+ filter,
15
+ module.exports.isEqual
16
+ );
11
17
  case 'not_equal':
12
18
  return module.exports.isNotEqual(filter);
13
19
  default:
@@ -81,4 +87,4 @@ module.exports.isNotEqual = (filter) => {
81
87
  }
82
88
 
83
89
  return null;
84
- };
90
+ };
@@ -1,4 +1,5 @@
1
1
  const splitString = require('../splitString');
2
+ const { isNoneOf } = require('../common');
2
3
 
3
4
  module.exports = (filter) => {
4
5
  switch (filter.condition) {
@@ -12,6 +13,11 @@ module.exports = (filter) => {
12
13
  return module.exports.isNotEqual(filter);
13
14
  case 'is_any_of':
14
15
  return module.exports.isAnyOf(filter);
16
+ case 'is_none_of':
17
+ return isNoneOf(
18
+ filter,
19
+ module.exports.isEqual
20
+ );
15
21
  default:
16
22
  return null;
17
23
  }
@@ -176,4 +182,4 @@ module.exports.isNotEqual = (filter) => {
176
182
  }
177
183
 
178
184
  return null;
179
- };
185
+ };
@@ -1,6 +1,7 @@
1
1
  const moment = require('moment');
2
2
 
3
3
  const splitString = require('../splitString');
4
+ const { isNoneOf } = require('../common');
4
5
 
5
6
  module.exports = (filter) => {
6
7
  switch (filter.condition) {
@@ -18,6 +19,11 @@ module.exports = (filter) => {
18
19
  return module.exports.isEqual(filter);
19
20
  case 'not_equal':
20
21
  return module.exports.isNotEqual(filter);
22
+ case 'is_none_of':
23
+ return isNoneOf(
24
+ filter,
25
+ module.exports.isEqual
26
+ );
21
27
  case 'before':
22
28
  case 'less_than':
23
29
  return module.exports.isBefore(filter);
@@ -1,9 +1,16 @@
1
+ const { isNoneOf } = require('../../common');
2
+
1
3
  module.exports = (filter) => {
2
4
  switch (filter.condition) {
3
5
  case 'is_equal':
4
6
  return module.exports.isEqual(filter);
5
7
  case 'not_equal':
6
8
  return module.exports.isNotEqual(filter);
9
+ case 'is_none_of':
10
+ return isNoneOf(
11
+ filter,
12
+ module.exports.isEqual
13
+ );
7
14
  default:
8
15
  return null;
9
16
  }
@@ -74,4 +81,4 @@ module.exports.isNotEqual = (filter) => {
74
81
  }
75
82
 
76
83
  return null;
77
- };
84
+ };
@@ -27,6 +27,10 @@ module.exports.conditions = {
27
27
  {
28
28
  label: 'Contains None',
29
29
  value: 'contains_none'
30
+ },
31
+ {
32
+ label: 'Is None Of',
33
+ value: 'is_none_of'
30
34
  }
31
35
  ],
32
36
  textarea: [
@@ -57,6 +61,10 @@ module.exports.conditions = {
57
61
  {
58
62
  label: 'Contains None',
59
63
  value: 'contains_none'
64
+ },
65
+ {
66
+ label: 'Is None Of',
67
+ value: 'is_none_of'
60
68
  }
61
69
  ],
62
70
  number: [
@@ -113,6 +121,10 @@ module.exports.conditions = {
113
121
  {
114
122
  label: 'Is Not Empty',
115
123
  value: 'is_not_empty'
124
+ },
125
+ {
126
+ label: 'Is None Of',
127
+ value: 'is_none_of'
116
128
  }
117
129
  ],
118
130
  select: [
@@ -135,6 +147,10 @@ module.exports.conditions = {
135
147
  {
136
148
  label: 'Is any of',
137
149
  value: 'is_any_of'
150
+ },
151
+ {
152
+ label: 'Is None Of',
153
+ value: 'is_none_of'
138
154
  }
139
155
  ],
140
156
  date: [
@@ -191,6 +207,10 @@ module.exports.conditions = {
191
207
  {
192
208
  label: 'Is Not Empty',
193
209
  value: 'is_not_empty'
210
+ },
211
+ {
212
+ label: 'Is None Of',
213
+ value: 'is_none_of'
194
214
  }
195
215
  ]
196
216
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@outliant/sunrise-utils",
3
3
  "description": "Helper functions for project Sunrise",
4
- "version": "1.1.13",
4
+ "version": "1.1.15",
5
5
  "license": "ISC",
6
6
  "author": "Outliant",
7
7
  "main": "index.js",
@@ -0,0 +1,139 @@
1
+ 'use strict';
2
+
3
+ /* eslint-env node, mocha */
4
+ const { expect } = require('chai');
5
+
6
+ // To test
7
+ const { isNoneOf } = require('../../helpers/common');
8
+ const { isEqual } = require('../../helpers/taskFilter/ownerFilter');
9
+
10
+ describe('isNoneOf', function () {
11
+ const filters = [
12
+ {
13
+ input: {
14
+ condition: 'is_none_of',
15
+ field_id: '',
16
+ type: 'critical_path_stage',
17
+ field_type: 'select',
18
+ value: 'meow1;meow2',
19
+ second_value: ''
20
+ },
21
+ callback: isEqual,
22
+ output: {
23
+ bool: {
24
+ must_not: [
25
+ {
26
+ bool: {
27
+ must: [
28
+ { term: { team_id: { value: 'meow1' } } }
29
+ ]
30
+ }
31
+ },
32
+ {
33
+ bool: {
34
+ must: [
35
+ { term: { team_id: { value: 'meow2' } } }
36
+ ]
37
+ }
38
+ }
39
+ ]
40
+ }
41
+ }
42
+ },
43
+ {
44
+ input: {
45
+ condition: 'is_none_of',
46
+ field_id: '',
47
+ type: 'critical_path_stage',
48
+ field_type: 'select',
49
+ value: ['meow1', 'meow2'],
50
+ second_value: ''
51
+ },
52
+ callback: isEqual,
53
+ output: {
54
+ bool: {
55
+ must_not: [
56
+ {
57
+ bool: {
58
+ must: [
59
+ { term: { team_id: { value: 'meow1' } } }
60
+ ]
61
+ }
62
+ },
63
+ {
64
+ bool: {
65
+ must: [
66
+ { term: { team_id: { value: 'meow2' } } }
67
+ ]
68
+ }
69
+ }
70
+ ]
71
+ }
72
+ }
73
+ },
74
+ {
75
+ input: {
76
+ condition: 'is_none_of',
77
+ field_id: '',
78
+ type: 'critical_path_stage',
79
+ field_type: 'select',
80
+ value: 'meow',
81
+ second_value: ''
82
+ },
83
+ callback: isEqual,
84
+ output: {
85
+ bool: {
86
+ must_not: [
87
+ {
88
+ bool: {
89
+ must: [
90
+ { term: { team_id: { value: 'meow' } } }
91
+ ]
92
+ }
93
+ }
94
+ ]
95
+ }
96
+ }
97
+ },
98
+ {
99
+ input: {
100
+ condition: 'is_none_of',
101
+ field_id: '',
102
+ type: 'critical_path_stage',
103
+ field_type: 'select',
104
+ value: [],
105
+ second_value: ''
106
+ },
107
+ callback: isEqual,
108
+ output: null
109
+ },
110
+ {
111
+ input: {
112
+ condition: 'is_none_of',
113
+ value: null
114
+ },
115
+ callback: isEqual,
116
+ output: null
117
+ },
118
+ {
119
+ input: {
120
+ condition: 'is_none_of',
121
+ field_id: '',
122
+ type: 'critical_path_stage',
123
+ field_type: 'select',
124
+ value: 'meow',
125
+ second_value: ''
126
+ },
127
+ callback: undefined,
128
+ output: null
129
+ }
130
+ ];
131
+ filters.forEach((filter) => {
132
+ it(`${filter.input.condition}: ${JSON.stringify(
133
+ filter.input.value
134
+ )}`, (done) => {
135
+ expect(isNoneOf(filter.input, filter.callback)).to.deep.equal(filter.output);
136
+ done();
137
+ });
138
+ });
139
+ });
@@ -145,6 +145,60 @@ describe('projectFilter/projectFieldFilter', function () {
145
145
  }
146
146
  }
147
147
  },
148
+ {
149
+ input: {
150
+ condition: 'is_none_of',
151
+ field_id: '2726455e-fd84-4049-9756-e981e20a8772',
152
+ type: 'ticketinformation',
153
+ field_type: 'select',
154
+ value: 'Commercial;Hanwha',
155
+ second_value: ''
156
+ },
157
+ output: {
158
+ bool: {
159
+ must_not: [
160
+ {
161
+ bool: {
162
+ must: [
163
+ {
164
+ nested: {
165
+ path: 'fields',
166
+ query: {
167
+ bool: {
168
+ must: [
169
+ { term: { 'fields.id': { value: '2726455e-fd84-4049-9756-e981e20a8772' } } },
170
+ { term: { 'fields.text': { value: 'Commercial' } } }
171
+ ]
172
+ }
173
+ }
174
+ }
175
+ }
176
+ ]
177
+ }
178
+ },
179
+ {
180
+ bool: {
181
+ must: [
182
+ {
183
+ nested: {
184
+ path: 'fields',
185
+ query: {
186
+ bool: {
187
+ must: [
188
+ { term: { 'fields.id': { value: '2726455e-fd84-4049-9756-e981e20a8772' } } },
189
+ { term: { 'fields.text': { value: 'Hanwha' } } }
190
+ ]
191
+ }
192
+ }
193
+ }
194
+ }
195
+ ]
196
+ }
197
+ }
198
+ ]
199
+ }
200
+ }
201
+ },
148
202
  {
149
203
  input: {
150
204
  condition: 'is_any_of',
@@ -174,6 +228,106 @@ describe('projectFilter/projectFieldFilter', function () {
174
228
  }
175
229
  }
176
230
  },
231
+ {
232
+ input: {
233
+ condition: 'is_none_of',
234
+ field_id: '2726455e-fd84-4049-9756-e981e20a8772',
235
+ type: 'dealinformation',
236
+ field_type: 'select',
237
+ value: ['Commercial', 'Hanwha'],
238
+ second_value: ''
239
+ },
240
+ output: {
241
+ bool: {
242
+ must_not: [
243
+ {
244
+ bool: {
245
+ must: [
246
+ {
247
+ nested: {
248
+ path: 'fields',
249
+ query: {
250
+ bool: {
251
+ must: [
252
+ { term: { 'fields.id': { value: '2726455e-fd84-4049-9756-e981e20a8772' } } },
253
+ { term: { 'fields.text': { value: 'Commercial' } } }
254
+ ]
255
+ }
256
+ }
257
+ }
258
+ }
259
+ ]
260
+ }
261
+ },
262
+ {
263
+ bool: {
264
+ must: [
265
+ {
266
+ nested: {
267
+ path: 'fields',
268
+ query: {
269
+ bool: {
270
+ must: [
271
+ { term: { 'fields.id': { value: '2726455e-fd84-4049-9756-e981e20a8772' } } },
272
+ { term: { 'fields.text': { value: 'Hanwha' } } }
273
+ ]
274
+ }
275
+ }
276
+ }
277
+ }
278
+ ]
279
+ }
280
+ }
281
+ ]
282
+ }
283
+ }
284
+ },
285
+ {
286
+ input: {
287
+ condition: 'is_none_of',
288
+ field_id: '2726455e-fd84-4049-9756-e981e20a8772',
289
+ type: 'dealinformation',
290
+ field_type: 'select',
291
+ value: 'Hanwha',
292
+ second_value: ''
293
+ },
294
+ output: {
295
+ bool: {
296
+ must_not: [
297
+ {
298
+ bool: {
299
+ must: [
300
+ {
301
+ nested: {
302
+ path: 'fields',
303
+ query: {
304
+ bool: {
305
+ must: [
306
+ { term: { 'fields.id': { value: '2726455e-fd84-4049-9756-e981e20a8772' } } },
307
+ { term: { 'fields.text': { value: 'Hanwha' } } }
308
+ ]
309
+ }
310
+ }
311
+ }
312
+ }
313
+ ]
314
+ }
315
+ }
316
+ ]
317
+ }
318
+ }
319
+ },
320
+ {
321
+ input: {
322
+ condition: 'is_none_of',
323
+ field_id: '2726455e-fd84-4049-9756-e981e20a8772',
324
+ type: 'dealinformation',
325
+ field_type: 'select',
326
+ value: null,
327
+ second_value: ''
328
+ },
329
+ output: null
330
+ },
177
331
  {
178
332
  input: {
179
333
  condition: 'is_equal',
@@ -1131,7 +1285,6 @@ describe('projectFilter/projectFilter', () => {
1131
1285
  it(`${filter.input.condition}: ${JSON.stringify(
1132
1286
  filter.input.value
1133
1287
  )}`, (done) => {
1134
-
1135
1288
  const observed = projectFilter(filter.input);
1136
1289
 
1137
1290
  expect(observed).to.deep.equal(filter.output);
@@ -161,7 +161,110 @@ describe('taskFilter/criticalPathFilter', function () {
161
161
  second_value: ''
162
162
  },
163
163
  output: null
164
- }
164
+ },
165
+ {
166
+ input: {
167
+ condition: 'is_none_of',
168
+ field_id: '',
169
+ type: 'critical_path_stage',
170
+ field_type: 'select',
171
+ value:
172
+ '163ba61c-acfa-4f92-bc18-cdef2ab2a959;e03ab325-f630-4517-8055-02c6c0f84141',
173
+ second_value: ''
174
+ },
175
+ output: {
176
+ bool: {
177
+ must_not: [
178
+ {
179
+ bool: {
180
+ must: [
181
+ { exists: { field: 'critical_path.stage_id' } },
182
+ { term: { 'critical_path.stage_id': { value: '163ba61c-acfa-4f92-bc18-cdef2ab2a959' } } }
183
+ ]
184
+ }
185
+ },
186
+ {
187
+ bool: {
188
+ must: [
189
+ { exists: { field: 'critical_path.stage_id' } },
190
+ { term: { 'critical_path.stage_id': { value: 'e03ab325-f630-4517-8055-02c6c0f84141' } } }
191
+ ]
192
+ }
193
+ }
194
+ ]
195
+ }
196
+ }
197
+ },
198
+ {
199
+ input: {
200
+ condition: 'is_none_of',
201
+ field_id: '',
202
+ type: 'critical_path_stage',
203
+ field_type: 'select',
204
+ value: [
205
+ '163ba61c-acfa-4f92-bc18-cdef2ab2a959',
206
+ 'e03ab325-f630-4517-8055-02c6c0f84141'
207
+ ],
208
+ second_value: ''
209
+ },
210
+ output: {
211
+ bool: {
212
+ must_not: [
213
+ {
214
+ bool: {
215
+ must: [
216
+ { exists: { field: 'critical_path.stage_id' } },
217
+ { term: { 'critical_path.stage_id': { value: '163ba61c-acfa-4f92-bc18-cdef2ab2a959' } } }
218
+ ]
219
+ }
220
+ },
221
+ {
222
+ bool: {
223
+ must: [
224
+ { exists: { field: 'critical_path.stage_id' } },
225
+ { term: { 'critical_path.stage_id': { value: 'e03ab325-f630-4517-8055-02c6c0f84141' } } }
226
+ ]
227
+ }
228
+ }
229
+ ]
230
+ }
231
+ }
232
+ },
233
+ {
234
+ input: {
235
+ condition: 'is_none_of',
236
+ field_id: '',
237
+ type: 'critical_path_stage',
238
+ field_type: 'select',
239
+ value: '163ba61c-acfa-4f92-bc18-cdef2ab2a959',
240
+ second_value: ''
241
+ },
242
+ output: {
243
+ bool: {
244
+ must_not: [
245
+ {
246
+ bool: {
247
+ must: [
248
+ { exists: { field: 'critical_path.stage_id' } },
249
+ { term: { 'critical_path.stage_id': { value: '163ba61c-acfa-4f92-bc18-cdef2ab2a959' } } }
250
+ ]
251
+ }
252
+ }
253
+ ]
254
+ }
255
+ }
256
+ },
257
+ {
258
+ input: {
259
+ condition: 'is_none_of',
260
+ field_id: '',
261
+ type: 'critical_path_stage',
262
+ field_type: 'select',
263
+ value: null,
264
+ second_value: ''
265
+ },
266
+ output: null
267
+ },
165
268
  ];
166
269
  filters.forEach((filter) => {
167
270
  it(`${filter.input.condition}: ${JSON.stringify(
@@ -98,6 +98,100 @@ describe('taskFilter/onHoldFilter', function () {
98
98
  second_value: ''
99
99
  },
100
100
  output: null
101
+ },
102
+ {
103
+ input: {
104
+ condition: 'is_none_of',
105
+ field_id: '',
106
+ type: 'on_hold',
107
+ field_type: 'select',
108
+ value: 'No;Yes',
109
+ second_value: ''
110
+ },
111
+ output: {
112
+ bool: {
113
+ must_not: [
114
+ {
115
+ bool: {
116
+ must: [
117
+ { term: { on_hold: { value: false } } }
118
+ ]
119
+ }
120
+ },
121
+ {
122
+ bool: {
123
+ must: [
124
+ { term: { on_hold: { value: true } } }
125
+ ]
126
+ }
127
+ }
128
+ ]
129
+ }
130
+ }
131
+ },
132
+ {
133
+ input: {
134
+ condition: 'is_none_of',
135
+ field_id: '',
136
+ type: 'on_hold',
137
+ field_type: 'select',
138
+ value: ['No', 'Yes'],
139
+ second_value: ''
140
+ },
141
+ output: {
142
+ bool: {
143
+ must_not: [
144
+ {
145
+ bool: {
146
+ must: [
147
+ { term: { on_hold: { value: false } } }
148
+ ]
149
+ }
150
+ },
151
+ {
152
+ bool: {
153
+ must: [
154
+ { term: { on_hold: { value: true } } }
155
+ ]
156
+ }
157
+ }
158
+ ]
159
+ }
160
+ }
161
+ },
162
+ {
163
+ input: {
164
+ condition: 'is_none_of',
165
+ field_id: '',
166
+ type: 'on_hold',
167
+ field_type: 'select',
168
+ value: 'Yes',
169
+ second_value: ''
170
+ },
171
+ output: {
172
+ bool: {
173
+ must_not: [
174
+ {
175
+ bool: {
176
+ must: [
177
+ { term: { on_hold: { value: true } } }
178
+ ]
179
+ }
180
+ }
181
+ ]
182
+ }
183
+ }
184
+ },
185
+ {
186
+ input: {
187
+ condition: 'is_none_of',
188
+ field_id: '',
189
+ type: 'on_hold',
190
+ field_type: 'select',
191
+ value: null,
192
+ second_value: ''
193
+ },
194
+ output: null
101
195
  }
102
196
  ];
103
197
 
@@ -212,6 +212,100 @@ describe('taskFilter/ownerFilter', function () {
212
212
  must: [{ term: { team_id: { value: 'LlrJx3gBfTAqAzzhrb2J' } } }]
213
213
  }
214
214
  }
215
+ },
216
+ {
217
+ input: {
218
+ condition: 'is_none_of',
219
+ field_id: '',
220
+ type: 'owner',
221
+ field_type: 'select',
222
+ value: 'meow1;meow2',
223
+ second_value: ''
224
+ },
225
+ output: {
226
+ bool: {
227
+ must_not: [
228
+ {
229
+ bool: {
230
+ must: [
231
+ { term: { team_id: { value: 'meow1' } } }
232
+ ]
233
+ }
234
+ },
235
+ {
236
+ bool: {
237
+ must: [
238
+ { term: { team_id: { value: 'meow2' } } }
239
+ ]
240
+ }
241
+ }
242
+ ]
243
+ }
244
+ }
245
+ },
246
+ {
247
+ input: {
248
+ condition: 'is_none_of',
249
+ field_id: '',
250
+ type: 'owner',
251
+ field_type: 'select',
252
+ value: ['meow1', 'meow2'],
253
+ second_value: ''
254
+ },
255
+ output: {
256
+ bool: {
257
+ must_not: [
258
+ {
259
+ bool: {
260
+ must: [
261
+ { term: { team_id: { value: 'meow1' } } }
262
+ ]
263
+ }
264
+ },
265
+ {
266
+ bool: {
267
+ must: [
268
+ { term: { team_id: { value: 'meow2' } } }
269
+ ]
270
+ }
271
+ }
272
+ ]
273
+ }
274
+ }
275
+ },
276
+ {
277
+ input: {
278
+ condition: 'is_none_of',
279
+ field_id: '',
280
+ type: 'owner',
281
+ field_type: 'select',
282
+ value: 'meow',
283
+ second_value: ''
284
+ },
285
+ output: {
286
+ bool: {
287
+ must_not: [
288
+ {
289
+ bool: {
290
+ must: [
291
+ { term: { team_id: { value: 'meow' } } }
292
+ ]
293
+ }
294
+ }
295
+ ]
296
+ }
297
+ }
298
+ },
299
+ {
300
+ input: {
301
+ condition: 'is_none_of',
302
+ field_id: '',
303
+ type: 'owner',
304
+ field_type: 'select',
305
+ value: null,
306
+ second_value: ''
307
+ },
308
+ output: null
215
309
  }
216
310
  ];
217
311
 
@@ -117,6 +117,100 @@ describe('taskFilter/regionFilter', function () {
117
117
  second_value: ''
118
118
  },
119
119
  output: null
120
+ },
121
+ {
122
+ input: {
123
+ condition: 'is_none_of',
124
+ field_id: '',
125
+ type: 'region',
126
+ field_type: 'checkbox',
127
+ value: 'meow1,meow2',
128
+ second_value: ''
129
+ },
130
+ output: {
131
+ bool: {
132
+ must_not: [
133
+ {
134
+ bool: {
135
+ should: [
136
+ { term: { region_id: { value: 'meow1' } } }
137
+ ]
138
+ }
139
+ },
140
+ {
141
+ bool: {
142
+ should: [
143
+ { term: { region_id: { value: 'meow2' } } }
144
+ ]
145
+ }
146
+ }
147
+ ]
148
+ }
149
+ }
150
+ },
151
+ {
152
+ input: {
153
+ condition: 'is_none_of',
154
+ field_id: '',
155
+ type: 'region',
156
+ field_type: 'checkbox',
157
+ value: ['meow1', 'meow2'],
158
+ second_value: ''
159
+ },
160
+ output: {
161
+ bool: {
162
+ must_not: [
163
+ {
164
+ bool: {
165
+ should: [
166
+ { term: { region_id: { value: 'meow1' } } }
167
+ ]
168
+ }
169
+ },
170
+ {
171
+ bool: {
172
+ should: [
173
+ { term: { region_id: { value: 'meow2' } } }
174
+ ]
175
+ }
176
+ }
177
+ ]
178
+ }
179
+ }
180
+ },
181
+ {
182
+ input: {
183
+ condition: 'is_none_of',
184
+ field_id: '',
185
+ type: 'region',
186
+ field_type: 'checkbox',
187
+ value: 'meow',
188
+ second_value: ''
189
+ },
190
+ output: {
191
+ bool: {
192
+ must_not: [
193
+ {
194
+ bool: {
195
+ should: [
196
+ { term: { region_id: { value: 'meow' } } }
197
+ ]
198
+ }
199
+ }
200
+ ]
201
+ }
202
+ }
203
+ },
204
+ {
205
+ input: {
206
+ condition: 'is_none_of',
207
+ field_id: '',
208
+ type: 'region',
209
+ field_type: 'checkbox',
210
+ value: null,
211
+ second_value: ''
212
+ },
213
+ output: null
120
214
  }
121
215
  ];
122
216
 
@@ -182,6 +182,103 @@ describe('taskFilter/statusFilter', function () {
182
182
  second_value: ''
183
183
  },
184
184
  output: null
185
+ },
186
+ {
187
+ input: {
188
+ condition: 'is_none_of',
189
+ field_id: '',
190
+ type: 'status',
191
+ field_type: 'select',
192
+ value: 'new;on_hold',
193
+ second_value: ''
194
+ },
195
+ output: {
196
+ bool: {
197
+ must_not: [
198
+ {
199
+ bool: {
200
+ must: [
201
+ { term: { is_ready: false } },
202
+ { term: { is_complete: false } }
203
+ ]
204
+ }
205
+ },
206
+ {
207
+ bool: {
208
+ must: [
209
+ { term: { on_hold: true } }
210
+ ]
211
+ }
212
+ }
213
+ ]
214
+ }
215
+ }
216
+ },
217
+ {
218
+ input: {
219
+ condition: 'is_none_of',
220
+ field_id: '',
221
+ type: 'status',
222
+ field_type: 'select',
223
+ value: ['new', 'on_hold'],
224
+ second_value: ''
225
+ },
226
+ output: {
227
+ bool: {
228
+ must_not: [
229
+ {
230
+ bool: {
231
+ must: [
232
+ { term: { is_ready: false } },
233
+ { term: { is_complete: false } }
234
+ ]
235
+ }
236
+ },
237
+ {
238
+ bool: {
239
+ must: [
240
+ { term: { on_hold: true } }
241
+ ]
242
+ }
243
+ }
244
+ ]
245
+ }
246
+ }
247
+ },
248
+ {
249
+ input: {
250
+ condition: 'is_none_of',
251
+ field_id: '',
252
+ type: 'status',
253
+ field_type: 'select',
254
+ value: 'new',
255
+ second_value: ''
256
+ },
257
+ output: {
258
+ bool: {
259
+ must_not: [
260
+ {
261
+ bool: {
262
+ must: [
263
+ { term: { is_ready: false } },
264
+ { term: { is_complete: false } }
265
+ ]
266
+ }
267
+ }
268
+ ]
269
+ }
270
+ }
271
+ },
272
+ {
273
+ input: {
274
+ condition: 'is_none_of',
275
+ field_id: '',
276
+ type: 'status',
277
+ field_type: 'select',
278
+ value: null,
279
+ second_value: ''
280
+ },
281
+ output: null
185
282
  }
186
283
  ];
187
284
 
@@ -190,7 +287,6 @@ describe('taskFilter/statusFilter', function () {
190
287
  filter.input.value
191
288
  )}`, (done) => {
192
289
  expect(statusFilter(filter.input)).to.deep.equal(filter.output);
193
-
194
290
  done();
195
291
  });
196
292
  });
@@ -341,6 +341,100 @@ describe('taskFieldFilter', function () {
341
341
  second_value: ''
342
342
  },
343
343
  output: null
344
+ },
345
+ {
346
+ input: {
347
+ condition: 'is_none_of',
348
+ field_id: '',
349
+ type: 'project_id',
350
+ field_type: 'text',
351
+ value: 'meow1;meow2',
352
+ second_value: ''
353
+ },
354
+ output: {
355
+ bool: {
356
+ must_not: [
357
+ {
358
+ bool: {
359
+ must: [
360
+ { term: { project_id: { value: 'meow1' } } }
361
+ ]
362
+ }
363
+ },
364
+ {
365
+ bool: {
366
+ must: [
367
+ { term: { project_id: { value: 'meow2' } } }
368
+ ]
369
+ }
370
+ }
371
+ ]
372
+ }
373
+ }
374
+ },
375
+ {
376
+ input: {
377
+ condition: 'is_none_of',
378
+ field_id: '',
379
+ type: 'project_id',
380
+ field_type: 'text',
381
+ value: ['meow1', 'meow2'],
382
+ second_value: ''
383
+ },
384
+ output: {
385
+ bool: {
386
+ must_not: [
387
+ {
388
+ bool: {
389
+ must: [
390
+ { term: { project_id: { value: 'meow1' } } }
391
+ ]
392
+ }
393
+ },
394
+ {
395
+ bool: {
396
+ must: [
397
+ { term: { project_id: { value: 'meow2' } } }
398
+ ]
399
+ }
400
+ }
401
+ ]
402
+ }
403
+ }
404
+ },
405
+ {
406
+ input: {
407
+ condition: 'is_none_of',
408
+ field_id: '',
409
+ type: 'project_id',
410
+ field_type: 'text',
411
+ value: 'meow',
412
+ second_value: ''
413
+ },
414
+ output: {
415
+ bool: {
416
+ must_not: [
417
+ {
418
+ bool: {
419
+ must: [
420
+ { term: { project_id: { value: 'meow' } } }
421
+ ]
422
+ }
423
+ }
424
+ ]
425
+ }
426
+ }
427
+ },
428
+ {
429
+ input: {
430
+ condition: 'is_none_of',
431
+ field_id: '',
432
+ type: 'project_id',
433
+ field_type: 'text',
434
+ value: null,
435
+ second_value: ''
436
+ },
437
+ output: null
344
438
  }
345
439
  ];
346
440