@tiledesk/tiledesk-server 2.19.12 → 2.19.14
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 +7 -0
- package/app.js +3 -0
- package/channels/chat21/chat21WebHook.js +13 -2
- package/docs/activities-client.md +864 -0
- package/event/requestEvent.js +14 -0
- package/jobs.js +1 -0
- package/jobsManager.js +2 -0
- package/models/dataTable.js +64 -0
- package/package.json +2 -2
- package/pubmodules/activities/activityArchiver.js +699 -377
- package/pubmodules/activities/activityMessageUtil.js +336 -0
- package/pubmodules/activities/index.js +1 -1
- package/pubmodules/activities/models/activity.js +99 -2
- package/pubmodules/activities/routes/activity.js +114 -144
- package/pubmodules/messageActions/messageActionsInterceptor.js +15 -2
- package/pubmodules/queue/reconnect.js +307 -2
- package/pubmodules/rules/conciergeBot.js +7 -1
- package/pubmodules/trigger/rulesTrigger.js +33 -5
- package/routes/dataTable.js +280 -0
- package/routes/faq_kb.js +24 -1
- package/routes/kb.js +90 -2
- package/routes/project_user.js +66 -17
- package/routes/request.js +20 -8
- package/services/chatbotService.js +6 -3
- package/services/dataTableService.js +545 -0
- package/services/requestService.js +180 -27
- package/test/dataTablesRoute.test.js +844 -0
- package/test/faqkbRoute.js +1 -0
- package/test/kbRoute.js +59 -0
- package/utils/activityActorUtil.js +167 -0
- package/utils/assignmentContextUtil.js +283 -0
- package/utils/dataTableBsonUtils.js +12 -0
- package/utils/dataTableUtils.js +353 -0
- package/utils/projectUserUpdateContextUtil.js +325 -0
|
@@ -1,182 +1,147 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
const express = require('express');
|
|
2
|
+
const router = express.Router();
|
|
3
|
+
const Activity = require("../models/activity");
|
|
4
|
+
const activityMessageUtil = require('../activityMessageUtil');
|
|
5
|
+
const winston = require('../../../config/winston');
|
|
6
|
+
const moment = require('moment');
|
|
7
|
+
const ObjectId = require('mongoose').Types.ObjectId;
|
|
7
8
|
|
|
8
9
|
csv = require('csv-express');
|
|
9
10
|
csv.separator = ';';
|
|
10
|
-
// csv = require('csv-express');
|
|
11
|
-
// csv.separator = ';';
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
// router.post('/', function (req, res) {
|
|
15
|
-
|
|
16
|
-
// winston.debug(req.body);
|
|
17
|
-
// winston.debug("req.user", req.user);
|
|
18
|
-
|
|
19
|
-
// var newLead = new Lead({
|
|
20
|
-
// fullname: req.body.fullname,
|
|
21
|
-
// lead_id: req.body.lead_id,
|
|
22
|
-
// email: req.body.email,
|
|
23
|
-
// id_project: req.projectid,
|
|
24
|
-
// createdBy: req.user.id,
|
|
25
|
-
// updatedBy: req.user.id
|
|
26
|
-
// });
|
|
27
|
-
|
|
28
|
-
// newLead.save(function (err, savedLead) {
|
|
29
|
-
// if (err) {
|
|
30
|
-
// winston.debug('--- > ERROR ', err)
|
|
31
|
-
// return res.status(500).send({ success: false, msg: 'Error saving object.' });
|
|
32
|
-
// }
|
|
33
|
-
// res.json(savedLead);
|
|
34
|
-
// });
|
|
35
|
-
// });
|
|
36
|
-
|
|
37
|
-
// router.get('/:leadid', function (req, res) {
|
|
38
|
-
// winston.debug(req.body);
|
|
39
|
-
|
|
40
|
-
// Lead.findById(req.params.leadid, function (err, lead) {
|
|
41
|
-
// if (err) {
|
|
42
|
-
// return res.status(500).send({ success: false, msg: 'Error getting object.' });
|
|
43
|
-
// }
|
|
44
|
-
// if (!lead) {
|
|
45
|
-
// return res.status(404).send({ success: false, msg: 'Object not found.' });
|
|
46
|
-
// }
|
|
47
|
-
// res.json(lead);
|
|
48
|
-
// });
|
|
49
|
-
// });
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
router.get('/', function (req, res) {
|
|
54
|
-
var limit = 40; // Number of activities per page
|
|
55
|
-
var page = 0;
|
|
56
11
|
|
|
57
|
-
|
|
58
|
-
|
|
12
|
+
const DEFAULT_ACTIVITY_LIMIT = 40;
|
|
13
|
+
const LIST_MAX_ACTIVITY_LIMIT = 100;
|
|
14
|
+
const CHART_MAX_ACTIVITY_LIMIT = 1000;
|
|
15
|
+
|
|
16
|
+
function isChartView(query) {
|
|
17
|
+
return query && (query.chart === 'true' || query.chart === true || query.chart === '1');
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function resolveActivityQueryLimit(query) {
|
|
21
|
+
const isChart = isChartView(query);
|
|
22
|
+
const parsedLimit = parseInt(query && query.limit, 10);
|
|
23
|
+
const requestedLimit = Number.isFinite(parsedLimit) && parsedLimit > 0
|
|
24
|
+
? parsedLimit
|
|
25
|
+
: DEFAULT_ACTIVITY_LIMIT;
|
|
26
|
+
|
|
27
|
+
if (isChart) {
|
|
28
|
+
if (requestedLimit > CHART_MAX_ACTIVITY_LIMIT) {
|
|
29
|
+
return {
|
|
30
|
+
limit: CHART_MAX_ACTIVITY_LIMIT,
|
|
31
|
+
requestedLimit: requestedLimit,
|
|
32
|
+
isChart: true,
|
|
33
|
+
limitWarning: 'Limit exceeded the maximum allowed value of 1000. Only the first 1000 matching activities are returned.'
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
return {
|
|
37
|
+
limit: requestedLimit,
|
|
38
|
+
requestedLimit: requestedLimit,
|
|
39
|
+
isChart: true,
|
|
40
|
+
limitWarning: null
|
|
41
|
+
};
|
|
59
42
|
}
|
|
60
43
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
44
|
+
const limit = Math.min(requestedLimit, LIST_MAX_ACTIVITY_LIMIT);
|
|
45
|
+
return {
|
|
46
|
+
limit: limit,
|
|
47
|
+
requestedLimit: requestedLimit,
|
|
48
|
+
isChart: false,
|
|
49
|
+
limitWarning: null
|
|
50
|
+
};
|
|
51
|
+
}
|
|
64
52
|
|
|
65
|
-
|
|
53
|
+
router.get('/', async (req, res) => {
|
|
54
|
+
|
|
55
|
+
let id_project = req.projectid;
|
|
56
|
+
const limitConfig = resolveActivityQueryLimit(req.query);
|
|
57
|
+
let limit = limitConfig.limit;
|
|
58
|
+
let page = parseInt(req.query.page) || 0;
|
|
59
|
+
let skip = page * limit;
|
|
66
60
|
|
|
67
61
|
|
|
68
|
-
var query = { "id_project": req.projectid };
|
|
69
62
|
|
|
63
|
+
let query = { id_project: id_project };
|
|
70
64
|
|
|
71
|
-
/**
|
|
72
|
-
* DATE RANGE */
|
|
73
65
|
if (req.query.start_date && req.query.end_date) {
|
|
74
|
-
winston.
|
|
75
|
-
winston.debug('Activity ROUTE - REQ QUERY end_date ', req.query.end_date);
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* USING MOMENT */
|
|
79
|
-
var startDate = moment(req.query.start_date, 'DD/MM/YYYY').format('YYYY-MM-DD');
|
|
80
|
-
var endDate = moment(req.query.end_date, 'DD/MM/YYYY').format('YYYY-MM-DD');
|
|
66
|
+
winston.verbose('(ActivityRoute) start_date and end_date provided: ' + req.query.start_date + ' - ' + req.query.end_date);
|
|
81
67
|
|
|
82
|
-
|
|
83
|
-
|
|
68
|
+
const startDate = moment(req.query.start_date, 'DD/MM/YYYY')
|
|
69
|
+
.startOf('day')
|
|
70
|
+
.toDate();
|
|
84
71
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
var endDate_plusOneDay = newdate.setDate(newdate.getDate() + 1);
|
|
89
|
-
winston.debug('Activity ROUTE - REQ QUERY FORMATTED END DATE + 1 DAY ', endDate_plusOneDay);
|
|
90
|
-
// var endDate_plusOneDay = moment('2018-09-03').add(1, 'd')
|
|
91
|
-
// var endDate_plusOneDay = endDate.add(1).day();
|
|
92
|
-
// var toDate = new Date(Date.parse(endDate_plusOneDay)).toISOString()
|
|
72
|
+
const endDate = moment(req.query.end_date, 'DD/MM/YYYY')
|
|
73
|
+
.endOf('day')
|
|
74
|
+
.toDate();
|
|
93
75
|
|
|
94
|
-
query.createdAt = { $gte:
|
|
95
|
-
winston.debug('Activity ROUTE - QUERY CREATED AT ', query.createdAt);
|
|
76
|
+
query.createdAt = { $gte: startDate, $lte: endDate };
|
|
96
77
|
|
|
97
78
|
} else if (req.query.start_date && !req.query.end_date) {
|
|
98
|
-
winston.
|
|
99
|
-
var startDate = moment(req.query.start_date, 'DD/MM/YYYY').format('YYYY-MM-DD');
|
|
79
|
+
winston.verbose('(ActivityRoute) start_date provided: ' + req.query.start_date);
|
|
100
80
|
|
|
101
|
-
|
|
102
|
-
|
|
81
|
+
const startDate = moment(req.query.start_date, 'DD/MM/YYYY')
|
|
82
|
+
.startOf('day')
|
|
83
|
+
.toDate();
|
|
84
|
+
|
|
85
|
+
query.createdAt = { $gte: startDate };
|
|
103
86
|
}
|
|
104
87
|
|
|
105
88
|
if (req.query.agent_id) {
|
|
106
|
-
|
|
89
|
+
// involvedUserIds covers actor, target user and related user for new records.
|
|
90
|
+
// The other two clauses keep backward compatibility with legacy records.
|
|
107
91
|
query["$or"] = [
|
|
108
|
-
{ "
|
|
92
|
+
{ "involvedUserIds": req.query.agent_id },
|
|
93
|
+
{ "target.object.id_user._id": req.query.agent_id },
|
|
109
94
|
{ "actor.id": req.query.agent_id }
|
|
110
95
|
];
|
|
111
|
-
|
|
112
|
-
// query["$or"] = [
|
|
113
|
-
// { $or: [{"target.object.id_user._id": new ObjectId(req.query.agent_id) }, { "actor.id": new ObjectId(req.query.agent_id) }]}
|
|
114
|
-
// ];
|
|
115
96
|
}
|
|
116
97
|
|
|
117
98
|
if (req.query.activities) {
|
|
118
|
-
|
|
99
|
+
query.verb = {
|
|
100
|
+
$in: req.query.activities.split(',')
|
|
101
|
+
};
|
|
102
|
+
}
|
|
119
103
|
|
|
120
|
-
|
|
104
|
+
let direction = parseInt(req.query.direction) || -1;
|
|
105
|
+
let sortField = req.query.sort || "createdAt";
|
|
121
106
|
|
|
122
|
-
|
|
123
|
-
|
|
107
|
+
let sortQuery = {};
|
|
108
|
+
sortQuery[sortField] = direction;
|
|
124
109
|
|
|
125
|
-
|
|
126
|
-
// query.verb = ['PROJECT_USER_DELETE','PROJECT_USER_INVITE']
|
|
127
|
-
}
|
|
110
|
+
winston.verbose('(ActivityRoute) Find query: ', query)
|
|
128
111
|
|
|
112
|
+
try {
|
|
113
|
+
let activities = await Activity.find(query)
|
|
114
|
+
.skip(skip)
|
|
115
|
+
.limit(limit)
|
|
116
|
+
.sort(sortQuery)
|
|
117
|
+
.lean()
|
|
118
|
+
.exec();
|
|
129
119
|
|
|
130
|
-
|
|
131
|
-
if (req.query.direction) {
|
|
132
|
-
direction = req.query.direction;
|
|
133
|
-
}
|
|
134
|
-
winston.debug("direction", direction);
|
|
120
|
+
let totalRowCount = await Activity.countDocuments(query);
|
|
135
121
|
|
|
136
|
-
|
|
137
|
-
if (req.query.sort) {
|
|
138
|
-
sortField = req.query.sort;
|
|
139
|
-
}
|
|
140
|
-
winston.debug("sortField", sortField);
|
|
122
|
+
activities = activities.map(activityMessageUtil.enrichActivityWithMessage);
|
|
141
123
|
|
|
142
|
-
|
|
143
|
-
|
|
124
|
+
let objectToReturn = {
|
|
125
|
+
perPage: limit,
|
|
126
|
+
count: totalRowCount,
|
|
127
|
+
activities: activities
|
|
128
|
+
};
|
|
144
129
|
|
|
145
|
-
|
|
130
|
+
if (limitConfig.isChart) {
|
|
131
|
+
objectToReturn.chart = true;
|
|
132
|
+
}
|
|
146
133
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
sort(sortQuery).
|
|
151
|
-
exec(function (err, activities) {
|
|
152
|
-
if (err) {
|
|
153
|
-
winston.error('Activity ROUTE - REQUEST FIND ERR ', err)
|
|
154
|
-
return (err);
|
|
155
|
-
}
|
|
134
|
+
if (limitConfig.limitWarning) {
|
|
135
|
+
objectToReturn.limitWarning = limitConfig.limitWarning;
|
|
136
|
+
}
|
|
156
137
|
|
|
157
|
-
|
|
158
|
-
if (err) {
|
|
159
|
-
winston.error('Activity ROUTE - REQUEST FIND ERR ', err)
|
|
160
|
-
return (err);
|
|
161
|
-
}
|
|
138
|
+
return res.status(200).send(objectToReturn);
|
|
162
139
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
};
|
|
168
|
-
winston.debug('Activity ROUTE - objectToReturn ', objectToReturn);
|
|
169
|
-
|
|
170
|
-
objectToReturn.activities.forEach(activity => {
|
|
171
|
-
winston.debug('Activity ROUTE - activity.target ', activity.target);
|
|
172
|
-
if (activity.target && activity.target.object && activity.target.object.id_user) {
|
|
173
|
-
winston.debug('Activity ROUTE - *** 9-+activity.target.id_user ', activity.target.object.id_user._id);
|
|
174
|
-
}
|
|
175
|
-
});
|
|
140
|
+
} catch (error) {
|
|
141
|
+
winston.error('(ActivityRoute) Find query error: ', error)
|
|
142
|
+
return res.status(500).send({ success: false, msg: 'Error getting activities.' });
|
|
143
|
+
}
|
|
176
144
|
|
|
177
|
-
return res.json(objectToReturn);
|
|
178
|
-
});
|
|
179
|
-
});
|
|
180
145
|
});
|
|
181
146
|
|
|
182
147
|
// DOWNLOAD ACTIVITIES AS CSV
|
|
@@ -234,6 +199,7 @@ router.get('/csv', function (req, res) {
|
|
|
234
199
|
if (req.query.agent_id) {
|
|
235
200
|
winston.debug('req.query.agent', req.query.agent_id);
|
|
236
201
|
query["$or"] = [
|
|
202
|
+
{ "involvedUserIds": req.query.agent_id },
|
|
237
203
|
{ "target.object.id_user._id": new ObjectId(req.query.agent_id) },
|
|
238
204
|
{ "actor.id": req.query.agent_id }
|
|
239
205
|
];
|
|
@@ -575,6 +541,7 @@ router.get('/csv', function (req, res) {
|
|
|
575
541
|
// if (lang) {
|
|
576
542
|
winston.debug('buildCsv lang: ', lang);
|
|
577
543
|
|
|
544
|
+
var message = activityMessageUtil.buildDefaultActivityMessage(activity) || '';
|
|
578
545
|
var actor_name = '';
|
|
579
546
|
var target_fullname = '';
|
|
580
547
|
if (activity.actor) {
|
|
@@ -597,21 +564,24 @@ router.get('/csv', function (req, res) {
|
|
|
597
564
|
}
|
|
598
565
|
|
|
599
566
|
if (activity.verb === "PROJECT_USER_UPDATE") {
|
|
600
|
-
|
|
567
|
+
message = buildMsg_PROJECT_USER_UPDATE(actor_name, target_fullname, lang, activity)
|
|
601
568
|
}
|
|
602
569
|
|
|
603
570
|
if (activity.verb === "PROJECT_USER_DELETE") {
|
|
604
|
-
|
|
571
|
+
message = buildMsg_PROJECT_USER_DELETE(actor_name, target_fullname, lang)
|
|
605
572
|
}
|
|
606
573
|
|
|
607
574
|
if (activity.verb === "PROJECT_USER_INVITE") {
|
|
608
|
-
|
|
575
|
+
message = buildMsg_PROJECT_USER_INVITE(actor_name, target_fullname, lang, activity)
|
|
609
576
|
}
|
|
610
577
|
|
|
611
578
|
if (activity.verb === "REQUEST_CREATE") {
|
|
612
|
-
|
|
579
|
+
message = buildMsg_REQUEST_CREATE(lang, activity)
|
|
613
580
|
}
|
|
614
581
|
|
|
582
|
+
if (!message) {
|
|
583
|
+
message = activityMessageUtil.buildDefaultActivityMessage(activity) || '';
|
|
584
|
+
}
|
|
615
585
|
|
|
616
586
|
if (activity.actionObj && activity.actionObj.email) {
|
|
617
587
|
var actionObj_email = activity.actionObj.email;
|
|
@@ -8,6 +8,7 @@ var requestService = require('../../services/requestService');
|
|
|
8
8
|
var i8nUtil = require("../../utils/i8nUtil");
|
|
9
9
|
var MessageConstants = require("../../models/messageConstants");
|
|
10
10
|
var BotFromParticipant = require("../../utils/botFromParticipant");
|
|
11
|
+
var assignmentContextUtil = require('../../utils/assignmentContextUtil');
|
|
11
12
|
|
|
12
13
|
class MessageActionsInterceptor {
|
|
13
14
|
|
|
@@ -98,7 +99,14 @@ class MessageActionsInterceptor {
|
|
|
98
99
|
|
|
99
100
|
// route(request_id, departmentid, id_project, nobot) {
|
|
100
101
|
// se \agent ma nessuno opertore online non toglie il bot
|
|
101
|
-
requestService.route(
|
|
102
|
+
requestService.route(
|
|
103
|
+
request.request_id,
|
|
104
|
+
request.department,
|
|
105
|
+
request.id_project,
|
|
106
|
+
true,
|
|
107
|
+
undefined,
|
|
108
|
+
assignmentContextUtil.buildInternalOptions('system', 'auto')
|
|
109
|
+
).then(function(routedRequest) {
|
|
102
110
|
winston.debug("routedRequest: ", routedRequest);
|
|
103
111
|
|
|
104
112
|
// messageService.send(
|
|
@@ -119,7 +127,12 @@ class MessageActionsInterceptor {
|
|
|
119
127
|
//route(request_id, departmentid, id_project) {
|
|
120
128
|
//TODO USE FINALLY?
|
|
121
129
|
|
|
122
|
-
requestService.reroute(
|
|
130
|
+
requestService.reroute(
|
|
131
|
+
request.request_id,
|
|
132
|
+
request.id_project,
|
|
133
|
+
true,
|
|
134
|
+
assignmentContextUtil.buildInternalOptions('system', 'auto')
|
|
135
|
+
).then(function() {
|
|
123
136
|
|
|
124
137
|
// messageService.send(
|
|
125
138
|
// 'system',
|