@chat21/chat21-ionic 3.4.28 → 3.4.29-rc1
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 +111 -5
- package/angular.json +1 -0
- package/package.json +1 -1
- package/src/app/app.component.html +3 -1
- package/src/app/app.component.ts +71 -10
- package/src/app/components/canned-response/canned-response.component.html +26 -23
- package/src/app/components/canned-response/canned-response.component.scss +0 -2
- package/src/app/components/canned-response/canned-response.component.ts +3 -1
- package/src/app/components/conversation-detail/message-text-area/message-text-area.component.html +24 -1
- package/src/app/components/conversation-detail/message-text-area/message-text-area.component.scss +30 -0
- package/src/app/components/conversation-detail/message-text-area/message-text-area.component.ts +29 -7
- package/src/app/components/conversation-info/info-content/info-content.component.ts +2 -2
- package/src/app/components/conversation-info/info-group/info-group.component.ts +23 -21
- package/src/app/components/conversations-list/header-conversations-list/header-conversations-list.component.html +1 -1
- package/src/app/components/conversations-list/header-conversations-list/header-conversations-list.component.ts +5 -1
- package/src/app/components/navbar/navbar.component.html +3 -3
- package/src/app/components/navbar/navbar.component.ts +29 -38
- package/src/app/components/project-item/project-item.component.ts +11 -11
- package/src/app/components/sidebar/sidebar.component.html +65 -45
- package/src/app/components/sidebar/sidebar.component.ts +110 -117
- package/src/app/components/sidebar-user-details/sidebar-user-details.component.html +2 -2
- package/src/app/components/sidebar-user-details/sidebar-user-details.component.ts +10 -7
- package/src/app/modals/create-ticket/create-ticket.page.ts +4 -2
- package/src/app/pages/contacts-directory/contacts-directory.page.scss +30 -25
- package/src/app/pages/conversation-detail/conversation-detail.page.html +7 -3
- package/src/app/pages/conversation-detail/conversation-detail.page.ts +89 -5
- package/src/app/pages/conversations-list/conversations-list.page.html +2 -0
- package/src/app/pages/conversations-list/conversations-list.page.scss +15 -4
- package/src/app/pages/conversations-list/conversations-list.page.ts +40 -2
- package/src/app/pages/unassigned-conversations/unassigned-conversations.page.scss +15 -5
- package/src/app/services/global-settings/global-settings.service.ts +11 -3
- package/src/app/services/nav-proxy.service.ts +0 -1
- package/src/app/services/project_users/project-users.service.spec.ts +16 -0
- package/src/app/services/project_users/project-users.service.ts +63 -0
- package/src/app/services/tiledesk/tiledesk.service.ts +0 -16
- package/src/app/services/triggerEvents/triggerEvents.ts +28 -0
- package/src/app/services/websocket/websocket-js.ts +59 -534
- package/src/app/services/websocket/websocket-js_old.ts +578 -0
- package/src/app/services/websocket/websocket.service.ts +9 -10
- package/src/app/services/websocket/websocket.worker.ts +242 -0
- package/src/app/shared/shared.module.ts +11 -2
- package/src/app/utils/globals.ts +2 -0
- package/src/app/utils/permissions.constants.ts +138 -0
- package/src/app/utils/project-utils.ts +2 -2
- package/src/app/utils/utils.ts +18 -1
- package/src/assets/i18n/ar.json +11 -1
- package/src/assets/i18n/az.json +11 -1
- package/src/assets/i18n/de.json +11 -1
- package/src/assets/i18n/en.json +11 -1
- package/src/assets/i18n/es.json +11 -1
- package/src/assets/i18n/fr.json +11 -1
- package/src/assets/i18n/it.json +13 -3
- package/src/assets/i18n/kk.json +11 -1
- package/src/assets/i18n/pt.json +11 -1
- package/src/assets/i18n/ru.json +11 -1
- package/src/assets/i18n/sr.json +11 -1
- package/src/assets/i18n/sv.json +11 -1
- package/src/assets/i18n/tr.json +11 -1
- package/src/assets/i18n/uk.json +11 -1
- package/src/assets/i18n/uz.json +12 -1
- package/src/assets/js/agentDesktop-sdk.js +55 -0
- package/src/assets/js/chat21client.js +36 -0
- package/src/assets/js/mqtt-keepalive-worker.js +53 -0
- package/src/assets/test.html +5 -2
- package/src/chat-config-template.json +1 -0
- package/src/chat-config.json +1 -0
- package/src/chat21-core/models/projectUsers.ts +19 -0
- package/src/chat21-core/providers/firebase/firebase-conversation-handler.ts +1 -1
- package/src/chat21-core/providers/mqtt/mqtt-conversation-handler.ts +1 -1
- package/src/chat21-core/providers/tiledesk/tiledesk-auth.service.ts +3 -0
- package/src/chat21-core/utils/utils.ts +16 -2
package/CHANGELOG.md
CHANGED
|
@@ -8,11 +8,98 @@
|
|
|
8
8
|
### **Copyrigth**:
|
|
9
9
|
*Tiledesk SRL*
|
|
10
10
|
|
|
11
|
-
# 3.4.
|
|
11
|
+
# 3.4.29-rc1
|
|
12
|
+
- **bug-fixed**: web (Chrome >= 144) `ion-content` stopped scrolling on some pages (conversation list / contacts directory / unassigned); removed the forced `--overflow: hidden` and handled scrolling on Ionic’s internal scroll container via `ion-content::part(scroll)`
|
|
13
|
+
|
|
14
|
+
# 3.4.28-rc1
|
|
12
15
|
- **bug-fixed**: cannot do project subscription if last_project object is not a project_user obj
|
|
13
16
|
|
|
14
|
-
# 3.4.27
|
|
15
|
-
- **bug-fixed**:
|
|
17
|
+
# 3.4.27-rc26
|
|
18
|
+
- **bug-fixed**: wss push requests twice
|
|
19
|
+
|
|
20
|
+
# 3.4.27-rc25
|
|
21
|
+
- **bug-fixed**: projectUserService is not initialized
|
|
22
|
+
|
|
23
|
+
# 3.4.27-rc24
|
|
24
|
+
- **added**: implementation of multiple message in wss onmessage
|
|
25
|
+
|
|
26
|
+
# 3.4.27-rc23
|
|
27
|
+
- **added**: keepAlive worker for MQTT connection
|
|
28
|
+
|
|
29
|
+
# 3.4.27-rc22
|
|
30
|
+
- **added**: new WsWorker to manage iframe chrome throttling while tab is in background or hidden
|
|
31
|
+
|
|
32
|
+
# 3.4.27-rc21
|
|
33
|
+
- **changed**: new wss reconnect and timeout keepalive
|
|
34
|
+
- **bug-fixed**: cannot route if senderFullaname contains /
|
|
35
|
+
|
|
36
|
+
# 3.4.27-rc20
|
|
37
|
+
- **added**: onOpenTicketExternally event in triggerEvents service
|
|
38
|
+
|
|
39
|
+
# 3.4.27-rc19
|
|
40
|
+
- **added**: window.parent['openTicketOnHDA']
|
|
41
|
+
|
|
42
|
+
# 3.4.27-rc18
|
|
43
|
+
- **added**: triggerOnUpdateNewConversationBadge to update conversation badge count in parent component
|
|
44
|
+
|
|
45
|
+
# 3.4.27-rc17
|
|
46
|
+
- **bug-fixed**: setNotification not called when click on a conversation
|
|
47
|
+
|
|
48
|
+
# 3.4.27-rc16
|
|
49
|
+
- **bug-fixed**: setNotification not called when resolve a conversation
|
|
50
|
+
|
|
51
|
+
# 3.4.27-rc15
|
|
52
|
+
- **changed**: /images with /img in assets folder
|
|
53
|
+
|
|
54
|
+
# 3.4.27-rc14
|
|
55
|
+
- **added**: DISPLAY_EDIT_PROFILE brand variable
|
|
56
|
+
- **bug-fixed**: emojii is sent also if is not allowed
|
|
57
|
+
|
|
58
|
+
# 3.4.27-rc13
|
|
59
|
+
- **added**: ability to mantain logout parameter when redirect to dashboard urls from sidebar component
|
|
60
|
+
|
|
61
|
+
# 3.4.27-rc12
|
|
62
|
+
- **added**: ability to manage logOut option in sidebar-user-detail with tiledesk_logOut url query params
|
|
63
|
+
|
|
64
|
+
# 3.4.27-rc11
|
|
65
|
+
- **bug-fixed**: fixed infinite loading in contact list
|
|
66
|
+
|
|
67
|
+
# 3.4.27-rc10
|
|
68
|
+
- **added**: ability to manage header-conversation-list with roles
|
|
69
|
+
- **bug-fixed**: members in group list not loaded
|
|
70
|
+
|
|
71
|
+
# 3.4.27-rc9
|
|
72
|
+
- **bug-fixed**: Scrolling to the last message when opening a conversation
|
|
73
|
+
- **bug-fixed**: Loading in the conversation list disabled when removing the last conversation
|
|
74
|
+
|
|
75
|
+
# 3.4.27-rc8
|
|
76
|
+
- **added**: ability to open ticket to external service
|
|
77
|
+
- **added**: ticketSection env var
|
|
78
|
+
|
|
79
|
+
# 3.4.27-rc7
|
|
80
|
+
- **bug-fixed**: Scrolling to the last message when opening a conversation
|
|
81
|
+
- **bug-fixed**: Loading in the conversation list disabled when removing the last conversation
|
|
82
|
+
|
|
83
|
+
# 3.4.27-rc6
|
|
84
|
+
- **bug-fixed**: user for dashboard app is incorrect
|
|
85
|
+
|
|
86
|
+
# 3.4.27-rc5
|
|
87
|
+
- **added**: managed roles in sidebar e navbar
|
|
88
|
+
- **bug-fixed**: projectId and supportMode url is not saved in localstorage
|
|
89
|
+
|
|
90
|
+
# 3.4.27-rc4
|
|
91
|
+
- **bug-fixed**: extractUrls function is not able to detect url start with www or without https/http
|
|
92
|
+
- **bug-fixed**: if message is sent with keydown, error on domain check is not showed
|
|
93
|
+
|
|
94
|
+
# 3.4.27-rc3
|
|
95
|
+
- **bug-fixed**: cannot set user availability if supportMode is enabled and tiledesk_projectID url params is set
|
|
96
|
+
|
|
97
|
+
# 3.4.27-rc2
|
|
98
|
+
- **bug-fixed**: cannede responses role
|
|
99
|
+
|
|
100
|
+
# 3.4.27-rc1
|
|
101
|
+
- **added**: managed canned responses with roles
|
|
102
|
+
- **changed**: name in info mesage
|
|
16
103
|
|
|
17
104
|
# 3.4.26 in PROD
|
|
18
105
|
|
|
@@ -22,6 +109,7 @@
|
|
|
22
109
|
# 3.4.26-rc1
|
|
23
110
|
- **added**: tiledesk_projectID query param to manage user status
|
|
24
111
|
- **added**: token to managane ticket feature
|
|
112
|
+
- **added**: getOsCode login into utils.ts
|
|
25
113
|
|
|
26
114
|
# 3.4.25 in PROD
|
|
27
115
|
- **changed**: pipe marked to support malicious text input
|
|
@@ -44,6 +132,24 @@
|
|
|
44
132
|
# 3.4.22 in PROD
|
|
45
133
|
- **added**: managed allowed_upload_extentions from project settings
|
|
46
134
|
|
|
135
|
+
# 3.4.21-rc6
|
|
136
|
+
- **added**: managed allowed_upload_extentions from project settings
|
|
137
|
+
|
|
138
|
+
# 3.4.21-rc5
|
|
139
|
+
- **added**: setConversation as read when agent click on it
|
|
140
|
+
|
|
141
|
+
# 3.4.21-rc4
|
|
142
|
+
- **added**: ability to init and decrement new conversation count badge
|
|
143
|
+
|
|
144
|
+
# 3.4.21-rc3
|
|
145
|
+
- **changed**: badge notification for agentDesktop
|
|
146
|
+
|
|
147
|
+
# 3.4.21-rc2
|
|
148
|
+
- **added**: count in newConversation handler event
|
|
149
|
+
|
|
150
|
+
# 3.4.21-rc1
|
|
151
|
+
- **added**: implement badge notification for agentDesktop sw when new conversation is assigned to logged agent
|
|
152
|
+
|
|
47
153
|
# 3.4.21 in PROD
|
|
48
154
|
|
|
49
155
|
# 3.4.20 in PROD
|
|
@@ -57,8 +163,8 @@
|
|
|
57
163
|
- **bug-fixed**: minor fix on ion-texarea element with allowed url domain
|
|
58
164
|
|
|
59
165
|
# 3.4.19-rc1
|
|
60
|
-
- added
|
|
61
|
-
- added
|
|
166
|
+
- **added**: ability to check for if emoji is allowd to be sent in message textarea
|
|
167
|
+
- **added**: ability to check for if url domain is allowd to be sent in message textarea
|
|
62
168
|
|
|
63
169
|
# 3.4.18 in PROD
|
|
64
170
|
|
package/angular.json
CHANGED
package/package.json
CHANGED
|
@@ -21,7 +21,9 @@
|
|
|
21
21
|
</div> -->
|
|
22
22
|
|
|
23
23
|
<div class="user-details-sidebar" [ngClass]="{'hide-sidebar': IS_ONLINE === false || IS_ON_MOBILE_DEVICE || SUPPORT_MODE === false}">
|
|
24
|
-
<app-sidebar-user-details
|
|
24
|
+
<app-sidebar-user-details
|
|
25
|
+
[logOut]="g?.logOut">
|
|
26
|
+
</app-sidebar-user-details>
|
|
25
27
|
</div>
|
|
26
28
|
|
|
27
29
|
<ion-split-pane when="md" contentId="main" [ngClass]="{'mobile': IS_ON_MOBILE_DEVICE, 'sidebar-hidden': IS_ON_MOBILE_DEVICE || SUPPORT_MODE === false}">
|
package/src/app/app.component.ts
CHANGED
|
@@ -44,6 +44,9 @@ import { conversationToMessage } from 'src/chat21-core/utils/utils-message';
|
|
|
44
44
|
import { ProjectService } from './services/projects/project.service';
|
|
45
45
|
import { ContactsService } from './services/contacts/contacts.service';
|
|
46
46
|
import { TiledeskService } from './services/tiledesk/tiledesk.service';
|
|
47
|
+
import { Project } from 'src/chat21-core/models/projects';
|
|
48
|
+
import { BRAND_BASE_INFO } from './utils/utils-resources';
|
|
49
|
+
import { ProjectUsersService } from './services/project_users/project-users.service';
|
|
47
50
|
|
|
48
51
|
@Component({
|
|
49
52
|
selector: 'app-root',
|
|
@@ -142,6 +145,7 @@ export class AppComponent implements OnInit {
|
|
|
142
145
|
/**TILEDESK SERVICES */
|
|
143
146
|
private tiledeskService: TiledeskService,
|
|
144
147
|
private projectService: ProjectService,
|
|
148
|
+
private projectUsersService: ProjectUsersService,
|
|
145
149
|
private contactsService: ContactsService
|
|
146
150
|
) {
|
|
147
151
|
|
|
@@ -168,6 +172,7 @@ export class AppComponent implements OnInit {
|
|
|
168
172
|
}, { capture: true });
|
|
169
173
|
}
|
|
170
174
|
|
|
175
|
+
|
|
171
176
|
listenChatAlreadyOpenWithoutParamsInMobileMode() {
|
|
172
177
|
this.events.subscribe('noparams:mobile', (isAlreadyOpenInMobileMode) => {
|
|
173
178
|
// console.log('[APP-COMP] Chat is Already Open In Mobile Mode ', isAlreadyOpenInMobileMode)
|
|
@@ -296,6 +301,10 @@ export class AppComponent implements OnInit {
|
|
|
296
301
|
this.zone = new NgZone({}); // a cosa serve?
|
|
297
302
|
|
|
298
303
|
this.SUPPORT_MODE = this.g.supportMode
|
|
304
|
+
this.logger.info('[APP-COMP] this.SUPPORT_MODE', this.SUPPORT_MODE)
|
|
305
|
+
|
|
306
|
+
BRAND_BASE_INFO['LOGOUT_ENABLED'] = this.g.logOut
|
|
307
|
+
this.logger.info('[APP-COMP] this.logOut', BRAND_BASE_INFO['LOGOUT_ENABLED'])
|
|
299
308
|
}
|
|
300
309
|
|
|
301
310
|
});
|
|
@@ -332,7 +341,7 @@ export class AppComponent implements OnInit {
|
|
|
332
341
|
|
|
333
342
|
listenToPostMsgs() {
|
|
334
343
|
window.addEventListener("message", (event) => {
|
|
335
|
-
this.logger.log("[APP-COMP] message event ", event);
|
|
344
|
+
// this.logger.log("[APP-COMP] message event ", event);
|
|
336
345
|
|
|
337
346
|
if (event && event.data && event.data.action && event.data.parameter) {
|
|
338
347
|
if (event.data.action === 'openJoinConversationModal') {
|
|
@@ -534,10 +543,10 @@ export class AppComponent implements OnInit {
|
|
|
534
543
|
this.statusBar.styleLightContent();
|
|
535
544
|
this.navService.init(this.sidebarNav, this.detailNav);
|
|
536
545
|
this.tiledeskAuthService.initialize(this.appConfigProvider.getConfig().apiUrl);
|
|
537
|
-
|
|
538
|
-
|
|
546
|
+
|
|
539
547
|
// this.currentUserService.initialize();
|
|
540
548
|
this.chatManager.initialize();
|
|
549
|
+
this.messagingAuthService.initialize();
|
|
541
550
|
this.presenceService.initialize(this.tenant);
|
|
542
551
|
this.typingService.initialize(this.tenant);
|
|
543
552
|
|
|
@@ -864,7 +873,8 @@ export class AppComponent implements OnInit {
|
|
|
864
873
|
// console.log('[APP-COMP] PLATFORM', PLATFORM_MOBILE, 'route.snapshot', this.route.snapshot);
|
|
865
874
|
if (!IDConv) {
|
|
866
875
|
this.logger.log('[APP-COMP] navigateByUrl -- conversations-list');
|
|
867
|
-
|
|
876
|
+
const queryString = window.location.search; // restituisce ad es. "?jwt=...&tiledesk_supportMode=false"
|
|
877
|
+
this.router.navigateByUrl('conversations-list' + queryString);
|
|
868
878
|
}
|
|
869
879
|
// this.router.navigateByUrl(pageUrl);
|
|
870
880
|
// this.navService.setRoot(ConversationListPage, {});
|
|
@@ -1115,13 +1125,19 @@ export class AppComponent implements OnInit {
|
|
|
1115
1125
|
if (conversation && conversation.is_new === true && this.isInitialized) {
|
|
1116
1126
|
this.manageTabNotification('conv_added', conversation.sound)
|
|
1117
1127
|
this.manageEventNewConversation(conversation)
|
|
1128
|
+
//UPDATE NOTIFICATION FOR NEW CONVERSATION COUNT
|
|
1129
|
+
this.triggerOnUpdateNewConversationBadge(this.conversationsHandlerService.countIsNew());
|
|
1118
1130
|
}
|
|
1119
1131
|
if(conversation) this.updateConversationsOnStorage()
|
|
1120
1132
|
});
|
|
1121
1133
|
|
|
1122
1134
|
this.conversationsHandlerService.conversationChanged.subscribe((conversation: ConversationModel) => {
|
|
1123
1135
|
// console.log('[APP-COMP] ***** subscribeConversationChanged conversation: ', conversation);
|
|
1124
|
-
if(conversation)
|
|
1136
|
+
if(conversation){
|
|
1137
|
+
this.updateConversationsOnStorage();
|
|
1138
|
+
//UPDATE NOTIFICATION FOR NEW CONVERSATION COUNT
|
|
1139
|
+
this.triggerOnUpdateNewConversationBadge(this.conversationsHandlerService.countIsNew());
|
|
1140
|
+
}
|
|
1125
1141
|
});
|
|
1126
1142
|
|
|
1127
1143
|
this.conversationsHandlerService.conversationChangedDetailed.subscribe((changes: {value: ConversationModel, previousValue: ConversationModel}) => {
|
|
@@ -1145,6 +1161,8 @@ export class AppComponent implements OnInit {
|
|
|
1145
1161
|
if(conversation) {
|
|
1146
1162
|
this.updateConversationsOnStorage();
|
|
1147
1163
|
this.segmentResolved(conversation);
|
|
1164
|
+
//UPDATE NOTIFICATION FOR NEW CONVERSATION COUNT
|
|
1165
|
+
this.triggerOnUpdateNewConversationBadge(this.conversationsHandlerService.countIsNew());
|
|
1148
1166
|
this.router.navigateByUrl('conversation-detail/'); //redirect to basePage
|
|
1149
1167
|
}
|
|
1150
1168
|
});
|
|
@@ -1178,6 +1196,7 @@ export class AppComponent implements OnInit {
|
|
|
1178
1196
|
this.chatManager.setCurrentUser(currentUser);
|
|
1179
1197
|
|
|
1180
1198
|
this.tiledeskService.initialize(serverBaseURL)
|
|
1199
|
+
this.projectUsersService.initialize(serverBaseURL)
|
|
1181
1200
|
this.projectService.initialize(serverBaseURL)
|
|
1182
1201
|
this.contactsService.initialize(serverBaseURL)
|
|
1183
1202
|
|
|
@@ -1185,11 +1204,14 @@ export class AppComponent implements OnInit {
|
|
|
1185
1204
|
this.events.publish('go:online', true);
|
|
1186
1205
|
// this.chatManager.startApp();
|
|
1187
1206
|
|
|
1207
|
+
|
|
1208
|
+
//INIT WEBSOCKET
|
|
1209
|
+
this.connetWebsocket(tiledeskToken)
|
|
1210
|
+
|
|
1188
1211
|
// ----------------------------------------------
|
|
1189
1212
|
// PUSH NOTIFICATIONS
|
|
1190
1213
|
// ----------------------------------------------
|
|
1191
1214
|
const pushEngine = this.appConfigProvider.getConfig().pushEngine
|
|
1192
|
-
|
|
1193
1215
|
if (currentUser) {
|
|
1194
1216
|
if (pushEngine && pushEngine !== 'none') {
|
|
1195
1217
|
this.notificationsService.getNotificationPermissionAndSaveToken(currentUser.uid);
|
|
@@ -1211,6 +1233,24 @@ export class AppComponent implements OnInit {
|
|
|
1211
1233
|
} catch (err) {
|
|
1212
1234
|
this.logger.error('[APP-COMP] -> error:', err);
|
|
1213
1235
|
}
|
|
1236
|
+
|
|
1237
|
+
// ----------------------------------------------
|
|
1238
|
+
// LAST PROJECT FROM URL
|
|
1239
|
+
// ----------------------------------------------
|
|
1240
|
+
if(this.g.projectID){
|
|
1241
|
+
this.projectService.getProjects().subscribe({ next: (projects: Project[]) => {
|
|
1242
|
+
const project = projects.find(prjct => prjct.id_project._id === this.g.projectID)
|
|
1243
|
+
if(project){
|
|
1244
|
+
this.logger.log('[APP-COMP] - GET PROJECT - project found with this.projectID', project);
|
|
1245
|
+
localStorage.setItem('last_project', JSON.stringify(project))
|
|
1246
|
+
this.events.publish('storage:last_project', project)
|
|
1247
|
+
}
|
|
1248
|
+
}, error: (error) => {
|
|
1249
|
+
this.logger.log('[APP-COMP] - GET PROJECT - project NOT found with this.projectID', this.g.projectID, error);
|
|
1250
|
+
}, complete: () => {
|
|
1251
|
+
|
|
1252
|
+
}});
|
|
1253
|
+
}
|
|
1214
1254
|
}
|
|
1215
1255
|
|
|
1216
1256
|
|
|
@@ -1251,9 +1291,21 @@ export class AppComponent implements OnInit {
|
|
|
1251
1291
|
}
|
|
1252
1292
|
|
|
1253
1293
|
goToDashboardLogin(){
|
|
1254
|
-
let DASHBOARD_URL = this.appConfigProvider.getConfig().dashboardUrl + '#/login'
|
|
1255
|
-
const myWindow = window.open(DASHBOARD_URL, '_self');
|
|
1256
|
-
myWindow.focus();
|
|
1294
|
+
// let DASHBOARD_URL = this.appConfigProvider.getConfig().dashboardUrl + '#/login'
|
|
1295
|
+
// const myWindow = window.open(DASHBOARD_URL, '_self');
|
|
1296
|
+
// myWindow.focus();
|
|
1297
|
+
}
|
|
1298
|
+
|
|
1299
|
+
connetWebsocket(tiledeskToken) {
|
|
1300
|
+
|
|
1301
|
+
this.logger.log('[WEBSOCKET-JS] connetWebsocket called in [PROJECT-ITEM] tiledeskToken ', tiledeskToken)
|
|
1302
|
+
const appconfig = this.appConfigProvider.getConfig();
|
|
1303
|
+
this.logger.log('[WEBSOCKET-JS] connetWebsocket called in [PROJECT-ITEM] wsUrl ', appconfig.wsUrl)
|
|
1304
|
+
const WS_URL = appconfig.wsUrl + '?token=' + tiledeskToken
|
|
1305
|
+
this.logger.log('[WEBSOCKET-JS] connetWebsocket called in [PROJECT-ITEM] wsUrl ', WS_URL)
|
|
1306
|
+
this.webSocketJs.init(
|
|
1307
|
+
WS_URL
|
|
1308
|
+
);
|
|
1257
1309
|
}
|
|
1258
1310
|
|
|
1259
1311
|
|
|
@@ -1352,7 +1404,8 @@ export class AppComponent implements OnInit {
|
|
|
1352
1404
|
|
|
1353
1405
|
subscribeConversationSelected= (conversation: ConversationModel) => {
|
|
1354
1406
|
if(conversation && conversation.is_new){
|
|
1355
|
-
this.audio_NewConv.pause()
|
|
1407
|
+
this.audio_NewConv.pause();
|
|
1408
|
+
this.conversationsHandlerService.setConversationRead(conversation.uid)
|
|
1356
1409
|
}
|
|
1357
1410
|
}
|
|
1358
1411
|
|
|
@@ -1428,6 +1481,9 @@ export class AppComponent implements OnInit {
|
|
|
1428
1481
|
this.logger.debug('[APP-COMP]-CONVS - INIT CONV CONVS 2', conversations)
|
|
1429
1482
|
this.events.publish('appcompSubscribeToConvs:loadingIsActive', false);
|
|
1430
1483
|
}
|
|
1484
|
+
|
|
1485
|
+
//INIT NOTIFICATION FOR NEW CONVERSATION COUNT
|
|
1486
|
+
this.triggerOnUpdateNewConversationBadge(this.conversationsHandlerService.countIsNew());
|
|
1431
1487
|
});
|
|
1432
1488
|
|
|
1433
1489
|
}
|
|
@@ -1710,6 +1766,11 @@ export class AppComponent implements OnInit {
|
|
|
1710
1766
|
this.triggerEvents.triggerOnInit(detailOBJ)
|
|
1711
1767
|
}
|
|
1712
1768
|
|
|
1769
|
+
private triggerOnUpdateNewConversationBadge(count: number){
|
|
1770
|
+
const detailOBJ = { event: 'onUpdateNewConversationBadge', count: count.toString() }
|
|
1771
|
+
this.triggerEvents.triggerOnUpdateNewConversationBadge(detailOBJ)
|
|
1772
|
+
}
|
|
1773
|
+
|
|
1713
1774
|
|
|
1714
1775
|
// @HostListener('mouseenter', ['$event'])
|
|
1715
1776
|
// onMouseEnter(event: any) {
|
|
@@ -1,20 +1,30 @@
|
|
|
1
1
|
<div>
|
|
2
|
-
<div class="canned-list" *ngIf="
|
|
3
|
-
<
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
<
|
|
9
|
-
|
|
2
|
+
<div class="canned-list" *ngIf="!showLoading">
|
|
3
|
+
<span *ngIf="tagsCannedFilter.length > 0">
|
|
4
|
+
<ion-item button="true" [ngClass]="{'is_active_item': i == arrowkeyLocation}" lines="none"
|
|
5
|
+
class="canned-item no-ripple border" id="{{'canned-item_'+ i }}"
|
|
6
|
+
*ngFor="let canned of tagsCannedFilter; let i = index;"
|
|
7
|
+
(click)="onClickCannedFN(canned, $event)">
|
|
8
|
+
<div class="cannedContent">
|
|
9
|
+
<ion-input [class.readonly]="canned?.disabled" [readonly]="canned?.disabled" type="text" [(ngModel)]="canned.title" class="title" id="{{'titleCanned_'+canned._id}}" #title></ion-input>
|
|
10
|
+
<ion-input [class.readonly]="canned?.disabled" [readonly]="canned?.disabled" type="text" [(ngModel)]="canned.text" class="text truncate"></ion-input>
|
|
11
|
+
</div>
|
|
12
|
+
<!-- <ion-icon class="canned-item-icon" name="pin" src="assets/img/pin.svg" slot=end *ngIf="canned.pinned" (click)="onPinCanned(canned, $event)"></ion-icon>
|
|
13
|
+
<ion-icon class="canned-item-icon" name="pin" src="assets/img/pinned.svg" slot=end (click)="onUnPinCanned(canned, $event)"></ion-icon> -->
|
|
14
|
+
<ion-icon class="canned-item-icon" name="checkmark-sharp" slot=end *ngIf="(canned.createdBy === loggedUser.uid && !canned.disabled) && roles[PERMISSIONS.CANNED_RESPONSES_UPDATE]" (click)="onConfirmEditCanned(canned, $event)"></ion-icon>
|
|
15
|
+
<ion-icon class="canned-item-icon" name="pencil-sharp" slot=end *ngIf="(canned.createdBy === loggedUser.uid && canned.disabled) && roles[PERMISSIONS.CANNED_RESPONSES_UPDATE]" (click)="onEditCanned(canned, $event)"></ion-icon>
|
|
16
|
+
<ion-icon class="canned-item-icon" name="trash-bin-outline" slot=end *ngIf="(canned.createdBy === loggedUser.uid) && roles[PERMISSIONS.CANNED_RESPONSES_DELETE]" (click)="onDeleteCanned(canned, $event)"></ion-icon>
|
|
17
|
+
</ion-item>
|
|
18
|
+
</span>
|
|
19
|
+
<div class="no-data" *ngIf="tagsCannedFilter.length === 0">
|
|
20
|
+
<div class="container">
|
|
21
|
+
<ion-item button="false" lines="none" class="canned-item no-ripple border">
|
|
22
|
+
<ion-icon name="cloud-offline" slot="start"></ion-icon>
|
|
23
|
+
<ion-label>{{translationMap.get('THERE_ARE_NO_CANNED_RESPONSES_AVAILABLE')}}</ion-label>
|
|
24
|
+
</ion-item>
|
|
10
25
|
</div>
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
<ion-icon class="canned-item-icon" name="checkmark-sharp" slot=end *ngIf="canned.createdBy === loggedUser.uid && !canned.disabled" (click)="onConfirmEditCanned(canned, $event)"></ion-icon>
|
|
14
|
-
<ion-icon class="canned-item-icon" name="pencil-sharp" slot=end *ngIf="canned.createdBy === loggedUser.uid && canned.disabled" (click)="onEditCanned(canned, $event)"></ion-icon>
|
|
15
|
-
<ion-icon class="canned-item-icon" name="trash-bin-outline" slot=end *ngIf="canned.createdBy === loggedUser.uid" (click)="onDeleteCanned(canned, $event)"></ion-icon>
|
|
16
|
-
</ion-item>
|
|
17
|
-
<ion-item class="canned-item add-canned-response-wpr" button="true" lines="none" (click)="onClickAddCannedResponseFN()">
|
|
26
|
+
</div>
|
|
27
|
+
<ion-item *ngIf="roles[PERMISSIONS.CANNED_RESPONSES_CREATE]" class="canned-item add-canned-response-wpr" button="true" lines="none" (click)="onClickAddCannedResponseFN()">
|
|
18
28
|
<ion-icon class="add-canned-response-icon" name="flash-outline"></ion-icon>
|
|
19
29
|
<span class="add-canned-response-add-icon">+</span>
|
|
20
30
|
<label class="add-canned-response-label" >{{translationMap?.get('AddNewCannedResponse')}}</label>
|
|
@@ -33,12 +43,5 @@
|
|
|
33
43
|
<div class="label">{{translationMap.get('LABEL_LOADING')}}</div>
|
|
34
44
|
</div>
|
|
35
45
|
</div>
|
|
36
|
-
|
|
37
|
-
<div class="container">
|
|
38
|
-
<ion-item button="false" lines="none" class="canned-item no-ripple border">
|
|
39
|
-
<ion-icon name="cloud-offline" slot="start"></ion-icon>
|
|
40
|
-
<ion-label>{{translationMap.get('THERE_ARE_NO_CANNED_RESPONSES_AVAILABLE')}}</ion-label>
|
|
41
|
-
</ion-item>
|
|
42
|
-
</div>
|
|
43
|
-
</div>
|
|
46
|
+
|
|
44
47
|
</div>
|
|
@@ -9,6 +9,7 @@ import { TiledeskAuthService } from 'src/chat21-core/providers/tiledesk/tiledesk
|
|
|
9
9
|
import { compareValues, htmlEntities } from 'src/chat21-core/utils/utils';
|
|
10
10
|
import { getProjectIdSelectedConversation } from 'src/chat21-core/utils/utils-message';
|
|
11
11
|
import { PLAN_NAME } from 'src/chat21-core/utils/constants';
|
|
12
|
+
import { PERMISSIONS } from 'src/app/utils/permissions.constants';
|
|
12
13
|
|
|
13
14
|
@Component({
|
|
14
15
|
selector: 'app-canned-response',
|
|
@@ -21,7 +22,7 @@ export class CannedResponseComponent implements OnInit {
|
|
|
21
22
|
@Input() conversationWith: string;
|
|
22
23
|
@Input() conversationWithFullname: string;
|
|
23
24
|
@Input() currentString: string;
|
|
24
|
-
@Input()
|
|
25
|
+
@Input() roles: Array<string>;
|
|
25
26
|
@Input() stylesMap: Map<string, string>;
|
|
26
27
|
@Input() translationMap: Map<string, string>;
|
|
27
28
|
@Output() onLoadedCannedResponses = new EventEmitter<[any]>();
|
|
@@ -36,6 +37,7 @@ export class CannedResponseComponent implements OnInit {
|
|
|
36
37
|
|
|
37
38
|
public arrowkeyLocation = -1
|
|
38
39
|
|
|
40
|
+
PERMISSIONS = PERMISSIONS
|
|
39
41
|
|
|
40
42
|
private logger: LoggerService = LoggerInstance.getInstance();
|
|
41
43
|
constructor(
|
package/src/app/components/conversation-detail/message-text-area/message-text-area.component.html
CHANGED
|
@@ -22,6 +22,13 @@
|
|
|
22
22
|
{{translationMap?.get('WHATSAPP.LABEL_TEMPLATES')}}
|
|
23
23
|
</ion-button>
|
|
24
24
|
</div>
|
|
25
|
+
<!-- OPEN TICKET -->
|
|
26
|
+
<div *ngIf="ticketSection" class="section-option" id="template" tooltip="{{translationMap?.get('TICKET.OPEN_TICKET')}}" placement="top">
|
|
27
|
+
<ion-button fill="clear" [class.active]="section==='ticket'" (click)="onOpenSection('ticket')" [disabled]="channelType === 'direct'">
|
|
28
|
+
<ion-icon name="ticket"></ion-icon>
|
|
29
|
+
{{translationMap?.get('TICKET.OPEN_TICKET')}}
|
|
30
|
+
</ion-button>
|
|
31
|
+
</div>
|
|
25
32
|
</div>
|
|
26
33
|
|
|
27
34
|
<div class="footerContainerAlert">
|
|
@@ -50,6 +57,22 @@
|
|
|
50
57
|
</ion-col>
|
|
51
58
|
</ion-row>
|
|
52
59
|
|
|
60
|
+
<ion-row id="ticket" [style.display]="section==='ticket'? 'flex': 'none'">
|
|
61
|
+
<ion-col col-auto>
|
|
62
|
+
<div class="placeholder">{{translationMap.get('TICKET.DESCRIPTION')}}</div>
|
|
63
|
+
<div class="buttons-container">
|
|
64
|
+
<ion-button name="add" size="small" (click)="onClickTicket('open')">
|
|
65
|
+
<ion-icon name="add"></ion-icon>
|
|
66
|
+
{{translationMap?.get('TICKET.CONFIRM')}}
|
|
67
|
+
</ion-button>
|
|
68
|
+
<ion-button size="small" color="danger" (click)="onClickTicket('close')">
|
|
69
|
+
<ion-icon name="close"></ion-icon>
|
|
70
|
+
{{translationMap?.get('TICKET.CLOSE')}}
|
|
71
|
+
</ion-button>
|
|
72
|
+
</div>
|
|
73
|
+
</ion-col>
|
|
74
|
+
</ion-row>
|
|
75
|
+
|
|
53
76
|
<ion-row id="message-text-area" [style.display]="section==='chat' || section ==='templates' || section ==='copilot'? 'flex': 'none'">
|
|
54
77
|
|
|
55
78
|
<ion-col col-auto style="display: flex;">
|
|
@@ -57,7 +80,7 @@
|
|
|
57
80
|
<div class="buttons-left">
|
|
58
81
|
|
|
59
82
|
<!-- CANNED RESPONSES -->
|
|
60
|
-
<ng-container *ngIf="areVisibleCAR && supportMode">
|
|
83
|
+
<ng-container *ngIf="areVisibleCAR && supportMode && cannedSection">
|
|
61
84
|
<div class="canned-responses-btn-wpr" tooltip="{{translationMap?.get('CANNED_RESPONSES')}}" placement="top">
|
|
62
85
|
<ion-button ion-button fill="clear" class="canned-responses-btn" (click)="openCannedResponses()"
|
|
63
86
|
[disabled]="!conversationWith?.startsWith(CHANNEL_TYPE.SUPPORT_GROUP) || disableTextarea">
|
package/src/app/components/conversation-detail/message-text-area/message-text-area.component.scss
CHANGED
|
@@ -183,6 +183,36 @@
|
|
|
183
183
|
}
|
|
184
184
|
}
|
|
185
185
|
|
|
186
|
+
#ticket{
|
|
187
|
+
text-align: center;
|
|
188
|
+
font-size: 12px;
|
|
189
|
+
|
|
190
|
+
.buttons-container{
|
|
191
|
+
display: flex;
|
|
192
|
+
justify-content: center;
|
|
193
|
+
gap: 10px;
|
|
194
|
+
|
|
195
|
+
ion-button{
|
|
196
|
+
font-size: 12px;
|
|
197
|
+
--padding-top: 4px;
|
|
198
|
+
--padding-bottom: 4px;
|
|
199
|
+
--padding-start: 6px;
|
|
200
|
+
--padding-end: 6px;
|
|
201
|
+
--ripple-color: transparent;
|
|
202
|
+
text-transform: unset;
|
|
203
|
+
height: auto;
|
|
204
|
+
|
|
205
|
+
ion-icon{
|
|
206
|
+
margin-right: 4px;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
&[name="add"]{
|
|
210
|
+
--background: var(--basic-blue);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
186
216
|
#fileInput {
|
|
187
217
|
position: absolute;
|
|
188
218
|
opacity: 0;
|
package/src/app/components/conversation-detail/message-text-area/message-text-area.component.ts
CHANGED
|
@@ -26,6 +26,7 @@ import { CopilotService } from 'src/app/services/copilot/copilot.service';
|
|
|
26
26
|
import { BRAND_BASE_INFO } from 'src/app/utils/utils-resources';
|
|
27
27
|
import { ProjectService } from 'src/app/services/projects/project.service';
|
|
28
28
|
import { Project } from 'src/chat21-core/models/projects';
|
|
29
|
+
import { ProjectUser } from 'src/chat21-core/models/projectUsers';
|
|
29
30
|
|
|
30
31
|
|
|
31
32
|
@Component({
|
|
@@ -49,6 +50,7 @@ export class MessageTextAreaComponent implements OnInit, AfterViewInit, OnChange
|
|
|
49
50
|
@ViewChild('fileInput', { static: false }) fileInput: any;
|
|
50
51
|
|
|
51
52
|
@Input() loggedUser: UserModel;
|
|
53
|
+
@Input() projectUser: ProjectUser;
|
|
52
54
|
@Input() conversationWith: string;
|
|
53
55
|
@Input() channelType: string;
|
|
54
56
|
@Input() channel: string;
|
|
@@ -61,16 +63,20 @@ export class MessageTextAreaComponent implements OnInit, AfterViewInit, OnChange
|
|
|
61
63
|
@Input() emailSection: boolean;
|
|
62
64
|
@Input() offlineMsgEmail: boolean;
|
|
63
65
|
@Input() whatsappTemplatesSection: boolean;
|
|
66
|
+
@Input() ticketSection: boolean
|
|
64
67
|
@Input() isOpenInfoConversation: boolean;
|
|
68
|
+
@Input() cannedSection: boolean;
|
|
65
69
|
@Input() stylesMap: Map<string, string>;
|
|
66
70
|
@Input() translationMap: Map<string, string>;
|
|
67
71
|
@Input() dropEvent: any;
|
|
68
72
|
@Input() disableTextarea: boolean;
|
|
73
|
+
@Input() roles: Array<string>;
|
|
69
74
|
@Output() eventChangeTextArea = new EventEmitter<{msg: string, offsetHeight: number}>();
|
|
70
75
|
@Output() eventSendMessage = new EventEmitter<{msg: string, type: string, metadata?: Object, attributes?: Object}>();
|
|
71
76
|
@Output() onClickOpenCannedResponses = new EventEmitter<boolean>();
|
|
72
77
|
@Output() onPresentModalScrollToBottom = new EventEmitter<boolean>();
|
|
73
78
|
@Output() onOpenFooterSection = new EventEmitter<string>();
|
|
79
|
+
@Output() onOpenTicket = new EventEmitter<boolean>();
|
|
74
80
|
|
|
75
81
|
public project: Project;
|
|
76
82
|
public conversationEnabled = false;
|
|
@@ -288,6 +294,17 @@ export class MessageTextAreaComponent implements OnInit, AfterViewInit, OnChange
|
|
|
288
294
|
this.prensentTemplateModal();
|
|
289
295
|
}
|
|
290
296
|
|
|
297
|
+
onClickTicket(option: "open" | "close"){
|
|
298
|
+
this.logger.log('[CONVS-DETAIL][MSG-TEXT-AREA] - onClickTicket', option);
|
|
299
|
+
switch(option){
|
|
300
|
+
case "open":
|
|
301
|
+
this.onOpenTicket.emit();
|
|
302
|
+
case "close":
|
|
303
|
+
this.section = 'chat'
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
}
|
|
307
|
+
|
|
291
308
|
|
|
292
309
|
/**
|
|
293
310
|
*
|
|
@@ -567,8 +584,10 @@ export class MessageTextAreaComponent implements OnInit, AfterViewInit, OnChange
|
|
|
567
584
|
if (!text.includes("/")) {
|
|
568
585
|
this.logger.log('[CONVS-DETAIL][MSG-TEXT-AREA] onKeydown - SEND MESSAGE 1 message: ', message);
|
|
569
586
|
this.logger.log("[CONVS-DETAIL] replaceTagInMessage onKeydown in msg-texarea SEND MESSAGE 1 message: ", message);
|
|
570
|
-
|
|
587
|
+
|
|
571
588
|
this.sendMessage(text);
|
|
589
|
+
// this.messageString = '';
|
|
590
|
+
|
|
572
591
|
this.countClicks = 0
|
|
573
592
|
} else if (text.includes("/") && pos === 0 && this.countClicks > 1 && this.tagsCannedFilter.length > 0) {
|
|
574
593
|
this.logger.log('[CONVS-DETAIL][MSG-TEXT-AREA] onKeydown - tagsCannedFilter.length 2: ', this.tagsCannedFilter.length);
|
|
@@ -580,9 +599,10 @@ export class MessageTextAreaComponent implements OnInit, AfterViewInit, OnChange
|
|
|
580
599
|
this.logger.log("[CONVS-DETAIL] replaceTagInMessage onKeydown in msg-texarea SEND MESSAGE 2 this.countClicks: ", this.countClicks);
|
|
581
600
|
this.logger.log("[CONVS-DETAIL][MSG-TEXT-AREA] onKeydown in msg-texarea SEND MESSAGE 2 this.countClicks: ", this.countClicks);
|
|
582
601
|
this.logger.log('[CONVS-DETAIL][MSG-TEXT-AREA] onKeydown - SEND MESSAGE 2 message: ', message);
|
|
583
|
-
|
|
584
|
-
|
|
602
|
+
|
|
585
603
|
this.sendMessage(text);
|
|
604
|
+
// this.messageString = '';
|
|
605
|
+
|
|
586
606
|
this.countClicks = 0
|
|
587
607
|
} else if (text.includes("/") && pos > 0 && this.countClicks > 1 && this.tagsCannedFilter.length > 0 && text.substr(-1) !== '/') {
|
|
588
608
|
this.logger.log('[CONVS-DETAIL][MSG-TEXT-AREA] onKeydown - tagsCannedFilter.length 3: ', this.tagsCannedFilter.length);
|
|
@@ -594,17 +614,19 @@ export class MessageTextAreaComponent implements OnInit, AfterViewInit, OnChange
|
|
|
594
614
|
this.logger.log("[CONVS-DETAIL] replaceTagInMessage onKeydown in msg-texarea SEND MESSAGE 2 this.countClicks: ", this.countClicks);
|
|
595
615
|
this.logger.log("[CONVS-DETAIL][MSG-TEXT-AREA] onKeydown in msg-texarea SEND MESSAGE 2 this.countClicks: ", this.countClicks);
|
|
596
616
|
this.logger.log('[CONVS-DETAIL][MSG-TEXT-AREA] onKeydown - SEND MESSAGE 2 message: ', message);
|
|
597
|
-
|
|
598
|
-
|
|
617
|
+
|
|
599
618
|
this.sendMessage(text);
|
|
619
|
+
// this.messageString = '';
|
|
620
|
+
|
|
600
621
|
this.countClicks = 0
|
|
601
622
|
} else if (text.includes("/") && this.tagsCannedFilter.length === 0) {
|
|
602
623
|
this.logger.log('[CONVS-DETAIL][MSG-TEXT-AREA] onKeydown - tagsCannedFilter.length 3: ', this.tagsCannedFilter.length);
|
|
603
624
|
this.logger.log('[CONVS-DETAIL][MSG-TEXT-AREA] onKeydown - SEND MESSAGE 3 message: ', message);
|
|
604
625
|
this.logger.log("[CONVS-DETAIL] replaceTagInMessage onKeydown in msg-texarea SEND MESSAGE 3 message: ", message);
|
|
605
|
-
|
|
606
|
-
|
|
626
|
+
|
|
607
627
|
this.sendMessage(text);
|
|
628
|
+
// this.messageString = '';
|
|
629
|
+
|
|
608
630
|
this.countClicks = 0
|
|
609
631
|
|
|
610
632
|
}
|