@outliant/sunrise-utils 1.1.2 → 1.1.4

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,9 +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.4](https://github.com/outliant/sunrise-utils/compare/1.1.3...1.1.4)
8
+
9
+ - chore: support user field type project fields #860qfghzp [`7f4688b`](https://github.com/outliant/sunrise-utils/commit/7f4688b270fe8734153613650c87eef28483068a)
10
+
11
+ #### [1.1.3](https://github.com/outliant/sunrise-utils/compare/1.1.2...1.1.3)
12
+
13
+ > 28 April 2023
14
+
15
+ - Task/project filter #860qjddeg [`#8`](https://github.com/outliant/sunrise-utils/pull/8)
16
+ - wip: project filter [`0dec4e1`](https://github.com/outliant/sunrise-utils/commit/0dec4e1830bab4470c0b2d23bdfd8cbafe8fc6a7)
17
+ - chore: fix specs [`4d0474c`](https://github.com/outliant/sunrise-utils/commit/4d0474c74bb6a545b66a821cf63376b323393e58)
18
+ - chore: before and after [`91b8c0f`](https://github.com/outliant/sunrise-utils/commit/91b8c0f0e7bf3912a069628563746332683cc06f)
19
+
7
20
  #### [1.1.2](https://github.com/outliant/sunrise-utils/compare/1.1.1...1.1.2)
8
21
 
22
+ > 19 April 2023
23
+
9
24
  - chore: set departmentId to optional [`#7`](https://github.com/outliant/sunrise-utils/pull/7)
25
+ - chore(release): 1.1.2 [`f9770a2`](https://github.com/outliant/sunrise-utils/commit/f9770a21f9b31d3acbb5e4c36b11013b5ba4951c)
10
26
 
11
27
  #### [1.1.1](https://github.com/outliant/sunrise-utils/compare/1.1.0...1.1.1)
12
28
 
@@ -4,6 +4,7 @@ const buildOnHoldFilter = require('./onHoldFilter');
4
4
  const buildIsGeneratedFilter = require('./isGeneratedFilter');
5
5
  const buildTagFilter = require('./tagFilter');
6
6
  const buildProjectFieldFilter = require('./projectFieldFilter');
7
+ const buildProjectFilter = require('./projectFilter');
7
8
 
8
9
  module.exports.defaultCustomColumns = [
9
10
  {
@@ -91,6 +92,6 @@ module.exports.buildProjectPipelineFilter = (filter) => {
91
92
  case 'contactPropertyMappings':
92
93
  return buildProjectFieldFilter(filter);
93
94
  default:
94
- return null;
95
+ return buildProjectFilter(filter);
95
96
  }
96
97
  };
@@ -0,0 +1,367 @@
1
+ const moment = require('moment');
2
+ const { escapeElasticQuery } = require('../es');
3
+
4
+ module.exports = (filter) => {
5
+ switch (filter.condition) {
6
+ case 'is_equal':
7
+ return module.exports.isEqual(filter);
8
+ case 'not_equal':
9
+ return module.exports.isNotEqual(filter);
10
+ case 'before':
11
+ case 'less_than':
12
+ return module.exports.isBefore(filter);
13
+ case 'after':
14
+ case 'greater_than':
15
+ return module.exports.isAfter(filter);
16
+ case 'between':
17
+ return module.exports.isBetween(filter);
18
+ case 'next_n_days':
19
+ return module.exports.nextNDays(filter);
20
+ case 'last_n_days':
21
+ return module.exports.lastNDays(filter);
22
+ case 'is_empty':
23
+ return module.exports.isEmpty(filter);
24
+ case 'is_not_empty':
25
+ return module.exports.isNotEmpty(filter);
26
+ default:
27
+ return null;
28
+ }
29
+ };
30
+
31
+ module.exports.isEmpty = (filter) => {
32
+ if (!filter.type) {
33
+ return null;
34
+ }
35
+
36
+ return {
37
+ bool: {
38
+ must: [
39
+ {
40
+ term: {
41
+ [filter.type]: {
42
+ value: ''
43
+ }
44
+ }
45
+ }
46
+ ]
47
+ }
48
+ };
49
+ };
50
+
51
+ module.exports.isNotEmpty = (filter) => {
52
+ if (!filter.type) {
53
+ return null;
54
+ }
55
+
56
+ return {
57
+ bool: {
58
+ must_not: [
59
+ {
60
+ term: {
61
+ [filter.type]: {
62
+ value: ''
63
+ }
64
+ }
65
+ }
66
+ ]
67
+ }
68
+ };
69
+ };
70
+
71
+ module.exports.isEqual = (filter) => {
72
+ if (!filter.type) {
73
+ return null;
74
+ }
75
+
76
+ const param = (() => {
77
+ if (filter.field_type === 'date') {
78
+ const startOfDay = moment(filter.value).startOf('day').valueOf();
79
+ const endOfDay = moment(filter.value).endOf('day').valueOf();
80
+
81
+ return {
82
+ range: {
83
+ [filter.type]: {
84
+ gte: startOfDay,
85
+ lte: endOfDay
86
+ }
87
+ }
88
+ };
89
+ }
90
+
91
+ if (filter.field_type === 'number') {
92
+ return {
93
+ term: {
94
+ [filter.type]: {
95
+ value: parseInt(filter.value)
96
+ }
97
+ }
98
+ };
99
+ }
100
+
101
+ if (filter.field_type === 'textarea') {
102
+ return {
103
+ query_string: {
104
+ fields: [filter.type],
105
+ query: `*${escapeElasticQuery(filter.value.trim())}*`
106
+ }
107
+ };
108
+ }
109
+
110
+ if (filter.field_type === 'checkbox') {
111
+ const value =
112
+ typeof filter.value === 'string' ? value.split(';') : filter.value;
113
+
114
+ return {
115
+ bool: {
116
+ should: value.map((x) => {
117
+ return {
118
+ match: {
119
+ [`${filter.type}.analyzed`]: {
120
+ query: x,
121
+ operator: 'and'
122
+ }
123
+ }
124
+ };
125
+ })
126
+ }
127
+ };
128
+ }
129
+
130
+ return {
131
+ term: {
132
+ 'fields.text': {
133
+ value: filter.value
134
+ }
135
+ }
136
+ };
137
+ })();
138
+
139
+ return {
140
+ bool: {
141
+ must: [param]
142
+ }
143
+ };
144
+ };
145
+
146
+ module.exports.isBefore = (filter) => {
147
+ if (!filter.type) {
148
+ return null;
149
+ }
150
+
151
+ const param = (() => {
152
+ if (filter.field_type === 'date') {
153
+ return moment(filter.value).startOf('day').valueOf();
154
+ }
155
+
156
+ if (filter.field_type === 'number') {
157
+ return parseInt(filter.value);
158
+ }
159
+
160
+ return null;
161
+ })();
162
+
163
+ if (!param) {
164
+ return null;
165
+ }
166
+
167
+ return {
168
+ bool: {
169
+ must: [
170
+ {
171
+ range: {
172
+ [filter.type]: {
173
+ lt: param
174
+ }
175
+ }
176
+ }
177
+ ]
178
+ }
179
+ };
180
+ };
181
+
182
+ module.exports.isAfter = (filter) => {
183
+ if (!filter.type) {
184
+ return null;
185
+ }
186
+
187
+ const param = (() => {
188
+ if (filter.field_type === 'date') {
189
+ return moment(filter.value).endOf('day').valueOf();
190
+ }
191
+
192
+ if (filter.field_type === 'number') {
193
+ return parseInt(filter.value);
194
+ }
195
+
196
+ return null;
197
+ })();
198
+
199
+ if (!param) {
200
+ return null;
201
+ }
202
+
203
+ return {
204
+ bool: {
205
+ must: [
206
+ {
207
+ range: {
208
+ [filter.type]: {
209
+ gt: param
210
+ }
211
+ }
212
+ }
213
+ ]
214
+ }
215
+ };
216
+ };
217
+
218
+ module.exports.nextNDays = (filter) => {
219
+ if (!filter.type) {
220
+ return null;
221
+ }
222
+
223
+ if (isNaN(filter.value)) {
224
+ return null;
225
+ }
226
+
227
+ const today = moment().startOf('day');
228
+
229
+ const nextNDays = moment().add(filter.value, 'd').endOf('day');
230
+
231
+ const res = {
232
+ bool: {
233
+ must: [
234
+ {
235
+ range: {
236
+ [filter.type]: {
237
+ gt: today.valueOf(),
238
+ lt: nextNDays.valueOf()
239
+ }
240
+ }
241
+ }
242
+ ]
243
+ }
244
+ };
245
+
246
+ return res;
247
+ };
248
+
249
+ module.exports.lastNDays = (filter) => {
250
+ if (!filter.type) {
251
+ return null;
252
+ }
253
+
254
+ if (isNaN(filter.value)) {
255
+ return null;
256
+ }
257
+
258
+ const today = moment().startOf('day');
259
+
260
+ const lastNDays = moment().subtract(filter.value, 'd').endOf('day');
261
+
262
+ const res = {
263
+ bool: {
264
+ must: [
265
+ {
266
+ range: {
267
+ [filter.type]: {
268
+ lt: today.valueOf(),
269
+ gt: lastNDays.valueOf()
270
+ }
271
+ }
272
+ }
273
+ ]
274
+ }
275
+ };
276
+
277
+ return res;
278
+ };
279
+
280
+ module.exports.isBetween = (filter) => {
281
+ if (!filter.type) {
282
+ return null;
283
+ }
284
+
285
+ const param = (() => {
286
+ if (filter.field_type === 'date') {
287
+ return {
288
+ from: moment(filter.value).startOf('day').valueOf(),
289
+ to: moment(filter.second_value).endOf('day').valueOf()
290
+ };
291
+ }
292
+
293
+ if (filter.field_type === 'number') {
294
+ return {
295
+ from: parseInt(filter.value),
296
+ to: parseInt(filter.second_value)
297
+ };
298
+ }
299
+
300
+ return null;
301
+ })();
302
+
303
+ if (!param) {
304
+ return null;
305
+ }
306
+
307
+ return {
308
+ bool: {
309
+ must: [
310
+ {
311
+ range: {
312
+ [filter.type]: {
313
+ gte: param.from,
314
+ lte: param.to
315
+ }
316
+ }
317
+ }
318
+ ]
319
+ }
320
+ };
321
+ };
322
+
323
+ module.exports.isNotEqual = (filter) => {
324
+ if (!filter.type) {
325
+ return null;
326
+ }
327
+
328
+ const mappingValue = (() => {
329
+ if (filter.field_type === 'date') {
330
+ const startOfDay = moment(filter.value).startOf('day').valueOf();
331
+ const endOfDay = moment(filter.value).endOf('day').valueOf();
332
+
333
+ return {
334
+ range: {
335
+ [filter.type]: {
336
+ gte: startOfDay,
337
+ lte: endOfDay
338
+ }
339
+ }
340
+ };
341
+ }
342
+
343
+ if (filter.field_type === 'number') {
344
+ return {
345
+ term: {
346
+ [filter.type]: {
347
+ value: parseInt(filter.value)
348
+ }
349
+ }
350
+ };
351
+ }
352
+
353
+ return {
354
+ term: {
355
+ [filter.type]: {
356
+ value: filter.value
357
+ }
358
+ }
359
+ };
360
+ })();
361
+
362
+ return {
363
+ bool: {
364
+ must_not: [mappingValue]
365
+ }
366
+ };
367
+ };
@@ -335,10 +335,12 @@ module.exports.projectFieldText = (order, value) => {
335
335
  if (fields[i].number != null) {
336
336
  return '';
337
337
  }
338
-
338
+
339
339
  textInfo = fields[i].text == null ? '' : fields[i].text;
340
+ if (fields[i].containsKey('computedText')) {
341
+ textInfo = fields[i].computedText == null ? textInfo : fields[i].computedText;
342
+ }
340
343
  }
341
-
342
344
  }
343
345
 
344
346
  return textInfo;
@@ -174,6 +174,24 @@ module.exports.conditions = {
174
174
  label: 'In The Last N Days',
175
175
  value: 'last_n_days'
176
176
  }
177
+ ],
178
+ user_select: [
179
+ {
180
+ label: 'Equals',
181
+ value: 'is_equal'
182
+ },
183
+ {
184
+ label: "Doesn't Equal",
185
+ value: 'not_equal'
186
+ },
187
+ {
188
+ label: 'Is Empty',
189
+ value: 'is_empty'
190
+ },
191
+ {
192
+ label: 'Is Not Empty',
193
+ value: 'is_not_empty'
194
+ }
177
195
  ]
178
196
  };
179
197
 
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.2",
4
+ "version": "1.1.4",
5
5
  "license": "ISC",
6
6
  "author": "Outliant",
7
7
  "main": "index.js",
@@ -5,6 +5,7 @@ const { expect } = require('chai');
5
5
 
6
6
  // To test
7
7
  const projectFieldFilter = require('../../../helpers/projectFilter/projectFieldFilter');
8
+ const projectFilter = require('../../../helpers/projectFilter/projectFilter');
8
9
 
9
10
  describe('projectFilter/projectFieldFilter', function () {
10
11
  const filters = [
@@ -879,3 +880,231 @@ describe('projectFilter/projectFieldFilter', function () {
879
880
  });
880
881
  });
881
882
  });
883
+
884
+ describe('projectFilter/projectFilter', () => {
885
+ const filters = [
886
+ {
887
+ input: {
888
+ condition: 'is_equal',
889
+ field_id: '5a681cb0-0682-48a8-875f-a525c795d398',
890
+ type: 'created_at',
891
+ field_type: 'date',
892
+ value: 1677196800000,
893
+ second_value: ''
894
+ },
895
+ output: {
896
+ bool: {
897
+ must: [
898
+ {
899
+ range: {
900
+ created_at: {
901
+ gte: 1677168000000,
902
+ lte: 1677254399999
903
+ }
904
+ }
905
+ }
906
+ ]
907
+ }
908
+ }
909
+ },
910
+ {
911
+ input: {
912
+ condition: 'not_equal',
913
+ field_id: '5a681cb0-0682-48a8-875f-a525c795d398',
914
+ type: 'created_at',
915
+ field_type: 'date',
916
+ value: 1677196800000,
917
+ second_value: ''
918
+ },
919
+ output: {
920
+ bool: {
921
+ must_not: [
922
+ {
923
+ range: {
924
+ created_at: {
925
+ gte: 1677168000000,
926
+ lte: 1677254399999
927
+ }
928
+ }
929
+ }
930
+ ]
931
+ }
932
+ }
933
+ },
934
+ ...['before', 'less_than'].map(condition => ({
935
+ input: {
936
+ condition: condition,
937
+ field_id: '5a681cb0-0682-48a8-875f-a525c795d398',
938
+ type: 'created_at',
939
+ field_type: 'date',
940
+ value: 1677196800000,
941
+ second_value: ''
942
+ },
943
+ output: {
944
+ bool: {
945
+ must: [
946
+ {
947
+ range: {
948
+ created_at: {
949
+ lt: 1677168000000
950
+ }
951
+ }
952
+ }
953
+ ]
954
+ }
955
+ }
956
+ })),
957
+ ...['after', 'greater_than'].map(condition => ({
958
+ input: {
959
+ condition: condition,
960
+ field_id: '5a681cb0-0682-48a8-875f-a525c795d398',
961
+ type: 'created_at',
962
+ field_type: 'date',
963
+ value: 1677196800000,
964
+ second_value: ''
965
+ },
966
+ output: {
967
+ bool: {
968
+ must: [
969
+ {
970
+ range: {
971
+ created_at: {
972
+ gt: 1677254399999
973
+ }
974
+ }
975
+ }
976
+ ]
977
+ }
978
+ }
979
+ })),
980
+ {
981
+ input: {
982
+ condition: 'between',
983
+ field_id: '5a681cb0-0682-48a8-875f-a525c795d398',
984
+ type: 'created_at',
985
+ field_type: 'date',
986
+ value: 1677196800000,
987
+ second_value: 1677196800000
988
+ },
989
+ output: {
990
+ bool: {
991
+ must: [
992
+ {
993
+ range: {
994
+ created_at: {
995
+ gte: 1677168000000,
996
+ lte: 1677254399999
997
+ }
998
+ }
999
+ }
1000
+ ]
1001
+ }
1002
+ }
1003
+ },
1004
+ {
1005
+ input: {
1006
+ condition: 'next_n_days',
1007
+ field_id: '5a681cb0-0682-48a8-875f-a525c795d398',
1008
+ type: 'created_at',
1009
+ field_type: 'date',
1010
+ value: 5,
1011
+ second_value: ''
1012
+ },
1013
+ output: {
1014
+ bool: {
1015
+ must: [
1016
+ {
1017
+ range: {
1018
+ created_at: {
1019
+ gt: 1682524800000,
1020
+ lt: 1683043199999
1021
+ }
1022
+ }
1023
+ }
1024
+ ]
1025
+ }
1026
+ }
1027
+ },
1028
+ {
1029
+ input: {
1030
+ condition: 'last_n_days',
1031
+ field_id: '5a681cb0-0682-48a8-875f-a525c795d398',
1032
+ type: 'created_at',
1033
+ field_type: 'date',
1034
+ value: 3,
1035
+ second_value: ''
1036
+ },
1037
+ output: {
1038
+ bool: {
1039
+ must: [
1040
+ {
1041
+ range: {
1042
+ created_at: {
1043
+ lt: 1682524800000,
1044
+ gt: 1682351999999
1045
+ }
1046
+ }
1047
+ }
1048
+ ]
1049
+ }
1050
+ }
1051
+ },
1052
+ {
1053
+ input: {
1054
+ condition: 'is_empty',
1055
+ field_id: '',
1056
+ type: 'created_at',
1057
+ field_type: 'date',
1058
+ value: '',
1059
+ second_value: ''
1060
+ },
1061
+ output: {
1062
+ bool: {
1063
+ must: [
1064
+ {
1065
+ term: {
1066
+ created_at: {
1067
+ value: ""
1068
+ }
1069
+ }
1070
+ }
1071
+ ]
1072
+ }
1073
+ }
1074
+ },
1075
+ {
1076
+ input: {
1077
+ condition: 'is_not_empty',
1078
+ field_id: '',
1079
+ type: 'created_at',
1080
+ field_type: 'date',
1081
+ value: '',
1082
+ second_value: ''
1083
+ },
1084
+ output: {
1085
+ bool: {
1086
+ must_not: [
1087
+ {
1088
+ term: {
1089
+ created_at: {
1090
+ value: ""
1091
+ }
1092
+ }
1093
+ }
1094
+ ]
1095
+ }
1096
+ }
1097
+ }
1098
+ ];
1099
+
1100
+ filters.forEach((filter) => {
1101
+ it(`${filter.input.condition}: ${JSON.stringify(
1102
+ filter.input.value
1103
+ )}`, (done) => {
1104
+ const observed = projectFilter(filter.input);
1105
+
1106
+ expect(observed).to.deep.equal(filter.output);
1107
+ done();
1108
+ });
1109
+ });
1110
+ });