@chat21/chat21-ionic 3.4.31 → 3.4.32-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 +133 -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 -52
- 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 +43 -17
- package/src/app/pages/unassigned-conversations/unassigned-conversations.page.scss +25 -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 +67 -14
- 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
|
@@ -83,8 +83,12 @@ import { WebsocketService } from 'src/app/services/websocket/websocket.service';
|
|
|
83
83
|
import { Project } from 'src/chat21-core/models/projects';
|
|
84
84
|
import { Globals } from 'src/app/utils/globals';
|
|
85
85
|
import { ProjectService } from 'src/app/services/projects/project.service';
|
|
86
|
-
import { getOSCode } from 'src/app/utils/utils';
|
|
87
86
|
import { UploadService } from 'src/chat21-core/providers/abstract/upload.service';
|
|
87
|
+
import { ProjectUsersService } from 'src/app/services/project_users/project-users.service';
|
|
88
|
+
import { ProjectUser } from 'src/chat21-core/models/projectUsers';
|
|
89
|
+
import { getOSCode, hasRole } from 'src/app/utils/utils';
|
|
90
|
+
import { PERMISSIONS } from 'src/app/utils/permissions.constants';
|
|
91
|
+
import { TriggerEvents } from 'src/app/services/triggerEvents/triggerEvents';
|
|
88
92
|
|
|
89
93
|
@Component({
|
|
90
94
|
selector: 'app-conversation-detail',
|
|
@@ -109,6 +113,7 @@ export class ConversationDetailPage implements OnInit, OnDestroy, AfterViewInit
|
|
|
109
113
|
private subscriptions: Array<any>
|
|
110
114
|
public tenant: string;
|
|
111
115
|
public loggedUser: UserModel
|
|
116
|
+
public projectUser: ProjectUser;
|
|
112
117
|
public conversationWith: string
|
|
113
118
|
public conversationWithFullname: string
|
|
114
119
|
public messages: Array<MessageModel> = []
|
|
@@ -138,6 +143,7 @@ export class ConversationDetailPage implements OnInit, OnDestroy, AfterViewInit
|
|
|
138
143
|
public tagsCannedFilter: Array<any> = [];
|
|
139
144
|
public SHOW_CANNED_RESPONSES: boolean = false
|
|
140
145
|
public canShowCanned: boolean = true
|
|
146
|
+
public rolesCanned: { [key: string]: boolean }
|
|
141
147
|
|
|
142
148
|
public SHOW_COPILOT_SUGGESTIONS: boolean = false;
|
|
143
149
|
|
|
@@ -172,6 +178,10 @@ export class ConversationDetailPage implements OnInit, OnDestroy, AfterViewInit
|
|
|
172
178
|
copilotQuestion: string = '';
|
|
173
179
|
/**COPILOT : end */
|
|
174
180
|
|
|
181
|
+
/** TICKET: start */
|
|
182
|
+
isTicketEnabled: boolean = false;
|
|
183
|
+
/** TICKET: end */
|
|
184
|
+
|
|
175
185
|
isMine = isMine
|
|
176
186
|
isInfo = isInfo
|
|
177
187
|
isFirstMessage = isFirstMessage
|
|
@@ -242,18 +252,20 @@ export class ConversationDetailPage implements OnInit, OnDestroy, AfterViewInit
|
|
|
242
252
|
public toastController: ToastController,
|
|
243
253
|
public tiledeskService: TiledeskService,
|
|
244
254
|
public projectService: ProjectService,
|
|
255
|
+
public projectUsersService: ProjectUsersService,
|
|
245
256
|
private networkService: NetworkService,
|
|
246
257
|
private events: EventsService,
|
|
247
258
|
private webSocketService: WebsocketService,
|
|
248
259
|
public projectPlanUtils: ProjectPlanUtils,
|
|
260
|
+
public triggerEvents: TriggerEvents,
|
|
249
261
|
private g: Globals,
|
|
250
262
|
) {
|
|
251
263
|
// Change list on date change
|
|
252
264
|
this.route.paramMap.subscribe((params) => {
|
|
253
265
|
this.logger.log('[CONVS-DETAIL] - constructor -> params: ', params)
|
|
254
266
|
this.conversationWith = params.get('IDConv')
|
|
255
|
-
this.conversationWithFullname = params.get('FullNameConv')
|
|
256
|
-
this.conv_type = params.get('Convtype')
|
|
267
|
+
this.conversationWithFullname = decodeURIComponent(params.get('FullNameConv'))
|
|
268
|
+
this.conv_type = decodeURIComponent(params.get('Convtype'))
|
|
257
269
|
|
|
258
270
|
this.events.publish('supportconvid:haschanged', this.conversationWith)
|
|
259
271
|
})
|
|
@@ -420,6 +432,8 @@ export class ConversationDetailPage implements OnInit, OnDestroy, AfterViewInit
|
|
|
420
432
|
ionViewDidEnter() {
|
|
421
433
|
this.logger.log('[CONVS-DETAIL] > ionViewDidEnter')
|
|
422
434
|
// this.info_content_child_enabled = true;
|
|
435
|
+
// Scroll to bottom to show the last message without animation
|
|
436
|
+
this.scrollToLastMessage()
|
|
423
437
|
}
|
|
424
438
|
|
|
425
439
|
// Unsubscibe when new page transition end
|
|
@@ -479,6 +493,7 @@ export class ConversationDetailPage implements OnInit, OnDestroy, AfterViewInit
|
|
|
479
493
|
this.messages = [] // list messages of conversation
|
|
480
494
|
this.isFileSelected = false // indicates if a file has been selected (image to upload)
|
|
481
495
|
this.isEmailEnabled = (this.appConfigProvider.getConfig().emailSection === 'true' || this.appConfigProvider.getConfig().emailSection === true) ? true : false;
|
|
496
|
+
this.isTicketEnabled = (this.appConfigProvider.getConfig().ticketSection === 'true' || this.appConfigProvider.getConfig().ticketSection === true) ? true : false;
|
|
482
497
|
this.isWhatsappTemplatesEnabled = (this.appConfigProvider.getConfig().whatsappTemplatesSection === 'true' || this.appConfigProvider.getConfig().whatsappTemplatesSection === true) ? true : false;
|
|
483
498
|
this.fileUploadAccept = this.appConfigProvider.getConfig().fileUploadAccept
|
|
484
499
|
|
|
@@ -538,7 +553,6 @@ export class ConversationDetailPage implements OnInit, OnDestroy, AfterViewInit
|
|
|
538
553
|
this.logger.log('[CONVS-DETAIL] - GET PROJECTID BY CONV RECIPIENT * COMPLETE *',)
|
|
539
554
|
})
|
|
540
555
|
}else {
|
|
541
|
-
this.canShowCanned = false;
|
|
542
556
|
this.offlineMsgEmail = false;
|
|
543
557
|
}
|
|
544
558
|
|
|
@@ -549,10 +563,13 @@ export class ConversationDetailPage implements OnInit, OnDestroy, AfterViewInit
|
|
|
549
563
|
this.logger.log('[CONVS-DETAIL] - GET PROJECTID BY CONV RECIPIENT RES', project)
|
|
550
564
|
if (project) {
|
|
551
565
|
const projectId = project.id_project
|
|
552
|
-
this.
|
|
566
|
+
this.projectUser = await this.projectUsersService.getProjectUserByProjectId(project._id)
|
|
553
567
|
this.offlineMsgEmail = this.checkOfflineMsgEmailIsEnabled(project)
|
|
554
568
|
this.isCopilotEnabled = this.projectPlanUtils.checkProjectProfileFeature(project, 'copilot');
|
|
555
569
|
this.fileUploadAccept = this.checkAcceptedUploadFile(project)
|
|
570
|
+
this.rolesCanned = this.checkCannedResponsesRoles()
|
|
571
|
+
this.canShowCanned = this.checkCannedResponses(project)
|
|
572
|
+
this.logger.log('[CONVS-DETAIL] this.rolesCanned ', this.canShowCanned)
|
|
556
573
|
}
|
|
557
574
|
}, (error) => {
|
|
558
575
|
this.logger.error('[CONVS-DETAIL] - GET PROJECTID BY CONV RECIPIENT - ERROR ', error)
|
|
@@ -590,6 +607,40 @@ export class ConversationDetailPage implements OnInit, OnDestroy, AfterViewInit
|
|
|
590
607
|
return this.appConfigProvider.getConfig().fileUploadAccept
|
|
591
608
|
}
|
|
592
609
|
|
|
610
|
+
checkCannedResponses(project: Project): boolean {
|
|
611
|
+
let expires = this.projectPlanUtils.checkPlanIsExpired(project)
|
|
612
|
+
this.logger.log('[CONVS-DETAIL] checkCannedResponses expires ', expires)
|
|
613
|
+
if(expires){
|
|
614
|
+
return false
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
let hasRoleToShowCanned = this.rolesCanned[PERMISSIONS.CANNED_RESPONSES_READ]
|
|
618
|
+
this.logger.log('[CONVS-DETAIL] checkCannedResponses hasRoleToShowCanned ', hasRoleToShowCanned)
|
|
619
|
+
if(!hasRoleToShowCanned){
|
|
620
|
+
return false
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
return true
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
checkCannedResponsesRoles(): { [key: string]: boolean } {
|
|
627
|
+
const permissionKeys = [
|
|
628
|
+
'CANNED_RESPONSES_CREATE',
|
|
629
|
+
'CANNED_RESPONSES_READ',
|
|
630
|
+
'CANNED_RESPONSES_UPDATE',
|
|
631
|
+
'CANNED_RESPONSES_DELETE',
|
|
632
|
+
] as const;
|
|
633
|
+
|
|
634
|
+
const roles: { [key: string]: boolean } = {};
|
|
635
|
+
for (const key of permissionKeys) {
|
|
636
|
+
const permission = PERMISSIONS[key];
|
|
637
|
+
roles[permission] = hasRole(this.projectUser, permission);
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
return roles;
|
|
641
|
+
|
|
642
|
+
}
|
|
643
|
+
|
|
593
644
|
// getProjectIdSelectedConversation(conversationWith: string): string{
|
|
594
645
|
// const conversationWith_segments = conversationWith.split('-')
|
|
595
646
|
// // Removes the last element of the array if is = to the separator
|
|
@@ -673,6 +724,11 @@ export class ConversationDetailPage implements OnInit, OnDestroy, AfterViewInit
|
|
|
673
724
|
"WHATSAPP.ERROR_WHATSAPP_NOT_INSTALLED",
|
|
674
725
|
"WHATSAPP.ERROR_WHATSAPP_GENERIC_ERROR",
|
|
675
726
|
|
|
727
|
+
"TICKET.OPEN_TICKET",
|
|
728
|
+
"TICKET.DESCRIPTION",
|
|
729
|
+
"TICKET.CONFIRM",
|
|
730
|
+
"TICKET.CLOSE",
|
|
731
|
+
|
|
676
732
|
"COPILOT.ASK_AI",
|
|
677
733
|
"COPILOT.NO_SUGGESTIONS_PRESENT",
|
|
678
734
|
|
|
@@ -1888,6 +1944,11 @@ export class ConversationDetailPage implements OnInit, OnDestroy, AfterViewInit
|
|
|
1888
1944
|
}
|
|
1889
1945
|
|
|
1890
1946
|
|
|
1947
|
+
onOpenTicket(event) {
|
|
1948
|
+
this.logger.debug('[CONVS-DETAIL] openTicketOnExternalService - conversationWith ', this.conversationWith)
|
|
1949
|
+
const detailOBJ = { event: 'onOpenTicketExternally', request_id: this.conversationWith, conversation: this.conversation }
|
|
1950
|
+
this.triggerEvents.triggerOnOpenTicketExternally(detailOBJ)
|
|
1951
|
+
}
|
|
1891
1952
|
// -------------- START SCROLL/RESIZE -------------- //
|
|
1892
1953
|
/** */
|
|
1893
1954
|
resizeTextArea() {
|
|
@@ -1931,6 +1992,29 @@ export class ConversationDetailPage implements OnInit, OnDestroy, AfterViewInit
|
|
|
1931
1992
|
}
|
|
1932
1993
|
}
|
|
1933
1994
|
|
|
1995
|
+
/**
|
|
1996
|
+
* Scroll to last message without animation using requestAnimationFrame
|
|
1997
|
+
* This is a best practice alternative to setTimeout
|
|
1998
|
+
*/
|
|
1999
|
+
private scrollToLastMessage() {
|
|
2000
|
+
this.showIonContent = true
|
|
2001
|
+
if (this.ionContentChatArea) {
|
|
2002
|
+
// Use requestAnimationFrame for better performance
|
|
2003
|
+
requestAnimationFrame(() => {
|
|
2004
|
+
requestAnimationFrame(() => {
|
|
2005
|
+
// Double RAF ensures DOM is fully rendered
|
|
2006
|
+
this.ionContentChatArea.scrollToBottom(0).then(() => {
|
|
2007
|
+
this.logger.log('[CONVS-DETAIL] scroll posizionato all\'ultimo messaggio')
|
|
2008
|
+
}).catch((error) => {
|
|
2009
|
+
this.logger.error('[CONVS-DETAIL] errore durante lo scroll:', error)
|
|
2010
|
+
})
|
|
2011
|
+
})
|
|
2012
|
+
})
|
|
2013
|
+
} else {
|
|
2014
|
+
this.logger.warn('[CONVS-DETAIL] ionContentChatArea non disponibile')
|
|
2015
|
+
}
|
|
2016
|
+
}
|
|
2017
|
+
|
|
1934
2018
|
/**
|
|
1935
2019
|
* detectBottom
|
|
1936
2020
|
*/
|
|
@@ -19,8 +19,7 @@ import { ProfileInfoPageModule } from '../profile-info/profile-info.module';
|
|
|
19
19
|
// import { ConversationDetailPageModule } from '../conversation-detail/conversation-detail.module';
|
|
20
20
|
import { SharedModule } from 'src/app/shared/shared.module';
|
|
21
21
|
import { ScrollbarThemeModule } from '../../utils/scrollbar-theme.directive';
|
|
22
|
-
import {
|
|
23
|
-
import { IonListConversationsComponent } from 'src/app/chatlib/list-conversations-component/ion-list-conversations/ion-list-conversations.component';
|
|
22
|
+
import { ListConversationsModule } from 'src/app/chatlib/list-conversations-component/list-conversations.module';
|
|
24
23
|
import { HeaderConversationsList } from 'src/app/components/conversations-list/header-conversations-list/header-conversations-list.component';
|
|
25
24
|
import { HeaderConversationsListArchived } from 'src/app/components/conversations-list/header-conversations-list-archived/header-conversations-list-archived.component';
|
|
26
25
|
import { HeaderConversationsListUnassigned } from 'src/app/components/conversations-list/header-conversations-list-unassigned/header-conversations-list-unassigned.component';
|
|
@@ -46,14 +45,13 @@ import { MomentModule } from 'ngx-moment';
|
|
|
46
45
|
}
|
|
47
46
|
}),
|
|
48
47
|
SharedModule,
|
|
49
|
-
MomentModule
|
|
48
|
+
MomentModule,
|
|
49
|
+
ListConversationsModule
|
|
50
50
|
],
|
|
51
51
|
// entryComponents: [DdpHeaderComponent],
|
|
52
52
|
declarations: [
|
|
53
53
|
ConversationListPage,
|
|
54
54
|
//******** COMPONENTS - init ********//
|
|
55
|
-
ListConversationsComponent,
|
|
56
|
-
IonListConversationsComponent,
|
|
57
55
|
HeaderConversationsList,
|
|
58
56
|
HeaderConversationsListArchived,
|
|
59
57
|
HeaderConversationsListUnassigned,
|
|
@@ -7,6 +7,8 @@
|
|
|
7
7
|
[sound_btn]="sound_btn"
|
|
8
8
|
[isMobile]="isMobile"
|
|
9
9
|
[isVisibleTKT]="isVisibleTKT"
|
|
10
|
+
[isVisibleCNT]="isVisibleCNT"
|
|
11
|
+
[roles]="rolesHeader"
|
|
10
12
|
(onSoundChange)="onSoundChange($event)"
|
|
11
13
|
(openContactsDirectory)=openContactsDirectory($event)
|
|
12
14
|
(openProfileInfo)=openProfileInfo($event)>
|
|
@@ -53,7 +53,10 @@ import { Globals } from 'src/app/utils/globals';
|
|
|
53
53
|
import { TriggerEvents } from 'src/app/services/triggerEvents/triggerEvents';
|
|
54
54
|
import { MessageModel } from 'src/chat21-core/models/message';
|
|
55
55
|
import { Project } from 'src/chat21-core/models/projects';
|
|
56
|
-
import { getOSCode } from 'src/app/utils/utils';
|
|
56
|
+
import { getOSCode, hasRole } from 'src/app/utils/utils';
|
|
57
|
+
import { PERMISSIONS } from 'src/app/utils/permissions.constants';
|
|
58
|
+
import { ProjectUser } from 'src/chat21-core/models/projectUsers';
|
|
59
|
+
import { ProjectUsersService } from 'src/app/services/project_users/project-users.service';
|
|
57
60
|
|
|
58
61
|
@Component({
|
|
59
62
|
selector: 'app-conversations-list',
|
|
@@ -82,6 +85,7 @@ export class ConversationListPage implements OnInit {
|
|
|
82
85
|
public archived_btn: boolean
|
|
83
86
|
public sound_btn: string
|
|
84
87
|
public isVisibleTKT: boolean = true;
|
|
88
|
+
public isVisibleCNT: boolean = true;;
|
|
85
89
|
public convertMessage = convertMessage
|
|
86
90
|
private isShowMenuPage = false
|
|
87
91
|
private logger: LoggerService = LoggerInstance.getInstance()
|
|
@@ -104,6 +108,9 @@ export class ConversationListPage implements OnInit {
|
|
|
104
108
|
public isMobile: boolean = false;
|
|
105
109
|
public isInitialized: boolean = false;
|
|
106
110
|
|
|
111
|
+
public projectUser: ProjectUser;
|
|
112
|
+
public rolesHeader: { [key: string]: boolean }
|
|
113
|
+
|
|
107
114
|
// PROJECT AVAILABILITY INFO: start
|
|
108
115
|
project: Project
|
|
109
116
|
profile_name_translated: string;
|
|
@@ -130,6 +137,7 @@ export class ConversationListPage implements OnInit {
|
|
|
130
137
|
private translateService: CustomTranslateService,
|
|
131
138
|
public tiledeskService: TiledeskService,
|
|
132
139
|
public tiledeskAuthService: TiledeskAuthService,
|
|
140
|
+
public projectUsersService: ProjectUsersService,
|
|
133
141
|
public appConfigProvider: AppConfigProvider,
|
|
134
142
|
public platform: Platform,
|
|
135
143
|
public wsService: WebsocketService,
|
|
@@ -294,17 +302,19 @@ export class ConversationListPage implements OnInit {
|
|
|
294
302
|
// ---------------------------------------------------------
|
|
295
303
|
// Opens the Unassigned Conversations iframe
|
|
296
304
|
// ---------------------------------------------------------
|
|
297
|
-
openUnassignedConversations(IFRAME_URL: string, event) {
|
|
305
|
+
openUnassignedConversations(IFRAME_URL: string, event: { event: string; data: ConversationModel[] }) {
|
|
306
|
+
const unassignedConversations = event?.data ?? [];
|
|
307
|
+
const params = {
|
|
308
|
+
iframe_URL: IFRAME_URL,
|
|
309
|
+
callerBtn: event.event,
|
|
310
|
+
unassignedConversations,
|
|
311
|
+
stylesMap: this.stylesMap,
|
|
312
|
+
translationMapConversation: this.translationMapConversation,
|
|
313
|
+
};
|
|
298
314
|
if (checkPlatformIsMobile()) {
|
|
299
|
-
presentModal(this.modalController, UnassignedConversationsPage,
|
|
300
|
-
iframe_URL: IFRAME_URL,
|
|
301
|
-
callerBtn: event,
|
|
302
|
-
})
|
|
315
|
+
presentModal(this.modalController, UnassignedConversationsPage, params);
|
|
303
316
|
} else {
|
|
304
|
-
this.navService.push(UnassignedConversationsPage,
|
|
305
|
-
iframe_URL: IFRAME_URL,
|
|
306
|
-
callerBtn: event,
|
|
307
|
-
})
|
|
317
|
+
this.navService.push(UnassignedConversationsPage, params);
|
|
308
318
|
}
|
|
309
319
|
}
|
|
310
320
|
|
|
@@ -371,6 +381,11 @@ export class ConversationListPage implements OnInit {
|
|
|
371
381
|
// save conversationHandler in chatManager
|
|
372
382
|
this.chatManager.setConversationsHandler(this.conversationsHandlerService)
|
|
373
383
|
this.showPlaceholder = false
|
|
384
|
+
|
|
385
|
+
// Hide loading spinner if there are no conversations
|
|
386
|
+
if (this.conversations.length === 0) {
|
|
387
|
+
this.loadingIsActive = false
|
|
388
|
+
}
|
|
374
389
|
}
|
|
375
390
|
|
|
376
391
|
// private manageStoredConversations() {
|
|
@@ -471,7 +486,7 @@ export class ConversationListPage implements OnInit {
|
|
|
471
486
|
}
|
|
472
487
|
|
|
473
488
|
listenToCurrentStoredProject() {
|
|
474
|
-
this.events.subscribe('storage:last_project', projectObjct => {
|
|
489
|
+
this.events.subscribe('storage:last_project', async(projectObjct) => {
|
|
475
490
|
if (projectObjct && projectObjct !== 'undefined') {
|
|
476
491
|
this.logger.log('[CONVS-LIST-PAGE] - GET STORED PROJECT ', projectObjct)
|
|
477
492
|
|
|
@@ -496,6 +511,10 @@ export class ConversationListPage implements OnInit {
|
|
|
496
511
|
} else if (this.project.profile.type === 'payment' && this.project.profile.name === 'enterprise') {
|
|
497
512
|
this.profile_name_translated = this.translationMapHeader.get('PaydPlanNameEnterprise');
|
|
498
513
|
}
|
|
514
|
+
|
|
515
|
+
this.projectUser = await this.projectUsersService.getProjectUserByProjectId(this.project._id)
|
|
516
|
+
this.rolesHeader = this.checkCannedResponsesRoles();
|
|
517
|
+
this.logger.log('[CONVS-LIST-PAGE] - GET PROJECT USER ROLES ', this.rolesHeader)
|
|
499
518
|
}
|
|
500
519
|
})
|
|
501
520
|
}
|
|
@@ -631,8 +650,24 @@ export class ConversationListPage implements OnInit {
|
|
|
631
650
|
const public_Key = this.appConfigProvider.getConfig().t2y12PruGU9wUtEGzBJfolMIgK
|
|
632
651
|
this.logger.log('[CONVS-LIST-PAGE] AppConfigService getAppConfig public_Key', public_Key)
|
|
633
652
|
this.isVisibleTKT = getOSCode("TKT", public_Key);
|
|
653
|
+
this.isVisibleCNT = getOSCode("CNT", public_Key);
|
|
634
654
|
}
|
|
635
655
|
|
|
656
|
+
checkCannedResponsesRoles(): { [key: string]: boolean } {
|
|
657
|
+
const permissionKeys = [
|
|
658
|
+
'LEADS_READ',
|
|
659
|
+
] as const;
|
|
660
|
+
|
|
661
|
+
const roles: { [key: string]: boolean } = {};
|
|
662
|
+
for (const key of permissionKeys) {
|
|
663
|
+
const permission = PERMISSIONS[key];
|
|
664
|
+
roles[permission] = hasRole(this.projectUser, permission);
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
return roles;
|
|
668
|
+
|
|
669
|
+
}
|
|
670
|
+
|
|
636
671
|
onBackButtonFN(event) {
|
|
637
672
|
this.conversationType = 'active'
|
|
638
673
|
|
|
@@ -883,6 +918,10 @@ export class ConversationListPage implements OnInit {
|
|
|
883
918
|
|
|
884
919
|
this.logger.log('[CONVS-LIST-PAGE] navigateByUrl this.uidConvSelected ', this.uidConvSelected)
|
|
885
920
|
|
|
921
|
+
const queryParams = this.route.snapshot.queryParams;
|
|
922
|
+
const queryString = new URLSearchParams(queryParams).toString();
|
|
923
|
+
|
|
924
|
+
|
|
886
925
|
this.setUidConvSelected(uidConvSelected, converationType)
|
|
887
926
|
if (checkPlatformIsMobile()) {
|
|
888
927
|
this.logger.log('[CONVS-LIST-PAGE] checkPlatformIsMobile(): ', checkPlatformIsMobile())
|
|
@@ -900,6 +939,7 @@ export class ConversationListPage implements OnInit {
|
|
|
900
939
|
if (this.conversationSelected && this.conversationSelected.conversation_with_fullname) {
|
|
901
940
|
pageUrl = 'conversation-detail/' + this.uidConvSelected + '/' + encodeURIComponent(this.conversationSelected.conversation_with_fullname) + '/' + converationType
|
|
902
941
|
}
|
|
942
|
+
pageUrl += queryString ? `?${queryString}` : '';
|
|
903
943
|
this.logger.log('[CONVS-LIST-PAGE] setUidConvSelected navigateByUrl--->: ', pageUrl)
|
|
904
944
|
// replace(/\(/g, '%28').replace(/\)/g, '%29') -> used for the encoder of any round brackets
|
|
905
945
|
this.router.navigateByUrl(pageUrl.replace(/\(/g, '%28').replace(/\)/g, '%29'), {replaceUrl: true})
|
|
@@ -1,22 +1,34 @@
|
|
|
1
1
|
import { NgModule } from '@angular/core';
|
|
2
2
|
import { CommonModule } from '@angular/common';
|
|
3
3
|
import { FormsModule } from '@angular/forms';
|
|
4
|
+
import { HttpClient } from '@angular/common/http';
|
|
4
5
|
|
|
5
6
|
import { IonicModule } from '@ionic/angular';
|
|
7
|
+
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
|
|
8
|
+
import { createTranslateLoader } from 'src/chat21-core/utils/utils';
|
|
6
9
|
|
|
7
10
|
import { UnassignedConversationsPageRoutingModule } from './unassigned-conversations-routing.module';
|
|
8
11
|
|
|
9
12
|
import { UnassignedConversationsPage } from './unassigned-conversations.page';
|
|
13
|
+
import { ListConversationsModule } from 'src/app/chatlib/list-conversations-component/list-conversations.module';
|
|
14
|
+
import { MomentModule } from 'ngx-moment';
|
|
10
15
|
|
|
11
16
|
@NgModule({
|
|
12
17
|
imports: [
|
|
13
18
|
CommonModule,
|
|
14
19
|
FormsModule,
|
|
15
20
|
IonicModule,
|
|
16
|
-
UnassignedConversationsPageRoutingModule
|
|
21
|
+
UnassignedConversationsPageRoutingModule,
|
|
22
|
+
MomentModule,
|
|
23
|
+
ListConversationsModule,
|
|
24
|
+
TranslateModule.forChild({
|
|
25
|
+
loader: {
|
|
26
|
+
provide: TranslateLoader,
|
|
27
|
+
useFactory: createTranslateLoader,
|
|
28
|
+
deps: [HttpClient],
|
|
29
|
+
},
|
|
30
|
+
}),
|
|
17
31
|
],
|
|
18
|
-
declarations: [
|
|
19
|
-
UnassignedConversationsPage,
|
|
20
|
-
]
|
|
32
|
+
declarations: [UnassignedConversationsPage]
|
|
21
33
|
})
|
|
22
34
|
export class UnassignedConversationsPageModule {}
|
|
@@ -1,27 +1,53 @@
|
|
|
1
|
-
<ion-
|
|
2
|
-
<ion-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
</ion-
|
|
1
|
+
<ion-toolbar [class.mobile]="isMobile">
|
|
2
|
+
<ion-title *ngIf="callerBtn !== 'pinbtn'" style="font-size: 16px;">
|
|
3
|
+
{{translationMap?.get('UnassignedConversations') }}
|
|
4
|
+
</ion-title>
|
|
5
|
+
<ion-title *ngIf="callerBtn === 'pinbtn'" style="font-size: 16px;">
|
|
6
|
+
{{translationMap?.get('PIN_A_PROJECT') }}
|
|
7
|
+
</ion-title>
|
|
8
|
+
|
|
9
|
+
<ion-buttons slot="end">
|
|
10
|
+
<ion-button ion-button fill="clear" (click)="onClose()">
|
|
11
|
+
<ion-icon slot="icon-only" name="close"></ion-icon>
|
|
12
|
+
</ion-button>
|
|
13
|
+
</ion-buttons>
|
|
14
|
+
|
|
15
|
+
</ion-toolbar>
|
|
16
16
|
|
|
17
17
|
<ion-content overflow-scroll="true" id="iframe-ion-content"
|
|
18
18
|
[ngClass]="{'ion-content-black-background' : isProjectsForPanel === true}">
|
|
19
|
-
|
|
20
|
-
<div class="loader-spinner-wpr">
|
|
19
|
+
<div *ngIf="callerBtn === 'pinbtn'" class="loader-spinner-wpr">
|
|
21
20
|
<div id="loader" class="loader">
|
|
22
21
|
<svg class="circular" viewBox="25 25 50 50">
|
|
23
22
|
<circle class="path" cx="50" cy="50" r="20" fill="none" stroke-width="2" stroke-miterlimit="10" />
|
|
24
23
|
</svg>
|
|
25
24
|
</div>
|
|
26
25
|
</div>
|
|
26
|
+
|
|
27
|
+
<div *ngIf="callerBtn !== 'pinbtn'" class="list-avatar-page">
|
|
28
|
+
<ion-list>
|
|
29
|
+
<ng-container *ngIf="unassignedConversationsList.length > 0; else noConvs">
|
|
30
|
+
<ion-list-conversations
|
|
31
|
+
[listConversations]="unassignedConversationsList"
|
|
32
|
+
[stylesMap]="stylesMap"
|
|
33
|
+
[translationMap]="translationMapConversation"
|
|
34
|
+
[uidConvSelected]="uidConvSelected"
|
|
35
|
+
(onConversationSelected)="onConversationSelected($event)"
|
|
36
|
+
(onCloseConversation)="onCloseConversation($event)"
|
|
37
|
+
(onJoinConversation)="onJoinConversation($event)"
|
|
38
|
+
(onImageLoaded)="onImageLoaded($event)"
|
|
39
|
+
(onConversationLoaded)="onConversationLoaded($event)">
|
|
40
|
+
</ion-list-conversations>
|
|
41
|
+
</ng-container>
|
|
42
|
+
<ng-template #noConvs>
|
|
43
|
+
<div class="no-convs-container">
|
|
44
|
+
<ion-item id="no-convs" class="ion-text-center" lines="none">
|
|
45
|
+
<ion-label class="ion-text-wrap" color="medium">
|
|
46
|
+
{{ 'LABEL_MSG_PUSH_START_CHAT' | translate }}
|
|
47
|
+
</ion-label>
|
|
48
|
+
</ion-item>
|
|
49
|
+
</div>
|
|
50
|
+
</ng-template>
|
|
51
|
+
</ion-list>
|
|
52
|
+
</div>
|
|
27
53
|
</ion-content>
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
ion-toolbar {
|
|
2
2
|
height: var(--header-height);
|
|
3
|
+
--background: transparent;
|
|
3
4
|
&:not(.mobile){
|
|
4
5
|
--background: var(--list-bkg-color);
|
|
5
6
|
border: none;
|
|
@@ -20,7 +21,7 @@ ion-content {
|
|
|
20
21
|
// Forcing `--overflow: hidden` breaks scrolling (Chrome >= 144 is stricter here).
|
|
21
22
|
--overflow: auto;
|
|
22
23
|
&:not(.mobile){
|
|
23
|
-
--background: var(--
|
|
24
|
+
--background: var(--bacis-white);
|
|
24
25
|
}
|
|
25
26
|
}
|
|
26
27
|
|
|
@@ -224,3 +225,26 @@ ion-content::part(scroll) {
|
|
|
224
225
|
.hide-stretchspinner {
|
|
225
226
|
display: none;
|
|
226
227
|
}
|
|
228
|
+
|
|
229
|
+
// -------------------------------------------------
|
|
230
|
+
// List avatar page - full viewport height
|
|
231
|
+
// -------------------------------------------------
|
|
232
|
+
.list-avatar-page {
|
|
233
|
+
min-height: calc(100vh - var(--header-height, 56px));
|
|
234
|
+
height: 100%;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// -------------------------------------------------
|
|
238
|
+
// Empty state - label centrata nell'altezza disponibile
|
|
239
|
+
// -------------------------------------------------
|
|
240
|
+
.no-convs-container {
|
|
241
|
+
display: flex;
|
|
242
|
+
align-items: center;
|
|
243
|
+
justify-content: center;
|
|
244
|
+
min-height: calc(100vh - var(--header-height, 56px));
|
|
245
|
+
width: 100%;
|
|
246
|
+
|
|
247
|
+
ion-item {
|
|
248
|
+
--background: transparent;
|
|
249
|
+
}
|
|
250
|
+
}
|