@outliant/sunrise-utils 1.0.0

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.
Files changed (40) hide show
  1. package/.eslintignore +5 -0
  2. package/.eslintrc +53 -0
  3. package/.github/workflows/pr-dev-workflow.yml +16 -0
  4. package/.nvmrc +1 -0
  5. package/.release-it.js +26 -0
  6. package/.vscode/launch.json +24 -0
  7. package/.vscode/settings.json +7 -0
  8. package/CHANGELOG.md +12 -0
  9. package/README.md +19 -0
  10. package/changelog.hbs +13 -0
  11. package/helpers/es.js +6 -0
  12. package/helpers/projectFilter/projectFieldFilter.js +587 -0
  13. package/helpers/searchFilter.js +86 -0
  14. package/helpers/taskFilter/criticalPathFilter.js +144 -0
  15. package/helpers/taskFilter/index.js +228 -0
  16. package/helpers/taskFilter/onHoldFilter.js +101 -0
  17. package/helpers/taskFilter/ownerFilter.js +148 -0
  18. package/helpers/taskFilter/pathAgeFilter.js +18 -0
  19. package/helpers/taskFilter/regionFilter.js +82 -0
  20. package/helpers/taskFilter/statusFilter.js +177 -0
  21. package/helpers/taskFilter/taskFieldFilter.js +309 -0
  22. package/helpers/taskSortScript.js +356 -0
  23. package/index.d.ts +11 -0
  24. package/index.js +9 -0
  25. package/lib/fieldConditions.js +166 -0
  26. package/lib/logger.js +48 -0
  27. package/lib/taskPipeline.js +137 -0
  28. package/package.json +73 -0
  29. package/test/helpers/projectFilter/projectFieldFilter.spec.js +881 -0
  30. package/test/helpers/taskFilter/criticalPathFilter.spec.js +174 -0
  31. package/test/helpers/taskFilter/index.spec.js +339 -0
  32. package/test/helpers/taskFilter/onHoldFilter.spec.js +112 -0
  33. package/test/helpers/taskFilter/ownerFilter.spec.js +226 -0
  34. package/test/helpers/taskFilter/pathAgeFilter.spec.js +47 -0
  35. package/test/helpers/taskFilter/regionFilter.spec.js +131 -0
  36. package/test/helpers/taskFilter/statusFilter.spec.js +197 -0
  37. package/test/helpers/taskFilter/taskFieldFilter.spec.js +355 -0
  38. package/test/lib/fieldConditions.spec.js +17 -0
  39. package/test/lib/logger.spec.js +117 -0
  40. package/test/lib/taskPipeline.spec.js +162 -0
@@ -0,0 +1,144 @@
1
+ module.exports = (filter) => {
2
+ switch (filter.condition) {
3
+ case 'is_empty':
4
+ return module.exports.isEmpty();
5
+ case 'is_not_empty':
6
+ return module.exports.isNotEmpty();
7
+ case 'is_equal':
8
+ return module.exports.isEqual(filter);
9
+ case 'not_equal':
10
+ return module.exports.isNotEqual(filter);
11
+ case 'is_any_of':
12
+ return module.exports.isAnyOf(filter);
13
+ default:
14
+ return null;
15
+ }
16
+ };
17
+
18
+ module.exports.isEmpty = () => {
19
+ return {
20
+ bool: {
21
+ should: [
22
+ {
23
+ bool: {
24
+ must_not: [
25
+ {
26
+ exists: {
27
+ field: 'critical_path'
28
+ }
29
+ }
30
+ ]
31
+ }
32
+ },
33
+ {
34
+ bool: {
35
+ must_not: [
36
+ {
37
+ exists: {
38
+ field: 'critical_path.stage_id'
39
+ }
40
+ }
41
+ ]
42
+ }
43
+ },
44
+ {
45
+ term: {
46
+ 'critical_path.stage_id': {
47
+ value: ''
48
+ }
49
+ }
50
+ }
51
+ ]
52
+ }
53
+ };
54
+ };
55
+
56
+ module.exports.isNotEmpty = () => {
57
+ return {
58
+ bool: {
59
+ must: [
60
+ {
61
+ exists: {
62
+ field: 'critical_path'
63
+ }
64
+ },
65
+ {
66
+ exists: {
67
+ field: 'critical_path.stage_id'
68
+ }
69
+ }
70
+ ],
71
+ must_not: [
72
+ {
73
+ term: {
74
+ 'critical_path.stage_id': {
75
+ value: ''
76
+ }
77
+ }
78
+ }
79
+ ]
80
+ }
81
+ };
82
+ };
83
+
84
+ module.exports.isEqual = (filter) => {
85
+ return {
86
+ bool: {
87
+ must: [
88
+ {
89
+ exists: {
90
+ field: 'critical_path.stage_id'
91
+ }
92
+ },
93
+ {
94
+ term: {
95
+ 'critical_path.stage_id': {
96
+ value: filter.value
97
+ }
98
+ }
99
+ }
100
+ ]
101
+ }
102
+ };
103
+ };
104
+
105
+ module.exports.isAnyOf = (filter) => {
106
+ let value = filter.value;
107
+
108
+ if (typeof value === 'string') {
109
+ value = value.split(';');
110
+ }
111
+
112
+ return {
113
+ bool: {
114
+ must: [
115
+ {
116
+ exists: {
117
+ field: 'critical_path.stage_id'
118
+ }
119
+ },
120
+ {
121
+ terms: {
122
+ 'critical_path.stage_id': value
123
+ }
124
+ }
125
+ ]
126
+ }
127
+ };
128
+ };
129
+
130
+ module.exports.isNotEqual = (filter) => {
131
+ return {
132
+ bool: {
133
+ must_not: [
134
+ {
135
+ term: {
136
+ 'critical_path.stage_id': {
137
+ value: filter.value
138
+ }
139
+ }
140
+ }
141
+ ]
142
+ }
143
+ };
144
+ };
@@ -0,0 +1,228 @@
1
+ const buildStatusFilter = require('./statusFilter');
2
+ const buildOwnerFilter = require('./ownerFilter');
3
+ const buildPathAgeFilter = require('./pathAgeFilter');
4
+ const buildRegionFilter = require('./regionFilter');
5
+ const buildTaskFieldFilter = require('./taskFieldFilter');
6
+ const buildCriticalPathFilter = require('./criticalPathFilter');
7
+ const buildOnHoldFilter = require('./onHoldFilter');
8
+ const buildProjectFieldFilter = require('../projectFilter/projectFieldFilter');
9
+
10
+ module.exports.taskStatusOptions = [
11
+ {
12
+ label: 'Blocked',
13
+ value: 'new'
14
+ },
15
+ {
16
+ label: 'Pending',
17
+ value: 'pending'
18
+ },
19
+ {
20
+ label: 'Completed',
21
+ value: 'completed'
22
+ },
23
+ {
24
+ label: 'Cancelled',
25
+ value: 'on_hold'
26
+ },
27
+ {
28
+ label: 'Overdue',
29
+ value: 'overdue'
30
+ }
31
+ ];
32
+
33
+ module.exports.defaultCustomColumns = [
34
+ {
35
+ name: 'Owner',
36
+ value: 'owner',
37
+ type: 'owner',
38
+ field_type: 'select',
39
+ options: []
40
+ },
41
+ {
42
+ name: 'Age',
43
+ value: 'ready_at',
44
+ type: 'ready_at',
45
+ field_type: 'date'
46
+ },
47
+ {
48
+ name: 'Project ID',
49
+ value: 'project_id',
50
+ type: 'project_id',
51
+ field_type: 'text'
52
+ },
53
+ {
54
+ name: 'Status',
55
+ value: 'status',
56
+ type: 'status',
57
+ field_type: 'select',
58
+ options: []
59
+ },
60
+ {
61
+ name: 'Region',
62
+ value: 'region',
63
+ type: 'region',
64
+ field_type: 'checkbox',
65
+ options: []
66
+ },
67
+ {
68
+ name: 'Description',
69
+ value: 'notes',
70
+ type: 'notes',
71
+ field_type: 'textarea'
72
+ },
73
+ {
74
+ name: 'Cancelled',
75
+ value: 'on_hold',
76
+ type: 'on_hold',
77
+ field_type: 'select',
78
+ options: [
79
+ {
80
+ label: 'Yes',
81
+ value: 'Yes'
82
+ },
83
+ {
84
+ label: 'No',
85
+ value: 'No'
86
+ }
87
+ ]
88
+ },
89
+ {
90
+ name: 'Last Comment',
91
+ value: 'last_comment',
92
+ type: 'last_comment',
93
+ field_type: 'textarea'
94
+ },
95
+ {
96
+ name: 'Last Comment Date',
97
+ value: 'last_comment_date',
98
+ type: 'last_comment_date',
99
+ field_type: 'date'
100
+ },
101
+ {
102
+ name: 'Due Date',
103
+ value: 'due_date',
104
+ type: 'due_date',
105
+ field_type: 'date'
106
+ },
107
+ {
108
+ name: 'Completed By',
109
+ value: 'completed_by',
110
+ type: 'completed_by',
111
+ field_type: 'select',
112
+ options: []
113
+ },
114
+ {
115
+ name: 'Completed At',
116
+ value: 'completed_at',
117
+ type: 'completed_at',
118
+ field_type: 'date'
119
+ },
120
+ {
121
+ name: 'Created',
122
+ value: 'created_at',
123
+ type: 'created_at',
124
+ field_type: 'date'
125
+ },
126
+ {
127
+ name: 'Updated',
128
+ value: 'updated_at',
129
+ type: 'updated_at',
130
+ field_type: 'date'
131
+ },
132
+ {
133
+ name: 'Critical Path Stage',
134
+ value: 'critical_path_stage',
135
+ type: 'critical_path_stage',
136
+ field_type: 'select',
137
+ options: []
138
+ },
139
+ {
140
+ name: 'Was Marked Incomplete',
141
+ value: 'was_marked_incomplete',
142
+ type: 'was_marked_incomplete',
143
+ field_type: 'select',
144
+ options: [
145
+ {
146
+ label: 'Yes',
147
+ value: 'Yes'
148
+ },
149
+ {
150
+ label: 'No',
151
+ value: 'No'
152
+ }
153
+ ]
154
+ },
155
+ {
156
+ name: 'Marked Incomplete At',
157
+ value: 'marked_incomplete_at',
158
+ type: 'marked_incomplete_at',
159
+ field_type: 'date'
160
+ }
161
+ ];
162
+
163
+ module.exports.defaultTaskFilter = {
164
+ bool: {
165
+ should: [
166
+ {
167
+ term: {
168
+ on_hold: false
169
+ }
170
+ },
171
+ {
172
+ bool: {
173
+ must_not: {
174
+ exists: {
175
+ field: 'on_hold'
176
+ }
177
+ }
178
+ }
179
+ }
180
+ ]
181
+ }
182
+ };
183
+
184
+ module.exports.buildTaskPipelineFilter = (filter) => {
185
+ switch (filter.type) {
186
+ case 'status':
187
+ return buildStatusFilter(filter);
188
+ case 'owner':
189
+ return buildOwnerFilter(filter);
190
+ case 'region':
191
+ return buildRegionFilter(filter);
192
+ case 'critical_path_stage':
193
+ return buildCriticalPathFilter(filter);
194
+ case 'on_hold':
195
+ return buildOnHoldFilter(filter);
196
+ // Always expected as is_equal condition
197
+ case 'path_age':
198
+ return buildPathAgeFilter(filter);
199
+ // Always expected as is_equal condition with array of task template ids
200
+ case 'task_templates':
201
+ let value = filter.value;
202
+
203
+ if (typeof value === 'string') {
204
+ value = value.split(';');
205
+ }
206
+
207
+ return {
208
+ bool: {
209
+ should: value.map((x) => {
210
+ return {
211
+ term: {
212
+ task_template_id: {
213
+ value: x
214
+ }
215
+ }
216
+ };
217
+ })
218
+ }
219
+ };
220
+ case 'dealinformation':
221
+ case 'contactinformation':
222
+ case 'ticketinformation':
223
+ return buildProjectFieldFilter(filter);
224
+ default:
225
+ // Task Fields
226
+ return buildTaskFieldFilter(filter);
227
+ }
228
+ };
@@ -0,0 +1,101 @@
1
+ module.exports = (filter) => {
2
+ switch (filter.condition) {
3
+ case 'is_empty':
4
+ return module.exports.isEmpty();
5
+ case 'is_not_empty':
6
+ return module.exports.isNotEmpty();
7
+ case 'is_equal':
8
+ return module.exports.isEqual(filter);
9
+ case 'not_equal':
10
+ return module.exports.isNotEqual(filter);
11
+ case 'is_any_of':
12
+ return module.exports.isAnyOf(filter); // if is any, means all tasks that have value
13
+ default:
14
+ return null;
15
+ }
16
+ };
17
+
18
+ module.exports.isEmpty = () => {
19
+ return {
20
+ bool: {
21
+ must_not: [
22
+ {
23
+ exists: {
24
+ field: 'on_hold'
25
+ }
26
+ }
27
+ ]
28
+ }
29
+ };
30
+ };
31
+
32
+ module.exports.isNotEmpty = () => {
33
+ return {
34
+ bool: {
35
+ must: [
36
+ {
37
+ exists: {
38
+ field: 'on_hold'
39
+ }
40
+ }
41
+ ]
42
+ }
43
+ };
44
+ };
45
+
46
+ module.exports.isEqual = (filter) => {
47
+ return {
48
+ bool: {
49
+ must: [
50
+ {
51
+ term: {
52
+ on_hold: {
53
+ value: filter.value === 'Yes'
54
+ }
55
+ }
56
+ }
57
+ ]
58
+ }
59
+ };
60
+ };
61
+
62
+ module.exports.isNotEqual = (filter) => {
63
+ return {
64
+ bool: {
65
+ must_not: [
66
+ {
67
+ term: {
68
+ on_hold: {
69
+ value: filter.value === 'Yes'
70
+ }
71
+ }
72
+ }
73
+ ]
74
+ }
75
+ };
76
+ };
77
+
78
+ module.exports.isAnyOf = (filter) => {
79
+ let value = filter.value;
80
+
81
+ if (typeof value === 'string') {
82
+ value = value.split(';');
83
+ }
84
+
85
+ const should = [];
86
+ value.forEach((x) => {
87
+ should.push({
88
+ term: {
89
+ on_hold: {
90
+ value: x === 'Yes'
91
+ }
92
+ }
93
+ });
94
+ });
95
+
96
+ return {
97
+ bool: {
98
+ should
99
+ }
100
+ };
101
+ };
@@ -0,0 +1,148 @@
1
+ const { validate: isUuid } = require('uuid');
2
+
3
+ module.exports = (filter) => {
4
+ switch (filter.condition) {
5
+ case 'is_empty':
6
+ return module.exports.isEmpty();
7
+ case 'is_not_empty':
8
+ return module.exports.isNotEmpty();
9
+ case 'is_equal':
10
+ return module.exports.isEqual(filter);
11
+ case 'not_equal':
12
+ return module.exports.isNotEqual(filter);
13
+ case 'is_any_of':
14
+ return module.exports.isAnyOf(filter);
15
+ default:
16
+ return null;
17
+ }
18
+ };
19
+
20
+ module.exports.isEmpty = () => {
21
+ return {
22
+ bool: {
23
+ should: [
24
+ {
25
+ bool: {
26
+ must: [
27
+ {
28
+ term: {
29
+ user_id: ''
30
+ }
31
+ },
32
+ {
33
+ term: {
34
+ team_id: ''
35
+ }
36
+ }
37
+ ]
38
+ }
39
+ },
40
+ {
41
+ bool: {
42
+ must_not: [
43
+ {
44
+ exists: {
45
+ field: 'user_id'
46
+ }
47
+ },
48
+ {
49
+ exists: {
50
+ field: 'team_id'
51
+ }
52
+ }
53
+ ]
54
+ }
55
+ }
56
+ ]
57
+ }
58
+ };
59
+ };
60
+
61
+ module.exports.isNotEmpty = (filter) => {
62
+ const isEmptyFilter = module.exports.isEmpty(filter);
63
+
64
+ return {
65
+ bool: {
66
+ must_not: isEmptyFilter
67
+ }
68
+ };
69
+ };
70
+
71
+ module.exports.isEqual = (filter) => {
72
+ const must = [];
73
+
74
+ // If uuid, treat as user id
75
+ if (isUuid(filter.value)) {
76
+ must.push({
77
+ term: {
78
+ user_id: {
79
+ value: filter.value
80
+ }
81
+ }
82
+ });
83
+ } else {
84
+ must.push({
85
+ term: {
86
+ team_id: {
87
+ value: filter.value
88
+ }
89
+ }
90
+ });
91
+ }
92
+
93
+ return {
94
+ bool: {
95
+ must
96
+ }
97
+ };
98
+ };
99
+
100
+ module.exports.isAnyOf = (filter) => {
101
+ let value = filter.value;
102
+
103
+ if (typeof value === 'string') {
104
+ value = value.split(';');
105
+ }
106
+
107
+ const should = [];
108
+ value.forEach((x) => {
109
+ // If uuid, treat as user id
110
+ if (isUuid(x)) {
111
+ should.push({
112
+ term: {
113
+ user_id: {
114
+ value: x
115
+ }
116
+ }
117
+ });
118
+ } else {
119
+ should.push({
120
+ term: {
121
+ team_id: {
122
+ value: x
123
+ }
124
+ }
125
+ });
126
+ }
127
+ });
128
+
129
+ return {
130
+ bool: {
131
+ should
132
+ }
133
+ };
134
+ };
135
+
136
+ module.exports.isNotEqual = (filter) => {
137
+ const equalFilter = module.exports.isEqual(filter);
138
+
139
+ if (equalFilter) {
140
+ return {
141
+ bool: {
142
+ must_not: equalFilter
143
+ }
144
+ };
145
+ }
146
+
147
+ return null;
148
+ };
@@ -0,0 +1,18 @@
1
+ module.exports = (filter) => {
2
+ switch (filter.condition) {
3
+ case 'is_equal':
4
+ return module.exports.isEqual(filter);
5
+ default:
6
+ return null;
7
+ }
8
+ };
9
+
10
+ module.exports.isEqual = (filter) => {
11
+ return {
12
+ term: {
13
+ 'critical_path.color_id': {
14
+ value: filter.value
15
+ }
16
+ }
17
+ };
18
+ };
@@ -0,0 +1,82 @@
1
+ module.exports = (filter) => {
2
+ switch (filter.condition) {
3
+ case 'is_empty':
4
+ return module.exports.isEmpty();
5
+ case 'is_not_empty':
6
+ return module.exports.isNotEmpty();
7
+ case 'is_equal':
8
+ return module.exports.isEqual(filter);
9
+ case 'not_equal':
10
+ return module.exports.isNotEqual(filter);
11
+ default:
12
+ return null;
13
+ }
14
+ };
15
+
16
+ module.exports.isEmpty = () => {
17
+ return {
18
+ bool: {
19
+ must_not: [
20
+ {
21
+ exists: {
22
+ field: 'region_id'
23
+ }
24
+ }
25
+ ]
26
+ }
27
+ };
28
+ };
29
+
30
+ module.exports.isNotEmpty = () => {
31
+ return {
32
+ bool: {
33
+ must: [
34
+ {
35
+ exists: {
36
+ field: 'region_id'
37
+ }
38
+ }
39
+ ]
40
+ }
41
+ };
42
+ };
43
+
44
+ module.exports.isEqual = (filter) => {
45
+ let value = filter.value;
46
+
47
+ if (typeof value === 'string') {
48
+ value = value.split(';');
49
+ }
50
+
51
+ return {
52
+ bool: {
53
+ should: value.map((value) => {
54
+ if (String(value).toLowerCase() === 'is_empty') {
55
+ return module.exports.isEmpty();
56
+ }
57
+
58
+ return {
59
+ term: {
60
+ region_id: {
61
+ value
62
+ }
63
+ }
64
+ };
65
+ })
66
+ }
67
+ };
68
+ };
69
+
70
+ module.exports.isNotEqual = (filter) => {
71
+ const equalFilter = module.exports.isEqual(filter);
72
+
73
+ if (equalFilter) {
74
+ return {
75
+ bool: {
76
+ must_not: equalFilter
77
+ }
78
+ };
79
+ }
80
+
81
+ return null;
82
+ };