@chat21/chat21-ionic 3.4.29 → 3.4.30-rc2
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 +120 -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 +71 -12
- package/src/app/chatlib/conversation-detail/message/image/image.component.html +1 -0
- package/src/app/chatlib/conversation-detail/message/image/image.component.ts +19 -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 +39 -9
- 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/conversation-detail/conversation-detail.page.html +7 -3
- package/src/app/pages/conversation-detail/conversation-detail.page.ts +95 -7
- package/src/app/pages/conversations-list/conversations-list.page.html +2 -0
- package/src/app/pages/conversations-list/conversations-list.page.ts +40 -2
- 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/img/no_data_found.png +0 -0
- 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/abstract/upload.service.ts +5 -1
- package/src/chat21-core/providers/firebase/firebase-conversation-handler.ts +1 -1
- package/src/chat21-core/providers/firebase/firebase-upload.service.ts +136 -9
- package/src/chat21-core/providers/mqtt/mqtt-conversation-handler.ts +1 -1
- package/src/chat21-core/providers/native/native-image-repo.ts +1 -1
- package/src/chat21-core/providers/native/native-upload-service.ts +143 -45
- 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,6 +8,12 @@
|
|
|
8
8
|
### **Copyrigth**:
|
|
9
9
|
*Tiledesk SRL*
|
|
10
10
|
|
|
11
|
+
# 3.4.29-rc2
|
|
12
|
+
- **changed**: minor updates on API to upload file/image into chat
|
|
13
|
+
|
|
14
|
+
# 3.4.29-rc1
|
|
15
|
+
- **changed**: API for upload a file/image into chat
|
|
16
|
+
|
|
11
17
|
# 3.4.29 in PROD
|
|
12
18
|
- **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
19
|
|
|
@@ -17,6 +23,99 @@
|
|
|
17
23
|
# 3.4.27 in PROD
|
|
18
24
|
- **bug-fixed**: cannot find route if userFullname contains /
|
|
19
25
|
|
|
26
|
+
# 3.4.29-rc1
|
|
27
|
+
- **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)`
|
|
28
|
+
|
|
29
|
+
# 3.4.28-rc1
|
|
30
|
+
- **bug-fixed**: cannot do project subscription if last_project object is not a project_user obj
|
|
31
|
+
|
|
32
|
+
# 3.4.27-rc26
|
|
33
|
+
- **bug-fixed**: wss push requests twice
|
|
34
|
+
|
|
35
|
+
# 3.4.27-rc25
|
|
36
|
+
- **bug-fixed**: projectUserService is not initialized
|
|
37
|
+
|
|
38
|
+
# 3.4.27-rc24
|
|
39
|
+
- **added**: implementation of multiple message in wss onmessage
|
|
40
|
+
|
|
41
|
+
# 3.4.27-rc23
|
|
42
|
+
- **added**: keepAlive worker for MQTT connection
|
|
43
|
+
|
|
44
|
+
# 3.4.27-rc22
|
|
45
|
+
- **added**: new WsWorker to manage iframe chrome throttling while tab is in background or hidden
|
|
46
|
+
|
|
47
|
+
# 3.4.27-rc21
|
|
48
|
+
- **changed**: new wss reconnect and timeout keepalive
|
|
49
|
+
- **bug-fixed**: cannot route if senderFullaname contains /
|
|
50
|
+
|
|
51
|
+
# 3.4.27-rc20
|
|
52
|
+
- **added**: onOpenTicketExternally event in triggerEvents service
|
|
53
|
+
|
|
54
|
+
# 3.4.27-rc19
|
|
55
|
+
- **added**: window.parent['openTicketOnHDA']
|
|
56
|
+
|
|
57
|
+
# 3.4.27-rc18
|
|
58
|
+
- **added**: triggerOnUpdateNewConversationBadge to update conversation badge count in parent component
|
|
59
|
+
|
|
60
|
+
# 3.4.27-rc17
|
|
61
|
+
- **bug-fixed**: setNotification not called when click on a conversation
|
|
62
|
+
|
|
63
|
+
# 3.4.27-rc16
|
|
64
|
+
- **bug-fixed**: setNotification not called when resolve a conversation
|
|
65
|
+
|
|
66
|
+
# 3.4.27-rc15
|
|
67
|
+
- **changed**: /images with /img in assets folder
|
|
68
|
+
|
|
69
|
+
# 3.4.27-rc14
|
|
70
|
+
- **added**: DISPLAY_EDIT_PROFILE brand variable
|
|
71
|
+
- **bug-fixed**: emojii is sent also if is not allowed
|
|
72
|
+
|
|
73
|
+
# 3.4.27-rc13
|
|
74
|
+
- **added**: ability to mantain logout parameter when redirect to dashboard urls from sidebar component
|
|
75
|
+
|
|
76
|
+
# 3.4.27-rc12
|
|
77
|
+
- **added**: ability to manage logOut option in sidebar-user-detail with tiledesk_logOut url query params
|
|
78
|
+
|
|
79
|
+
# 3.4.27-rc11
|
|
80
|
+
- **bug-fixed**: fixed infinite loading in contact list
|
|
81
|
+
|
|
82
|
+
# 3.4.27-rc10
|
|
83
|
+
- **added**: ability to manage header-conversation-list with roles
|
|
84
|
+
- **bug-fixed**: members in group list not loaded
|
|
85
|
+
|
|
86
|
+
# 3.4.27-rc9
|
|
87
|
+
- **bug-fixed**: Scrolling to the last message when opening a conversation
|
|
88
|
+
- **bug-fixed**: Loading in the conversation list disabled when removing the last conversation
|
|
89
|
+
|
|
90
|
+
# 3.4.27-rc8
|
|
91
|
+
- **added**: ability to open ticket to external service
|
|
92
|
+
- **added**: ticketSection env var
|
|
93
|
+
|
|
94
|
+
# 3.4.27-rc7
|
|
95
|
+
- **bug-fixed**: Scrolling to the last message when opening a conversation
|
|
96
|
+
- **bug-fixed**: Loading in the conversation list disabled when removing the last conversation
|
|
97
|
+
|
|
98
|
+
# 3.4.27-rc6
|
|
99
|
+
- **bug-fixed**: user for dashboard app is incorrect
|
|
100
|
+
|
|
101
|
+
# 3.4.27-rc5
|
|
102
|
+
- **added**: managed roles in sidebar e navbar
|
|
103
|
+
- **bug-fixed**: projectId and supportMode url is not saved in localstorage
|
|
104
|
+
|
|
105
|
+
# 3.4.27-rc4
|
|
106
|
+
- **bug-fixed**: extractUrls function is not able to detect url start with www or without https/http
|
|
107
|
+
- **bug-fixed**: if message is sent with keydown, error on domain check is not showed
|
|
108
|
+
|
|
109
|
+
# 3.4.27-rc3
|
|
110
|
+
- **bug-fixed**: cannot set user availability if supportMode is enabled and tiledesk_projectID url params is set
|
|
111
|
+
|
|
112
|
+
# 3.4.27-rc2
|
|
113
|
+
- **bug-fixed**: cannede responses role
|
|
114
|
+
|
|
115
|
+
# 3.4.27-rc1
|
|
116
|
+
- **added**: managed canned responses with roles
|
|
117
|
+
- **changed**: name in info mesage
|
|
118
|
+
|
|
20
119
|
# 3.4.26 in PROD
|
|
21
120
|
|
|
22
121
|
# 3.4.26-rc2
|
|
@@ -25,6 +124,7 @@
|
|
|
25
124
|
# 3.4.26-rc1
|
|
26
125
|
- **added**: tiledesk_projectID query param to manage user status
|
|
27
126
|
- **added**: token to managane ticket feature
|
|
127
|
+
- **added**: getOsCode login into utils.ts
|
|
28
128
|
|
|
29
129
|
# 3.4.25 in PROD
|
|
30
130
|
- **changed**: pipe marked to support malicious text input
|
|
@@ -47,6 +147,24 @@
|
|
|
47
147
|
# 3.4.22 in PROD
|
|
48
148
|
- **added**: managed allowed_upload_extentions from project settings
|
|
49
149
|
|
|
150
|
+
# 3.4.21-rc6
|
|
151
|
+
- **added**: managed allowed_upload_extentions from project settings
|
|
152
|
+
|
|
153
|
+
# 3.4.21-rc5
|
|
154
|
+
- **added**: setConversation as read when agent click on it
|
|
155
|
+
|
|
156
|
+
# 3.4.21-rc4
|
|
157
|
+
- **added**: ability to init and decrement new conversation count badge
|
|
158
|
+
|
|
159
|
+
# 3.4.21-rc3
|
|
160
|
+
- **changed**: badge notification for agentDesktop
|
|
161
|
+
|
|
162
|
+
# 3.4.21-rc2
|
|
163
|
+
- **added**: count in newConversation handler event
|
|
164
|
+
|
|
165
|
+
# 3.4.21-rc1
|
|
166
|
+
- **added**: implement badge notification for agentDesktop sw when new conversation is assigned to logged agent
|
|
167
|
+
|
|
50
168
|
# 3.4.21 in PROD
|
|
51
169
|
|
|
52
170
|
# 3.4.20 in PROD
|
|
@@ -60,8 +178,8 @@
|
|
|
60
178
|
- **bug-fixed**: minor fix on ion-texarea element with allowed url domain
|
|
61
179
|
|
|
62
180
|
# 3.4.19-rc1
|
|
63
|
-
- added
|
|
64
|
-
- added
|
|
181
|
+
- **added**: ability to check for if emoji is allowd to be sent in message textarea
|
|
182
|
+
- **added**: ability to check for if url domain is allowd to be sent in message textarea
|
|
65
183
|
|
|
66
184
|
# 3.4.18 in PROD
|
|
67
185
|
|
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',
|
|
@@ -119,7 +122,6 @@ export class AppComponent implements OnInit {
|
|
|
119
122
|
private navService: NavProxyService,
|
|
120
123
|
// public chatPresenceHandler: ChatPresenceHandler,
|
|
121
124
|
public typingService: TypingService,
|
|
122
|
-
public uploadService: UploadService,
|
|
123
125
|
public appStorageService: AppStorageService,
|
|
124
126
|
|
|
125
127
|
// public chatConversationsHandler: ChatConversationsHandler,
|
|
@@ -142,6 +144,7 @@ export class AppComponent implements OnInit {
|
|
|
142
144
|
/**TILEDESK SERVICES */
|
|
143
145
|
private tiledeskService: TiledeskService,
|
|
144
146
|
private projectService: ProjectService,
|
|
147
|
+
private projectUsersService: ProjectUsersService,
|
|
145
148
|
private contactsService: ContactsService
|
|
146
149
|
) {
|
|
147
150
|
|
|
@@ -168,6 +171,7 @@ export class AppComponent implements OnInit {
|
|
|
168
171
|
}, { capture: true });
|
|
169
172
|
}
|
|
170
173
|
|
|
174
|
+
|
|
171
175
|
listenChatAlreadyOpenWithoutParamsInMobileMode() {
|
|
172
176
|
this.events.subscribe('noparams:mobile', (isAlreadyOpenInMobileMode) => {
|
|
173
177
|
// console.log('[APP-COMP] Chat is Already Open In Mobile Mode ', isAlreadyOpenInMobileMode)
|
|
@@ -296,6 +300,10 @@ export class AppComponent implements OnInit {
|
|
|
296
300
|
this.zone = new NgZone({}); // a cosa serve?
|
|
297
301
|
|
|
298
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'])
|
|
299
307
|
}
|
|
300
308
|
|
|
301
309
|
});
|
|
@@ -332,7 +340,7 @@ export class AppComponent implements OnInit {
|
|
|
332
340
|
|
|
333
341
|
listenToPostMsgs() {
|
|
334
342
|
window.addEventListener("message", (event) => {
|
|
335
|
-
this.logger.log("[APP-COMP] message event ", event);
|
|
343
|
+
// this.logger.log("[APP-COMP] message event ", event);
|
|
336
344
|
|
|
337
345
|
if (event && event.data && event.data.action && event.data.parameter) {
|
|
338
346
|
if (event.data.action === 'openJoinConversationModal') {
|
|
@@ -534,10 +542,10 @@ export class AppComponent implements OnInit {
|
|
|
534
542
|
this.statusBar.styleLightContent();
|
|
535
543
|
this.navService.init(this.sidebarNav, this.detailNav);
|
|
536
544
|
this.tiledeskAuthService.initialize(this.appConfigProvider.getConfig().apiUrl);
|
|
537
|
-
|
|
538
|
-
|
|
545
|
+
|
|
539
546
|
// this.currentUserService.initialize();
|
|
540
547
|
this.chatManager.initialize();
|
|
548
|
+
this.messagingAuthService.initialize();
|
|
541
549
|
this.presenceService.initialize(this.tenant);
|
|
542
550
|
this.typingService.initialize(this.tenant);
|
|
543
551
|
|
|
@@ -547,7 +555,6 @@ export class AppComponent implements OnInit {
|
|
|
547
555
|
if (pushEngine && pushEngine !== 'none') {
|
|
548
556
|
this.notificationsService.initialize(this.tenant, vap_id_Key, platform)
|
|
549
557
|
}
|
|
550
|
-
this.uploadService.initialize();
|
|
551
558
|
|
|
552
559
|
this.setLanguage(null)
|
|
553
560
|
this.initAuthentication();
|
|
@@ -864,7 +871,8 @@ export class AppComponent implements OnInit {
|
|
|
864
871
|
// console.log('[APP-COMP] PLATFORM', PLATFORM_MOBILE, 'route.snapshot', this.route.snapshot);
|
|
865
872
|
if (!IDConv) {
|
|
866
873
|
this.logger.log('[APP-COMP] navigateByUrl -- conversations-list');
|
|
867
|
-
|
|
874
|
+
const queryString = window.location.search; // restituisce ad es. "?jwt=...&tiledesk_supportMode=false"
|
|
875
|
+
this.router.navigateByUrl('conversations-list' + queryString);
|
|
868
876
|
}
|
|
869
877
|
// this.router.navigateByUrl(pageUrl);
|
|
870
878
|
// this.navService.setRoot(ConversationListPage, {});
|
|
@@ -1115,13 +1123,19 @@ export class AppComponent implements OnInit {
|
|
|
1115
1123
|
if (conversation && conversation.is_new === true && this.isInitialized) {
|
|
1116
1124
|
this.manageTabNotification('conv_added', conversation.sound)
|
|
1117
1125
|
this.manageEventNewConversation(conversation)
|
|
1126
|
+
//UPDATE NOTIFICATION FOR NEW CONVERSATION COUNT
|
|
1127
|
+
this.triggerOnUpdateNewConversationBadge(this.conversationsHandlerService.countIsNew());
|
|
1118
1128
|
}
|
|
1119
1129
|
if(conversation) this.updateConversationsOnStorage()
|
|
1120
1130
|
});
|
|
1121
1131
|
|
|
1122
1132
|
this.conversationsHandlerService.conversationChanged.subscribe((conversation: ConversationModel) => {
|
|
1123
1133
|
// console.log('[APP-COMP] ***** subscribeConversationChanged conversation: ', conversation);
|
|
1124
|
-
if(conversation)
|
|
1134
|
+
if(conversation){
|
|
1135
|
+
this.updateConversationsOnStorage();
|
|
1136
|
+
//UPDATE NOTIFICATION FOR NEW CONVERSATION COUNT
|
|
1137
|
+
this.triggerOnUpdateNewConversationBadge(this.conversationsHandlerService.countIsNew());
|
|
1138
|
+
}
|
|
1125
1139
|
});
|
|
1126
1140
|
|
|
1127
1141
|
this.conversationsHandlerService.conversationChangedDetailed.subscribe((changes: {value: ConversationModel, previousValue: ConversationModel}) => {
|
|
@@ -1145,6 +1159,8 @@ export class AppComponent implements OnInit {
|
|
|
1145
1159
|
if(conversation) {
|
|
1146
1160
|
this.updateConversationsOnStorage();
|
|
1147
1161
|
this.segmentResolved(conversation);
|
|
1162
|
+
//UPDATE NOTIFICATION FOR NEW CONVERSATION COUNT
|
|
1163
|
+
this.triggerOnUpdateNewConversationBadge(this.conversationsHandlerService.countIsNew());
|
|
1148
1164
|
this.router.navigateByUrl('conversation-detail/'); //redirect to basePage
|
|
1149
1165
|
}
|
|
1150
1166
|
});
|
|
@@ -1178,6 +1194,7 @@ export class AppComponent implements OnInit {
|
|
|
1178
1194
|
this.chatManager.setCurrentUser(currentUser);
|
|
1179
1195
|
|
|
1180
1196
|
this.tiledeskService.initialize(serverBaseURL)
|
|
1197
|
+
this.projectUsersService.initialize(serverBaseURL)
|
|
1181
1198
|
this.projectService.initialize(serverBaseURL)
|
|
1182
1199
|
this.contactsService.initialize(serverBaseURL)
|
|
1183
1200
|
|
|
@@ -1185,11 +1202,14 @@ export class AppComponent implements OnInit {
|
|
|
1185
1202
|
this.events.publish('go:online', true);
|
|
1186
1203
|
// this.chatManager.startApp();
|
|
1187
1204
|
|
|
1205
|
+
|
|
1206
|
+
//INIT WEBSOCKET
|
|
1207
|
+
this.connetWebsocket(tiledeskToken)
|
|
1208
|
+
|
|
1188
1209
|
// ----------------------------------------------
|
|
1189
1210
|
// PUSH NOTIFICATIONS
|
|
1190
1211
|
// ----------------------------------------------
|
|
1191
1212
|
const pushEngine = this.appConfigProvider.getConfig().pushEngine
|
|
1192
|
-
|
|
1193
1213
|
if (currentUser) {
|
|
1194
1214
|
if (pushEngine && pushEngine !== 'none') {
|
|
1195
1215
|
this.notificationsService.getNotificationPermissionAndSaveToken(currentUser.uid);
|
|
@@ -1211,6 +1231,24 @@ export class AppComponent implements OnInit {
|
|
|
1211
1231
|
} catch (err) {
|
|
1212
1232
|
this.logger.error('[APP-COMP] -> error:', err);
|
|
1213
1233
|
}
|
|
1234
|
+
|
|
1235
|
+
// ----------------------------------------------
|
|
1236
|
+
// LAST PROJECT FROM URL
|
|
1237
|
+
// ----------------------------------------------
|
|
1238
|
+
if(this.g.projectID){
|
|
1239
|
+
this.projectService.getProjects().subscribe({ next: (projects: Project[]) => {
|
|
1240
|
+
const project = projects.find(prjct => prjct.id_project._id === this.g.projectID)
|
|
1241
|
+
if(project){
|
|
1242
|
+
this.logger.log('[APP-COMP] - GET PROJECT - project found with this.projectID', project);
|
|
1243
|
+
localStorage.setItem('last_project', JSON.stringify(project))
|
|
1244
|
+
this.events.publish('storage:last_project', project)
|
|
1245
|
+
}
|
|
1246
|
+
}, error: (error) => {
|
|
1247
|
+
this.logger.log('[APP-COMP] - GET PROJECT - project NOT found with this.projectID', this.g.projectID, error);
|
|
1248
|
+
}, complete: () => {
|
|
1249
|
+
|
|
1250
|
+
}});
|
|
1251
|
+
}
|
|
1214
1252
|
}
|
|
1215
1253
|
|
|
1216
1254
|
|
|
@@ -1251,9 +1289,21 @@ export class AppComponent implements OnInit {
|
|
|
1251
1289
|
}
|
|
1252
1290
|
|
|
1253
1291
|
goToDashboardLogin(){
|
|
1254
|
-
let DASHBOARD_URL = this.appConfigProvider.getConfig().dashboardUrl + '#/login'
|
|
1255
|
-
const myWindow = window.open(DASHBOARD_URL, '_self');
|
|
1256
|
-
myWindow.focus();
|
|
1292
|
+
// let DASHBOARD_URL = this.appConfigProvider.getConfig().dashboardUrl + '#/login'
|
|
1293
|
+
// const myWindow = window.open(DASHBOARD_URL, '_self');
|
|
1294
|
+
// myWindow.focus();
|
|
1295
|
+
}
|
|
1296
|
+
|
|
1297
|
+
connetWebsocket(tiledeskToken) {
|
|
1298
|
+
|
|
1299
|
+
this.logger.log('[WEBSOCKET-JS] connetWebsocket called in [PROJECT-ITEM] tiledeskToken ', tiledeskToken)
|
|
1300
|
+
const appconfig = this.appConfigProvider.getConfig();
|
|
1301
|
+
this.logger.log('[WEBSOCKET-JS] connetWebsocket called in [PROJECT-ITEM] wsUrl ', appconfig.wsUrl)
|
|
1302
|
+
const WS_URL = appconfig.wsUrl + '?token=' + tiledeskToken
|
|
1303
|
+
this.logger.log('[WEBSOCKET-JS] connetWebsocket called in [PROJECT-ITEM] wsUrl ', WS_URL)
|
|
1304
|
+
this.webSocketJs.init(
|
|
1305
|
+
WS_URL
|
|
1306
|
+
);
|
|
1257
1307
|
}
|
|
1258
1308
|
|
|
1259
1309
|
|
|
@@ -1352,7 +1402,8 @@ export class AppComponent implements OnInit {
|
|
|
1352
1402
|
|
|
1353
1403
|
subscribeConversationSelected= (conversation: ConversationModel) => {
|
|
1354
1404
|
if(conversation && conversation.is_new){
|
|
1355
|
-
this.audio_NewConv.pause()
|
|
1405
|
+
this.audio_NewConv.pause();
|
|
1406
|
+
this.conversationsHandlerService.setConversationRead(conversation.uid)
|
|
1356
1407
|
}
|
|
1357
1408
|
}
|
|
1358
1409
|
|
|
@@ -1428,6 +1479,9 @@ export class AppComponent implements OnInit {
|
|
|
1428
1479
|
this.logger.debug('[APP-COMP]-CONVS - INIT CONV CONVS 2', conversations)
|
|
1429
1480
|
this.events.publish('appcompSubscribeToConvs:loadingIsActive', false);
|
|
1430
1481
|
}
|
|
1482
|
+
|
|
1483
|
+
//INIT NOTIFICATION FOR NEW CONVERSATION COUNT
|
|
1484
|
+
this.triggerOnUpdateNewConversationBadge(this.conversationsHandlerService.countIsNew());
|
|
1431
1485
|
});
|
|
1432
1486
|
|
|
1433
1487
|
}
|
|
@@ -1710,6 +1764,11 @@ export class AppComponent implements OnInit {
|
|
|
1710
1764
|
this.triggerEvents.triggerOnInit(detailOBJ)
|
|
1711
1765
|
}
|
|
1712
1766
|
|
|
1767
|
+
private triggerOnUpdateNewConversationBadge(count: number){
|
|
1768
|
+
const detailOBJ = { event: 'onUpdateNewConversationBadge', count: count.toString() }
|
|
1769
|
+
this.triggerEvents.triggerOnUpdateNewConversationBadge(detailOBJ)
|
|
1770
|
+
}
|
|
1771
|
+
|
|
1713
1772
|
|
|
1714
1773
|
// @HostListener('mouseenter', ['$event'])
|
|
1715
1774
|
// onMouseEnter(event: any) {
|
|
@@ -15,6 +15,7 @@ export class ImageComponent implements OnInit {
|
|
|
15
15
|
loading: boolean = true
|
|
16
16
|
modal: any
|
|
17
17
|
span: any
|
|
18
|
+
private readonly fallbackSrc = 'assets/img/no_data_found.png'
|
|
18
19
|
|
|
19
20
|
constructor() { }
|
|
20
21
|
|
|
@@ -26,6 +27,24 @@ export class ImageComponent implements OnInit {
|
|
|
26
27
|
this.onElementRendered.emit({element: "image", status:true})
|
|
27
28
|
}
|
|
28
29
|
|
|
30
|
+
onError(event: Event) {
|
|
31
|
+
this.loading = false
|
|
32
|
+
const img = event?.target as HTMLImageElement | null
|
|
33
|
+
if (!img) {
|
|
34
|
+
return
|
|
35
|
+
}
|
|
36
|
+
// avoid infinite loop if fallback image fails too
|
|
37
|
+
if (img.src && img.src.includes(this.fallbackSrc)) {
|
|
38
|
+
return
|
|
39
|
+
}
|
|
40
|
+
img.src = this.fallbackSrc
|
|
41
|
+
// also update metadata so click-to-open uses the fallback consistently
|
|
42
|
+
if (this.metadata) {
|
|
43
|
+
this.metadata.src = this.fallbackSrc
|
|
44
|
+
}
|
|
45
|
+
this.onElementRendered.emit({ element: 'image', status: true })
|
|
46
|
+
}
|
|
47
|
+
|
|
29
48
|
_downloadImage(url: string, fileName: string) {
|
|
30
49
|
// console.log('Image COMP - IMAGE URL ', url)
|
|
31
50
|
// console.log('Image COMP - IMAGE FILENAME ', fileName)
|
|
@@ -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;
|