@chat21/chat21-ionic 3.4.31 → 3.4.32-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 +127 -2
- package/angular.json +1 -0
- package/package.json +1 -1
- package/src/app/app.component.html +3 -1
- package/src/app/app.component.ts +72 -11
- package/src/app/chatlib/list-conversations-component/ion-list-conversations/ion-list-conversations.component.html +14 -2
- package/src/app/chatlib/list-conversations-component/ion-list-conversations/ion-list-conversations.component.scss +39 -2
- package/src/app/chatlib/list-conversations-component/list-conversations.module.ts +14 -0
- 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 +35 -9
- package/src/app/components/navbar/navbar.component.scss +64 -0
- package/src/app/components/navbar/navbar.component.ts +100 -42
- package/src/app/components/project-item/project-item.component.ts +79 -51
- 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 +3 -3
- package/src/app/components/sidebar-user-details/sidebar-user-details.component.ts +15 -22
- package/src/app/modals/create-ticket/create-ticket.page.ts +4 -2
- 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.module.ts +3 -5
- package/src/app/pages/conversations-list/conversations-list.page.html +2 -0
- package/src/app/pages/conversations-list/conversations-list.page.ts +51 -11
- package/src/app/pages/unassigned-conversations/unassigned-conversations.module.ts +16 -4
- package/src/app/pages/unassigned-conversations/unassigned-conversations.page.html +41 -17
- package/src/app/pages/unassigned-conversations/unassigned-conversations.page.scss +10 -1
- package/src/app/pages/unassigned-conversations/unassigned-conversations.page.ts +114 -9
- 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/projects/project.service.ts +2 -1
- package/src/app/services/tiledesk/tiledesk.service.ts +21 -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 +59 -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/models/project_user.ts +2 -1
- 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/constants.ts +5 -0
- package/src/chat21-core/utils/convertRequestToConversation.ts +1 -1
- package/src/chat21-core/utils/utils.ts +53 -3
- package/src/variables.scss +3 -0
package/CHANGELOG.md
CHANGED
|
@@ -8,22 +8,128 @@
|
|
|
8
8
|
### **Copyrigth**:
|
|
9
9
|
*Tiledesk SRL*
|
|
10
10
|
|
|
11
|
+
# 3.4.32-rc1
|
|
12
|
+
- **added**: ability to change availability status for each project the logged-in user belongs to.
|
|
13
|
+
- **changed**: unserved-request.page refactor html and ts refactor
|
|
14
|
+
|
|
11
15
|
# 3.4.31 in PROD
|
|
12
16
|
- **changed**: enhance HTML entities encoding by normalizing line breaks and handling null/undefined inputs
|
|
13
17
|
- **changed**: API for upload a file/image into chat
|
|
14
18
|
|
|
15
19
|
# 3.4.30 in PROD
|
|
20
|
+
|
|
21
|
+
# 3.4.30-rc3
|
|
16
22
|
- **changed**: when the app is in background, play a sound whenever a new message arrives.
|
|
17
23
|
|
|
18
24
|
# 3.4.29 in PROD
|
|
19
25
|
- **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)`
|
|
20
26
|
|
|
27
|
+
# 3.4.29-rc2
|
|
28
|
+
- **changed**: minor updates on API to upload file/image into chat
|
|
29
|
+
|
|
30
|
+
# 3.4.29-rc1
|
|
31
|
+
- **changed**: API for upload a file/image into chat
|
|
32
|
+
|
|
33
|
+
|
|
21
34
|
# 3.4.28 in PROD
|
|
22
35
|
- **bug-fixed**: cannot do project subscription if last_project object is not a project_user obj
|
|
23
36
|
|
|
24
37
|
# 3.4.27 in PROD
|
|
25
38
|
- **bug-fixed**: cannot find route if userFullname contains /
|
|
26
39
|
|
|
40
|
+
# 3.4.29-rc1
|
|
41
|
+
- **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)`
|
|
42
|
+
|
|
43
|
+
# 3.4.28-rc1
|
|
44
|
+
- **bug-fixed**: cannot do project subscription if last_project object is not a project_user obj
|
|
45
|
+
|
|
46
|
+
# 3.4.27-rc26
|
|
47
|
+
- **bug-fixed**: wss push requests twice
|
|
48
|
+
|
|
49
|
+
# 3.4.27-rc25
|
|
50
|
+
- **bug-fixed**: projectUserService is not initialized
|
|
51
|
+
|
|
52
|
+
# 3.4.27-rc24
|
|
53
|
+
- **added**: implementation of multiple message in wss onmessage
|
|
54
|
+
|
|
55
|
+
# 3.4.27-rc23
|
|
56
|
+
- **added**: keepAlive worker for MQTT connection
|
|
57
|
+
|
|
58
|
+
# 3.4.27-rc22
|
|
59
|
+
- **added**: new WsWorker to manage iframe chrome throttling while tab is in background or hidden
|
|
60
|
+
|
|
61
|
+
# 3.4.27-rc21
|
|
62
|
+
- **changed**: new wss reconnect and timeout keepalive
|
|
63
|
+
- **bug-fixed**: cannot route if senderFullaname contains /
|
|
64
|
+
|
|
65
|
+
# 3.4.27-rc20
|
|
66
|
+
- **added**: onOpenTicketExternally event in triggerEvents service
|
|
67
|
+
|
|
68
|
+
# 3.4.27-rc19
|
|
69
|
+
- **added**: window.parent['openTicketOnHDA']
|
|
70
|
+
|
|
71
|
+
# 3.4.27-rc18
|
|
72
|
+
- **added**: triggerOnUpdateNewConversationBadge to update conversation badge count in parent component
|
|
73
|
+
|
|
74
|
+
# 3.4.27-rc17
|
|
75
|
+
- **bug-fixed**: setNotification not called when click on a conversation
|
|
76
|
+
|
|
77
|
+
# 3.4.27-rc16
|
|
78
|
+
- **bug-fixed**: setNotification not called when resolve a conversation
|
|
79
|
+
|
|
80
|
+
# 3.4.27-rc15
|
|
81
|
+
- **changed**: /images with /img in assets folder
|
|
82
|
+
|
|
83
|
+
# 3.4.27-rc14
|
|
84
|
+
- **added**: DISPLAY_EDIT_PROFILE brand variable
|
|
85
|
+
- **bug-fixed**: emojii is sent also if is not allowed
|
|
86
|
+
|
|
87
|
+
# 3.4.27-rc13
|
|
88
|
+
- **added**: ability to mantain logout parameter when redirect to dashboard urls from sidebar component
|
|
89
|
+
|
|
90
|
+
# 3.4.27-rc12
|
|
91
|
+
- **added**: ability to manage logOut option in sidebar-user-detail with tiledesk_logOut url query params
|
|
92
|
+
|
|
93
|
+
# 3.4.27-rc11
|
|
94
|
+
- **bug-fixed**: fixed infinite loading in contact list
|
|
95
|
+
|
|
96
|
+
# 3.4.27-rc10
|
|
97
|
+
- **added**: ability to manage header-conversation-list with roles
|
|
98
|
+
- **bug-fixed**: members in group list not loaded
|
|
99
|
+
|
|
100
|
+
# 3.4.27-rc9
|
|
101
|
+
- **bug-fixed**: Scrolling to the last message when opening a conversation
|
|
102
|
+
- **bug-fixed**: Loading in the conversation list disabled when removing the last conversation
|
|
103
|
+
|
|
104
|
+
# 3.4.27-rc8
|
|
105
|
+
- **added**: ability to open ticket to external service
|
|
106
|
+
- **added**: ticketSection env var
|
|
107
|
+
|
|
108
|
+
# 3.4.27-rc7
|
|
109
|
+
- **bug-fixed**: Scrolling to the last message when opening a conversation
|
|
110
|
+
- **bug-fixed**: Loading in the conversation list disabled when removing the last conversation
|
|
111
|
+
|
|
112
|
+
# 3.4.27-rc6
|
|
113
|
+
- **bug-fixed**: user for dashboard app is incorrect
|
|
114
|
+
|
|
115
|
+
# 3.4.27-rc5
|
|
116
|
+
- **added**: managed roles in sidebar e navbar
|
|
117
|
+
- **bug-fixed**: projectId and supportMode url is not saved in localstorage
|
|
118
|
+
|
|
119
|
+
# 3.4.27-rc4
|
|
120
|
+
- **bug-fixed**: extractUrls function is not able to detect url start with www or without https/http
|
|
121
|
+
- **bug-fixed**: if message is sent with keydown, error on domain check is not showed
|
|
122
|
+
|
|
123
|
+
# 3.4.27-rc3
|
|
124
|
+
- **bug-fixed**: cannot set user availability if supportMode is enabled and tiledesk_projectID url params is set
|
|
125
|
+
|
|
126
|
+
# 3.4.27-rc2
|
|
127
|
+
- **bug-fixed**: cannede responses role
|
|
128
|
+
|
|
129
|
+
# 3.4.27-rc1
|
|
130
|
+
- **added**: managed canned responses with roles
|
|
131
|
+
- **changed**: name in info mesage
|
|
132
|
+
|
|
27
133
|
# 3.4.26 in PROD
|
|
28
134
|
|
|
29
135
|
# 3.4.26-rc2
|
|
@@ -32,6 +138,7 @@
|
|
|
32
138
|
# 3.4.26-rc1
|
|
33
139
|
- **added**: tiledesk_projectID query param to manage user status
|
|
34
140
|
- **added**: token to managane ticket feature
|
|
141
|
+
- **added**: getOsCode login into utils.ts
|
|
35
142
|
|
|
36
143
|
# 3.4.25 in PROD
|
|
37
144
|
- **changed**: pipe marked to support malicious text input
|
|
@@ -54,6 +161,24 @@
|
|
|
54
161
|
# 3.4.22 in PROD
|
|
55
162
|
- **added**: managed allowed_upload_extentions from project settings
|
|
56
163
|
|
|
164
|
+
# 3.4.21-rc6
|
|
165
|
+
- **added**: managed allowed_upload_extentions from project settings
|
|
166
|
+
|
|
167
|
+
# 3.4.21-rc5
|
|
168
|
+
- **added**: setConversation as read when agent click on it
|
|
169
|
+
|
|
170
|
+
# 3.4.21-rc4
|
|
171
|
+
- **added**: ability to init and decrement new conversation count badge
|
|
172
|
+
|
|
173
|
+
# 3.4.21-rc3
|
|
174
|
+
- **changed**: badge notification for agentDesktop
|
|
175
|
+
|
|
176
|
+
# 3.4.21-rc2
|
|
177
|
+
- **added**: count in newConversation handler event
|
|
178
|
+
|
|
179
|
+
# 3.4.21-rc1
|
|
180
|
+
- **added**: implement badge notification for agentDesktop sw when new conversation is assigned to logged agent
|
|
181
|
+
|
|
57
182
|
# 3.4.21 in PROD
|
|
58
183
|
|
|
59
184
|
# 3.4.20 in PROD
|
|
@@ -67,8 +192,8 @@
|
|
|
67
192
|
- **bug-fixed**: minor fix on ion-texarea element with allowed url domain
|
|
68
193
|
|
|
69
194
|
# 3.4.19-rc1
|
|
70
|
-
- added
|
|
71
|
-
- added
|
|
195
|
+
- **added**: ability to check for if emoji is allowd to be sent in message textarea
|
|
196
|
+
- **added**: ability to check for if url domain is allowd to be sent in message textarea
|
|
72
197
|
|
|
73
198
|
# 3.4.18 in PROD
|
|
74
199
|
|
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',
|
|
@@ -141,6 +144,7 @@ export class AppComponent implements OnInit {
|
|
|
141
144
|
/**TILEDESK SERVICES */
|
|
142
145
|
private tiledeskService: TiledeskService,
|
|
143
146
|
private projectService: ProjectService,
|
|
147
|
+
private projectUsersService: ProjectUsersService,
|
|
144
148
|
private contactsService: ContactsService
|
|
145
149
|
) {
|
|
146
150
|
|
|
@@ -167,6 +171,7 @@ export class AppComponent implements OnInit {
|
|
|
167
171
|
}, { capture: true });
|
|
168
172
|
}
|
|
169
173
|
|
|
174
|
+
|
|
170
175
|
listenChatAlreadyOpenWithoutParamsInMobileMode() {
|
|
171
176
|
this.events.subscribe('noparams:mobile', (isAlreadyOpenInMobileMode) => {
|
|
172
177
|
// console.log('[APP-COMP] Chat is Already Open In Mobile Mode ', isAlreadyOpenInMobileMode)
|
|
@@ -295,6 +300,10 @@ export class AppComponent implements OnInit {
|
|
|
295
300
|
this.zone = new NgZone({}); // a cosa serve?
|
|
296
301
|
|
|
297
302
|
this.SUPPORT_MODE = this.g.supportMode
|
|
303
|
+
this.logger.info('[APP-COMP] this.SUPPORT_MODE', this.SUPPORT_MODE)
|
|
304
|
+
|
|
305
|
+
BRAND_BASE_INFO['LOGOUT_ENABLED'] = this.g.logOut
|
|
306
|
+
this.logger.info('[APP-COMP] this.logOut', BRAND_BASE_INFO['LOGOUT_ENABLED'])
|
|
298
307
|
}
|
|
299
308
|
|
|
300
309
|
});
|
|
@@ -331,7 +340,7 @@ export class AppComponent implements OnInit {
|
|
|
331
340
|
|
|
332
341
|
listenToPostMsgs() {
|
|
333
342
|
window.addEventListener("message", (event) => {
|
|
334
|
-
this.logger.log("[APP-COMP] message event ", event);
|
|
343
|
+
// this.logger.log("[APP-COMP] message event ", event);
|
|
335
344
|
|
|
336
345
|
if (event && event.data && event.data.action && event.data.parameter) {
|
|
337
346
|
if (event.data.action === 'openJoinConversationModal') {
|
|
@@ -341,7 +350,7 @@ export class AppComponent implements OnInit {
|
|
|
341
350
|
|
|
342
351
|
if (event && event.data && event.data.action && event.data.parameter) {
|
|
343
352
|
if (event.data.action === 'resolveConversation') {
|
|
344
|
-
this.conversationsHandlerService.archiveConversation(event.data.
|
|
353
|
+
this.conversationsHandlerService.archiveConversation(event.data.parameter)
|
|
345
354
|
}
|
|
346
355
|
}
|
|
347
356
|
// if (event && event.data && event.data.action && event.data.parameter) {
|
|
@@ -533,10 +542,10 @@ export class AppComponent implements OnInit {
|
|
|
533
542
|
this.statusBar.styleLightContent();
|
|
534
543
|
this.navService.init(this.sidebarNav, this.detailNav);
|
|
535
544
|
this.tiledeskAuthService.initialize(this.appConfigProvider.getConfig().apiUrl);
|
|
536
|
-
|
|
537
|
-
|
|
545
|
+
|
|
538
546
|
// this.currentUserService.initialize();
|
|
539
547
|
this.chatManager.initialize();
|
|
548
|
+
this.messagingAuthService.initialize();
|
|
540
549
|
this.presenceService.initialize(this.tenant);
|
|
541
550
|
this.typingService.initialize(this.tenant);
|
|
542
551
|
|
|
@@ -862,7 +871,8 @@ export class AppComponent implements OnInit {
|
|
|
862
871
|
// console.log('[APP-COMP] PLATFORM', PLATFORM_MOBILE, 'route.snapshot', this.route.snapshot);
|
|
863
872
|
if (!IDConv) {
|
|
864
873
|
this.logger.log('[APP-COMP] navigateByUrl -- conversations-list');
|
|
865
|
-
|
|
874
|
+
const queryString = window.location.search; // restituisce ad es. "?jwt=...&tiledesk_supportMode=false"
|
|
875
|
+
this.router.navigateByUrl('conversations-list' + queryString);
|
|
866
876
|
}
|
|
867
877
|
// this.router.navigateByUrl(pageUrl);
|
|
868
878
|
// this.navService.setRoot(ConversationListPage, {});
|
|
@@ -1113,13 +1123,19 @@ export class AppComponent implements OnInit {
|
|
|
1113
1123
|
if (conversation && conversation.is_new === true && this.isInitialized) {
|
|
1114
1124
|
this.manageTabNotification('conv_added', conversation.sound)
|
|
1115
1125
|
this.manageEventNewConversation(conversation)
|
|
1126
|
+
//UPDATE NOTIFICATION FOR NEW CONVERSATION COUNT
|
|
1127
|
+
this.triggerOnUpdateNewConversationBadge(this.conversationsHandlerService.countIsNew());
|
|
1116
1128
|
}
|
|
1117
1129
|
if(conversation) this.updateConversationsOnStorage()
|
|
1118
1130
|
});
|
|
1119
1131
|
|
|
1120
1132
|
this.conversationsHandlerService.conversationChanged.subscribe((conversation: ConversationModel) => {
|
|
1121
1133
|
// console.log('[APP-COMP] ***** subscribeConversationChanged conversation: ', conversation);
|
|
1122
|
-
if(conversation)
|
|
1134
|
+
if(conversation){
|
|
1135
|
+
this.updateConversationsOnStorage();
|
|
1136
|
+
//UPDATE NOTIFICATION FOR NEW CONVERSATION COUNT
|
|
1137
|
+
this.triggerOnUpdateNewConversationBadge(this.conversationsHandlerService.countIsNew());
|
|
1138
|
+
}
|
|
1123
1139
|
});
|
|
1124
1140
|
|
|
1125
1141
|
this.conversationsHandlerService.conversationChangedDetailed.subscribe((changes: {value: ConversationModel, previousValue: ConversationModel}) => {
|
|
@@ -1147,6 +1163,8 @@ export class AppComponent implements OnInit {
|
|
|
1147
1163
|
if(conversation) {
|
|
1148
1164
|
this.updateConversationsOnStorage();
|
|
1149
1165
|
this.segmentResolved(conversation);
|
|
1166
|
+
//UPDATE NOTIFICATION FOR NEW CONVERSATION COUNT
|
|
1167
|
+
this.triggerOnUpdateNewConversationBadge(this.conversationsHandlerService.countIsNew());
|
|
1150
1168
|
this.router.navigateByUrl('conversation-detail/'); //redirect to basePage
|
|
1151
1169
|
}
|
|
1152
1170
|
});
|
|
@@ -1180,6 +1198,7 @@ export class AppComponent implements OnInit {
|
|
|
1180
1198
|
this.chatManager.setCurrentUser(currentUser);
|
|
1181
1199
|
|
|
1182
1200
|
this.tiledeskService.initialize(serverBaseURL)
|
|
1201
|
+
this.projectUsersService.initialize(serverBaseURL)
|
|
1183
1202
|
this.projectService.initialize(serverBaseURL)
|
|
1184
1203
|
this.contactsService.initialize(serverBaseURL)
|
|
1185
1204
|
|
|
@@ -1187,11 +1206,14 @@ export class AppComponent implements OnInit {
|
|
|
1187
1206
|
this.events.publish('go:online', true);
|
|
1188
1207
|
// this.chatManager.startApp();
|
|
1189
1208
|
|
|
1209
|
+
|
|
1210
|
+
//INIT WEBSOCKET
|
|
1211
|
+
this.connetWebsocket(tiledeskToken)
|
|
1212
|
+
|
|
1190
1213
|
// ----------------------------------------------
|
|
1191
1214
|
// PUSH NOTIFICATIONS
|
|
1192
1215
|
// ----------------------------------------------
|
|
1193
1216
|
const pushEngine = this.appConfigProvider.getConfig().pushEngine
|
|
1194
|
-
|
|
1195
1217
|
if (currentUser) {
|
|
1196
1218
|
if (pushEngine && pushEngine !== 'none') {
|
|
1197
1219
|
this.notificationsService.getNotificationPermissionAndSaveToken(currentUser.uid);
|
|
@@ -1213,6 +1235,24 @@ export class AppComponent implements OnInit {
|
|
|
1213
1235
|
} catch (err) {
|
|
1214
1236
|
this.logger.error('[APP-COMP] -> error:', err);
|
|
1215
1237
|
}
|
|
1238
|
+
|
|
1239
|
+
// ----------------------------------------------
|
|
1240
|
+
// LAST PROJECT FROM URL
|
|
1241
|
+
// ----------------------------------------------
|
|
1242
|
+
if(this.g.projectID){
|
|
1243
|
+
this.projectService.getProjects().subscribe({ next: (projects: Project[]) => {
|
|
1244
|
+
const project = projects.find(prjct => prjct.id_project._id === this.g.projectID)
|
|
1245
|
+
if(project){
|
|
1246
|
+
this.logger.log('[APP-COMP] - GET PROJECT - project found with this.projectID', project);
|
|
1247
|
+
localStorage.setItem('last_project', JSON.stringify(project))
|
|
1248
|
+
this.events.publish('storage:last_project', project)
|
|
1249
|
+
}
|
|
1250
|
+
}, error: (error) => {
|
|
1251
|
+
this.logger.log('[APP-COMP] - GET PROJECT - project NOT found with this.projectID', this.g.projectID, error);
|
|
1252
|
+
}, complete: () => {
|
|
1253
|
+
|
|
1254
|
+
}});
|
|
1255
|
+
}
|
|
1216
1256
|
}
|
|
1217
1257
|
|
|
1218
1258
|
|
|
@@ -1253,9 +1293,21 @@ export class AppComponent implements OnInit {
|
|
|
1253
1293
|
}
|
|
1254
1294
|
|
|
1255
1295
|
goToDashboardLogin(){
|
|
1256
|
-
let DASHBOARD_URL = this.appConfigProvider.getConfig().dashboardUrl + '#/login'
|
|
1257
|
-
const myWindow = window.open(DASHBOARD_URL, '_self');
|
|
1258
|
-
myWindow.focus();
|
|
1296
|
+
// let DASHBOARD_URL = this.appConfigProvider.getConfig().dashboardUrl + '#/login'
|
|
1297
|
+
// const myWindow = window.open(DASHBOARD_URL, '_self');
|
|
1298
|
+
// myWindow.focus();
|
|
1299
|
+
}
|
|
1300
|
+
|
|
1301
|
+
connetWebsocket(tiledeskToken) {
|
|
1302
|
+
|
|
1303
|
+
this.logger.log('[WEBSOCKET-JS] connetWebsocket called in [PROJECT-ITEM] tiledeskToken ', tiledeskToken)
|
|
1304
|
+
const appconfig = this.appConfigProvider.getConfig();
|
|
1305
|
+
this.logger.log('[WEBSOCKET-JS] connetWebsocket called in [PROJECT-ITEM] wsUrl ', appconfig.wsUrl)
|
|
1306
|
+
const WS_URL = appconfig.wsUrl + '?token=' + tiledeskToken
|
|
1307
|
+
this.logger.log('[WEBSOCKET-JS] connetWebsocket called in [PROJECT-ITEM] wsUrl ', WS_URL)
|
|
1308
|
+
this.webSocketJs.init(
|
|
1309
|
+
WS_URL
|
|
1310
|
+
);
|
|
1259
1311
|
}
|
|
1260
1312
|
|
|
1261
1313
|
|
|
@@ -1354,7 +1406,8 @@ export class AppComponent implements OnInit {
|
|
|
1354
1406
|
|
|
1355
1407
|
subscribeConversationSelected= (conversation: ConversationModel) => {
|
|
1356
1408
|
if(conversation && conversation.is_new){
|
|
1357
|
-
this.audio_NewConv.pause()
|
|
1409
|
+
this.audio_NewConv.pause();
|
|
1410
|
+
this.conversationsHandlerService.setConversationRead(conversation.uid)
|
|
1358
1411
|
}
|
|
1359
1412
|
}
|
|
1360
1413
|
|
|
@@ -1430,6 +1483,9 @@ export class AppComponent implements OnInit {
|
|
|
1430
1483
|
this.logger.debug('[APP-COMP]-CONVS - INIT CONV CONVS 2', conversations)
|
|
1431
1484
|
this.events.publish('appcompSubscribeToConvs:loadingIsActive', false);
|
|
1432
1485
|
}
|
|
1486
|
+
|
|
1487
|
+
//INIT NOTIFICATION FOR NEW CONVERSATION COUNT
|
|
1488
|
+
this.triggerOnUpdateNewConversationBadge(this.conversationsHandlerService.countIsNew());
|
|
1433
1489
|
});
|
|
1434
1490
|
|
|
1435
1491
|
}
|
|
@@ -1712,6 +1768,11 @@ export class AppComponent implements OnInit {
|
|
|
1712
1768
|
this.triggerEvents.triggerOnInit(detailOBJ)
|
|
1713
1769
|
}
|
|
1714
1770
|
|
|
1771
|
+
private triggerOnUpdateNewConversationBadge(count: number){
|
|
1772
|
+
const detailOBJ = { event: 'onUpdateNewConversationBadge', count: count.toString() }
|
|
1773
|
+
this.triggerEvents.triggerOnUpdateNewConversationBadge(detailOBJ)
|
|
1774
|
+
}
|
|
1775
|
+
|
|
1715
1776
|
|
|
1716
1777
|
// @HostListener('mouseenter', ['$event'])
|
|
1717
1778
|
// onMouseEnter(event: any) {
|
|
@@ -77,6 +77,8 @@
|
|
|
77
77
|
|
|
78
78
|
<ion-item button="true" lines="none" class="ion-no-padding" [class.ion-selected]="conversation?.uid === uidConvSelected"
|
|
79
79
|
*ngFor="let conversation of listConversations; let index= index" (click)="openConversationByID(conversation)" detail=false>
|
|
80
|
+
<div class="conv-item-wrapper">
|
|
81
|
+
<div class="conv-item-top">
|
|
80
82
|
<div tabindex="0"></div>
|
|
81
83
|
|
|
82
84
|
<!-- <div [class.selected]="conversation.uid === uidConvSelected"></div> -->
|
|
@@ -170,9 +172,9 @@
|
|
|
170
172
|
<div *ngIf="conversation?.recipient.startsWith('support-group')" tooltip="{{ translationsMap?.get('Archive')}}"></div> -->
|
|
171
173
|
</ion-button>
|
|
172
174
|
|
|
173
|
-
<!-- <ion-button *ngIf="conversation?.recipient.startsWith('support-group') && !conversation.archived"
|
|
175
|
+
<!-- <ion-button *ngIf="conversation?.recipient.startsWith('support-group') && !conversation.archived"
|
|
174
176
|
[ngClass]="{'hide': !IS_ON_MOBILE_DEVICE, 'button-on-desktop': !IS_ON_MOBILE_DEVICE, 'button-on-mobile': IS_ON_MOBILE_DEVICE }"
|
|
175
|
-
id="{{ 'join_conversation_button' + conversation.uid }}" class="
|
|
177
|
+
id="{{ 'join_conversation_button' + conversation.uid }}" class="join-conversation-button" ion-button clear
|
|
176
178
|
item-end (click)="joinConversation(conversation);$event.stopPropagation();" padding>
|
|
177
179
|
<ion-icon slot="icon-only" style="display:block;" id="{{ 'join_button_icon' + conversation.uid }}" name="link-outline" item-end></ion-icon>
|
|
178
180
|
|
|
@@ -196,5 +198,15 @@
|
|
|
196
198
|
[ngClass]="{'notification_point-on-desktop': !IS_ON_MOBILE_DEVICE, 'notification_point-on-mobile': IS_ON_MOBILE_DEVICE }"
|
|
197
199
|
*ngIf="conversation.is_new">
|
|
198
200
|
</div>
|
|
201
|
+
</div>
|
|
202
|
+
<div class="conv-item-actions" *ngIf="!conversation.archived && conversation.status ===100" (click)="$event.stopPropagation()">
|
|
203
|
+
<ion-button size="small" class="join-button" (click)="joinConversation(conversation)">
|
|
204
|
+
{{ translationsMap?.get('JOIN_CONVERSATION') || 'Join' }}
|
|
205
|
+
</ion-button>
|
|
206
|
+
<ion-button size="small" class="resolve-button" (click)="closeConversation(conversation)">
|
|
207
|
+
{{ translationsMap?.get('Resolve') || 'Resolve' }}
|
|
208
|
+
</ion-button>
|
|
209
|
+
</div>
|
|
210
|
+
</div>
|
|
199
211
|
|
|
200
212
|
</ion-item>
|
|
@@ -9,8 +9,9 @@
|
|
|
9
9
|
}
|
|
10
10
|
ion-item {
|
|
11
11
|
cursor: pointer;
|
|
12
|
-
height: 90px;
|
|
13
|
-
|
|
12
|
+
min-height: 90px;
|
|
13
|
+
height: auto;
|
|
14
|
+
--min-height: auto;
|
|
14
15
|
position: relative;
|
|
15
16
|
display: flex;
|
|
16
17
|
text-decoration: none;
|
|
@@ -23,6 +24,42 @@ ion-item {
|
|
|
23
24
|
border-radius: var(--border-radius-item);
|
|
24
25
|
margin: 4px 5px;
|
|
25
26
|
transition: none;
|
|
27
|
+
.conv-item-wrapper {
|
|
28
|
+
display: flex;
|
|
29
|
+
flex-direction: column;
|
|
30
|
+
width: 100%;
|
|
31
|
+
padding-bottom: 8px;
|
|
32
|
+
}
|
|
33
|
+
.conv-item-top {
|
|
34
|
+
display: flex;
|
|
35
|
+
flex: 1;
|
|
36
|
+
position: relative;
|
|
37
|
+
}
|
|
38
|
+
.conv-item-actions {
|
|
39
|
+
display: flex;
|
|
40
|
+
justify-content: space-around;
|
|
41
|
+
gap: 8px;
|
|
42
|
+
margin-top: 4px;
|
|
43
|
+
ion-button {
|
|
44
|
+
--padding-start: 12px;
|
|
45
|
+
--padding-end: 12px;
|
|
46
|
+
font-size: 12px;
|
|
47
|
+
margin: 0;
|
|
48
|
+
--border-radius: var(--button-border-radius);
|
|
49
|
+
&.join-button {
|
|
50
|
+
--background: var(--join-button-background);
|
|
51
|
+
--background-hover: #e4e6eb;
|
|
52
|
+
--background-activated: #d8dae0;
|
|
53
|
+
--color: var(--bacis-white);
|
|
54
|
+
}
|
|
55
|
+
&.resolve-button {
|
|
56
|
+
--background: var(--resolve-button-background);
|
|
57
|
+
--background-hover: #e4e6eb;
|
|
58
|
+
--background-activated: #d8dae0;
|
|
59
|
+
--color: #1c1e21;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
26
63
|
.conv-container{
|
|
27
64
|
width: 84%;
|
|
28
65
|
height: 100%;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { NgModule } from '@angular/core';
|
|
2
|
+
import { CommonModule } from '@angular/common';
|
|
3
|
+
import { IonicModule } from '@ionic/angular';
|
|
4
|
+
import { MomentModule } from 'ngx-moment';
|
|
5
|
+
|
|
6
|
+
import { ListConversationsComponent } from './list-conversations/list-conversations.component';
|
|
7
|
+
import { IonListConversationsComponent } from './ion-list-conversations/ion-list-conversations.component';
|
|
8
|
+
|
|
9
|
+
@NgModule({
|
|
10
|
+
imports: [CommonModule, IonicModule, MomentModule],
|
|
11
|
+
declarations: [ListConversationsComponent, IonListConversationsComponent],
|
|
12
|
+
exports: [ListConversationsComponent, IonListConversationsComponent],
|
|
13
|
+
})
|
|
14
|
+
export class ListConversationsModule {}
|
|
@@ -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">
|