@chat21/chat21-ionic 3.4.27-rc1 → 3.4.27-rc10

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.
Files changed (45) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/angular.json +1 -0
  3. package/package.json +1 -1
  4. package/src/app/app.component.ts +46 -2
  5. package/src/app/components/canned-response/canned-response.component.scss +0 -2
  6. package/src/app/components/conversation-detail/message-text-area/message-text-area.component.html +23 -0
  7. package/src/app/components/conversation-detail/message-text-area/message-text-area.component.scss +30 -0
  8. package/src/app/components/conversation-detail/message-text-area/message-text-area.component.ts +26 -7
  9. package/src/app/components/conversation-info/info-group/info-group.component.ts +23 -21
  10. package/src/app/components/conversations-list/header-conversations-list/header-conversations-list.component.html +1 -1
  11. package/src/app/components/conversations-list/header-conversations-list/header-conversations-list.component.ts +5 -1
  12. package/src/app/components/navbar/navbar.component.html +3 -3
  13. package/src/app/components/navbar/navbar.component.ts +29 -38
  14. package/src/app/components/project-item/project-item.component.ts +11 -11
  15. package/src/app/components/sidebar/sidebar.component.html +65 -45
  16. package/src/app/components/sidebar/sidebar.component.ts +92 -117
  17. package/src/app/components/sidebar-user-details/sidebar-user-details.component.html +2 -2
  18. package/src/app/components/sidebar-user-details/sidebar-user-details.component.ts +9 -7
  19. package/src/app/pages/conversation-detail/conversation-detail.page.html +3 -1
  20. package/src/app/pages/conversation-detail/conversation-detail.page.ts +47 -5
  21. package/src/app/pages/conversations-list/conversations-list.page.html +2 -0
  22. package/src/app/pages/conversations-list/conversations-list.page.ts +36 -3
  23. package/src/app/services/global-settings/global-settings.service.ts +5 -2
  24. package/src/app/shared/shared.module.ts +11 -0
  25. package/src/app/utils/permissions.constants.ts +14 -11
  26. package/src/assets/i18n/ar.json +11 -1
  27. package/src/assets/i18n/az.json +11 -1
  28. package/src/assets/i18n/de.json +11 -1
  29. package/src/assets/i18n/en.json +11 -1
  30. package/src/assets/i18n/es.json +11 -1
  31. package/src/assets/i18n/fr.json +11 -1
  32. package/src/assets/i18n/it.json +13 -3
  33. package/src/assets/i18n/kk.json +11 -1
  34. package/src/assets/i18n/pt.json +11 -1
  35. package/src/assets/i18n/ru.json +11 -1
  36. package/src/assets/i18n/sr.json +11 -1
  37. package/src/assets/i18n/sv.json +11 -1
  38. package/src/assets/i18n/tr.json +11 -1
  39. package/src/assets/i18n/uk.json +11 -1
  40. package/src/assets/i18n/uz.json +12 -1
  41. package/src/assets/js/agentDesktop-sdk.js +47 -0
  42. package/src/chat-config-template.json +1 -0
  43. package/src/chat-config.json +1 -0
  44. package/src/chat21-core/providers/tiledesk/tiledesk-auth.service.ts +3 -0
  45. package/src/chat21-core/utils/utils.ts +10 -2
package/CHANGELOG.md CHANGED
@@ -8,6 +8,39 @@
8
8
  ### **Copyrigth**:
9
9
  *Tiledesk SRL*
10
10
 
11
+ # 3.4.27-rc10
12
+ - **added**: ability to manage header-conversation-list with roles
13
+ - **bug-fixed**: members in group list not loaded
14
+
15
+ # 3.4.27-rc9
16
+ - **bug-fixed**: Scrolling to the last message when opening a conversation
17
+ - **bug-fixed**: Loading in the conversation list disabled when removing the last conversation
18
+
19
+ # 3.4.27-rc8
20
+ - **added**: ability to open ticket to external service
21
+ - **added**: ticketSection env var
22
+
23
+ # 3.4.27-rc7
24
+ - **bug-fixed**: Scrolling to the last message when opening a conversation
25
+ - **bug-fixed**: Loading in the conversation list disabled when removing the last conversation
26
+
27
+ # 3.4.27-rc6
28
+ - **bug-fixed**: user for dashboard app is incorrect
29
+
30
+ # 3.4.27-rc5
31
+ - **added**: managed roles in sidebar e navbar
32
+ - **bug-fixed**: projectId and supportMode url is not saved in localstorage
33
+
34
+ # 3.4.27-rc4
35
+ - **bug-fixed**: extractUrls function is not able to detect url start with www or without https/http
36
+ - **bug-fixed**: if message is sent with keydown, error on domain check is not showed
37
+
38
+ # 3.4.27-rc3
39
+ - **bug-fixed**: cannot set user availability if supportMode is enabled and tiledesk_projectID url params is set
40
+
41
+ # 3.4.27-rc2
42
+ - **bug-fixed**: cannede responses role
43
+
11
44
  # 3.4.27-rc1
12
45
  - **added**: managed canned responses with roles
13
46
  - **changed**: name in info mesage
package/angular.json CHANGED
@@ -32,6 +32,7 @@
32
32
  "src/chat-config-template.json",
33
33
  "src/chat-config.json",
34
34
  "src/chat-config-dev.json",
35
+ "src/chat-config-native-ar.json",
35
36
  {
36
37
  "glob": "**/*",
37
38
  "input": "src/assets",
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@chat21/chat21-ionic",
3
3
  "author": "Tiledesk SRL",
4
- "version": "3.4.27-rc1",
4
+ "version": "3.4.27-rc10",
5
5
  "license": "MIT License",
6
6
  "homepage": "https://tiledesk.com/",
7
7
  "repository": {
@@ -44,6 +44,7 @@ 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';
47
48
  import { ProjectUsersService } from './services/project_users/project-users.service';
48
49
 
49
50
  @Component({
@@ -299,6 +300,7 @@ export class AppComponent implements OnInit {
299
300
  this.zone = new NgZone({}); // a cosa serve?
300
301
 
301
302
  this.SUPPORT_MODE = this.g.supportMode
303
+ this.logger.info('[APP-COMP] this.SUPPORT_MODE', this.SUPPORT_MODE)
302
304
  }
303
305
 
304
306
  });
@@ -867,7 +869,8 @@ export class AppComponent implements OnInit {
867
869
  // console.log('[APP-COMP] PLATFORM', PLATFORM_MOBILE, 'route.snapshot', this.route.snapshot);
868
870
  if (!IDConv) {
869
871
  this.logger.log('[APP-COMP] navigateByUrl -- conversations-list');
870
- this.router.navigateByUrl('conversations-list')
872
+ const queryString = window.location.search; // restituisce ad es. "?jwt=...&tiledesk_supportMode=false"
873
+ this.router.navigateByUrl('conversations-list' + queryString);
871
874
  }
872
875
  // this.router.navigateByUrl(pageUrl);
873
876
  // this.navService.setRoot(ConversationListPage, {});
@@ -891,6 +894,11 @@ export class AppComponent implements OnInit {
891
894
  if (IDConv && FullNameConv) {
892
895
  pageUrl += IDConv + '/' + FullNameConv + '/' + Convtype
893
896
  }
897
+
898
+ const queryParams = this.route.snapshot.queryParams;
899
+ const queryString = new URLSearchParams(queryParams).toString();
900
+ pageUrl += queryString ? `?${queryString}` : '';
901
+
894
902
  // replace(/\(/g, '%28').replace(/\)/g, '%29') -> used for the encoder of any round brackets
895
903
  this.router.navigateByUrl(pageUrl.replace(/\(/g, '%28').replace(/\)/g, '%29').replace( /#/g, "%23" ));
896
904
 
@@ -1182,11 +1190,14 @@ export class AppComponent implements OnInit {
1182
1190
  this.contactsService.initialize(serverBaseURL)
1183
1191
  // this.chatManager.startApp();
1184
1192
 
1193
+
1194
+ //INIT WEBSOCKET
1195
+ this.connetWebsocket(tiledeskToken)
1196
+
1185
1197
  // ----------------------------------------------
1186
1198
  // PUSH NOTIFICATIONS
1187
1199
  // ----------------------------------------------
1188
1200
  const pushEngine = this.appConfigProvider.getConfig().pushEngine
1189
-
1190
1201
  if (currentUser) {
1191
1202
  if (pushEngine && pushEngine !== 'none') {
1192
1203
  this.notificationsService.getNotificationPermissionAndSaveToken(currentUser.uid);
@@ -1208,6 +1219,24 @@ export class AppComponent implements OnInit {
1208
1219
  } catch (err) {
1209
1220
  this.logger.error('[APP-COMP] -> error:', err);
1210
1221
  }
1222
+
1223
+ // ----------------------------------------------
1224
+ // LAST PROJECT FROM URL
1225
+ // ----------------------------------------------
1226
+ if(this.g.projectID){
1227
+ this.projectService.getProjects().subscribe({ next: (projects: Project[]) => {
1228
+ const project = projects.find(prjct => prjct.id_project._id === this.g.projectID)
1229
+ if(project){
1230
+ this.logger.log('[APP-COMP] - GET PROJECT - project found with this.projectID', project);
1231
+ localStorage.setItem('last_project', JSON.stringify(project))
1232
+ this.events.publish('storage:last_project', project)
1233
+ }
1234
+ }, error: (error) => {
1235
+ this.logger.log('[APP-COMP] - GET PROJECT - project NOT found with this.projectID', this.g.projectID, error);
1236
+ }, complete: () => {
1237
+
1238
+ }});
1239
+ }
1211
1240
  }
1212
1241
 
1213
1242
 
@@ -1253,6 +1282,21 @@ export class AppComponent implements OnInit {
1253
1282
  myWindow.focus();
1254
1283
  }
1255
1284
 
1285
+ connetWebsocket(tiledeskToken) {
1286
+
1287
+ this.logger.log('[WEBSOCKET-JS] connetWebsocket called in [PROJECT-ITEM] tiledeskToken ', tiledeskToken)
1288
+ const appconfig = this.appConfigProvider.getConfig();
1289
+ this.logger.log('[WEBSOCKET-JS] connetWebsocket called in [PROJECT-ITEM] wsUrl ', appconfig.wsUrl)
1290
+ const WS_URL = appconfig.wsUrl + '?token=' + tiledeskToken
1291
+ this.logger.log('[WEBSOCKET-JS] connetWebsocket called in [PROJECT-ITEM] wsUrl ', WS_URL)
1292
+ this.webSocketJs.init(
1293
+ WS_URL,
1294
+ undefined,
1295
+ undefined,
1296
+ undefined
1297
+ );
1298
+ }
1299
+
1256
1300
 
1257
1301
  webSocketClose() {
1258
1302
  this.logger.log('[APP-COMP] - GO-OFFLINE - webSocketClose');
@@ -278,7 +278,5 @@ ion-item {
278
278
  display: flex;
279
279
  justify-content: center;
280
280
  flex-direction: column;
281
- align-items: center;
282
-
283
281
  }
284
282
  }
@@ -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;">
@@ -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;
@@ -63,17 +63,20 @@ export class MessageTextAreaComponent implements OnInit, AfterViewInit, OnChange
63
63
  @Input() emailSection: boolean;
64
64
  @Input() offlineMsgEmail: boolean;
65
65
  @Input() whatsappTemplatesSection: boolean;
66
+ @Input() ticketSection: boolean
66
67
  @Input() isOpenInfoConversation: boolean;
67
68
  @Input() cannedSection: boolean;
68
69
  @Input() stylesMap: Map<string, string>;
69
70
  @Input() translationMap: Map<string, string>;
70
71
  @Input() dropEvent: any;
71
72
  @Input() disableTextarea: boolean;
73
+ @Input() roles: Array<string>;
72
74
  @Output() eventChangeTextArea = new EventEmitter<{msg: string, offsetHeight: number}>();
73
75
  @Output() eventSendMessage = new EventEmitter<{msg: string, type: string, metadata?: Object, attributes?: Object}>();
74
76
  @Output() onClickOpenCannedResponses = new EventEmitter<boolean>();
75
77
  @Output() onPresentModalScrollToBottom = new EventEmitter<boolean>();
76
78
  @Output() onOpenFooterSection = new EventEmitter<string>();
79
+ @Output() onOpenTicket = new EventEmitter<boolean>();
77
80
 
78
81
  public project: Project;
79
82
  public conversationEnabled = false;
@@ -291,6 +294,17 @@ export class MessageTextAreaComponent implements OnInit, AfterViewInit, OnChange
291
294
  this.prensentTemplateModal();
292
295
  }
293
296
 
297
+ onClickTicket(option: "open" | "close"){
298
+ this.logger.log('[CONVS-DETAIL][MSG-TEXT-AREA] - onClickTicket', option);
299
+ switch(option){
300
+ case "open":
301
+ this.onOpenTicket.emit();
302
+ case "close":
303
+ this.section = 'chat'
304
+ }
305
+
306
+ }
307
+
294
308
 
295
309
  /**
296
310
  *
@@ -566,8 +580,10 @@ export class MessageTextAreaComponent implements OnInit, AfterViewInit, OnChange
566
580
  if (!text.includes("/")) {
567
581
  this.logger.log('[CONVS-DETAIL][MSG-TEXT-AREA] onKeydown - SEND MESSAGE 1 message: ', message);
568
582
  this.logger.log("[CONVS-DETAIL] replaceTagInMessage onKeydown in msg-texarea SEND MESSAGE 1 message: ", message);
569
- this.messageString = '';
583
+
570
584
  this.sendMessage(text);
585
+ // this.messageString = '';
586
+
571
587
  this.countClicks = 0
572
588
  } else if (text.includes("/") && pos === 0 && this.countClicks > 1 && this.tagsCannedFilter.length > 0) {
573
589
  this.logger.log('[CONVS-DETAIL][MSG-TEXT-AREA] onKeydown - tagsCannedFilter.length 2: ', this.tagsCannedFilter.length);
@@ -579,9 +595,10 @@ export class MessageTextAreaComponent implements OnInit, AfterViewInit, OnChange
579
595
  this.logger.log("[CONVS-DETAIL] replaceTagInMessage onKeydown in msg-texarea SEND MESSAGE 2 this.countClicks: ", this.countClicks);
580
596
  this.logger.log("[CONVS-DETAIL][MSG-TEXT-AREA] onKeydown in msg-texarea SEND MESSAGE 2 this.countClicks: ", this.countClicks);
581
597
  this.logger.log('[CONVS-DETAIL][MSG-TEXT-AREA] onKeydown - SEND MESSAGE 2 message: ', message);
582
- this.messageString = '';
583
-
598
+
584
599
  this.sendMessage(text);
600
+ // this.messageString = '';
601
+
585
602
  this.countClicks = 0
586
603
  } else if (text.includes("/") && pos > 0 && this.countClicks > 1 && this.tagsCannedFilter.length > 0 && text.substr(-1) !== '/') {
587
604
  this.logger.log('[CONVS-DETAIL][MSG-TEXT-AREA] onKeydown - tagsCannedFilter.length 3: ', this.tagsCannedFilter.length);
@@ -593,17 +610,19 @@ export class MessageTextAreaComponent implements OnInit, AfterViewInit, OnChange
593
610
  this.logger.log("[CONVS-DETAIL] replaceTagInMessage onKeydown in msg-texarea SEND MESSAGE 2 this.countClicks: ", this.countClicks);
594
611
  this.logger.log("[CONVS-DETAIL][MSG-TEXT-AREA] onKeydown in msg-texarea SEND MESSAGE 2 this.countClicks: ", this.countClicks);
595
612
  this.logger.log('[CONVS-DETAIL][MSG-TEXT-AREA] onKeydown - SEND MESSAGE 2 message: ', message);
596
- this.messageString = '';
597
-
613
+
598
614
  this.sendMessage(text);
615
+ // this.messageString = '';
616
+
599
617
  this.countClicks = 0
600
618
  } else if (text.includes("/") && this.tagsCannedFilter.length === 0) {
601
619
  this.logger.log('[CONVS-DETAIL][MSG-TEXT-AREA] onKeydown - tagsCannedFilter.length 3: ', this.tagsCannedFilter.length);
602
620
  this.logger.log('[CONVS-DETAIL][MSG-TEXT-AREA] onKeydown - SEND MESSAGE 3 message: ', message);
603
621
  this.logger.log("[CONVS-DETAIL] replaceTagInMessage onKeydown in msg-texarea SEND MESSAGE 3 message: ", message);
604
- this.messageString = '';
605
-
622
+
606
623
  this.sendMessage(text);
624
+ // this.messageString = '';
625
+
607
626
  this.countClicks = 0
608
627
 
609
628
  }
@@ -151,27 +151,29 @@ export class InfoGroupComponent implements OnInit, AfterViewInit, OnChanges {
151
151
  });
152
152
 
153
153
  this.contactsService.loadContactDetail(key).pipe(takeUntil(this.unsubscribe$)).subscribe(user => {
154
- this.logger.log('InfoGroupComponent group detail loadContactDetail RES', user);
155
- // this.logger.log('InfoGroupComponent group detail this.presenceService.BSIsOnline.value()', this.presenceService.BSIsOnline.getValue);
156
-
157
- user.imageurl = this.imageRepoService.getImagePhotoUrl(key)
158
- // this.member_array.push({ userid: user.uid, avatar: user.avatar, color: user.color, email: user.email, fullname: user.fullname, imageurl: user.imageurl, userOnline: isOnline })
159
- var index = this.member_array.findIndex(m => m.userid === user.uid);
160
- this.logger.log('InfoGroupComponent member_array first of push index', index);
161
- this.logger.log('InfoGroupComponent member_array first of push', this.member_array);
162
- if (index === -1) {
163
- this.member_array.push(
164
- {
165
- userid: user.uid,
166
- avatar: user.avatar,
167
- color: user.color,
168
- email: user.email,
169
- fullname: user.fullname,
170
- imageurl: user.imageurl,
171
- userOnline: members_isonline_array[user.uid]['isSignin']
172
- })
173
- } else {
174
- this.logger.log('InfoGroupComponent member already exist in member_array');
154
+ if(user){
155
+ this.logger.log('InfoGroupComponent group detail loadContactDetail RES', user);
156
+ // this.logger.log('InfoGroupComponent group detail this.presenceService.BSIsOnline.value()', this.presenceService.BSIsOnline.getValue);
157
+
158
+ user.imageurl = this.imageRepoService.getImagePhotoUrl(key)
159
+ // this.member_array.push({ userid: user.uid, avatar: user.avatar, color: user.color, email: user.email, fullname: user.fullname, imageurl: user.imageurl, userOnline: isOnline })
160
+ var index = this.member_array.findIndex(m => m.userid === user.uid);
161
+ this.logger.log('InfoGroupComponent member_array first of push index', index);
162
+ this.logger.log('InfoGroupComponent member_array first of push', this.member_array);
163
+ if (index === -1) {
164
+ this.member_array.push(
165
+ {
166
+ userid: user.uid,
167
+ avatar: user.avatar,
168
+ color: user.color,
169
+ email: user.email,
170
+ fullname: user.fullname,
171
+ imageurl: user.imageurl,
172
+ userOnline: members_isonline_array[user.uid]['isSignin']
173
+ })
174
+ } else {
175
+ this.logger.log('InfoGroupComponent member already exist in member_array');
176
+ }
175
177
  }
176
178
  }, (error) => {
177
179
  this.logger.error('InfoGroupComponent group detail loadContactDetail - ERROR ', error);
@@ -34,7 +34,7 @@
34
34
  <!-- <ion-icon name="file-tray-full-outline"></ion-icon> -->
35
35
  </ion-button>
36
36
 
37
- <ion-button *ngIf="writeto_btn" ion-button fill="clear" (click)="onOpenContactsDirectory($event)"
37
+ <ion-button *ngIf="writeto_btn && isVisibleCNT && roles?.[PERMISSIONS.LEADS_READ]" ion-button fill="clear" (click)="onOpenContactsDirectory($event)"
38
38
  tooltip="{{translationMap?.get('ViewContactsList')}}" placement="bottom">
39
39
  <ion-icon slot="icon-only" name="create-outline"></ion-icon>
40
40
  <!-- <ion-icon slot="icon-only" name="people-outline"></ion-icon> -->
@@ -1,3 +1,4 @@
1
+ import { PERMISSIONS } from 'src/app/utils/permissions.constants';
1
2
  import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core'
2
3
  import { ModalController } from '@ionic/angular'
3
4
  import { EventsService } from 'src/app/services/events-service'
@@ -17,6 +18,8 @@ export class HeaderConversationsList implements OnInit {
17
18
  @Input() sound_btn: string;
18
19
  @Input() isMobile: boolean;
19
20
  @Input() isVisibleTKT: boolean = true;
21
+ @Input() isVisibleCNT: boolean = true;;
22
+ @Input() roles: Array<string>;
20
23
  @Output() onSoundChange = new EventEmitter<string>()
21
24
  @Output() openContactsDirectory = new EventEmitter()
22
25
  @Output() openProfileInfo = new EventEmitter()
@@ -24,6 +27,7 @@ export class HeaderConversationsList implements OnInit {
24
27
  createTicketModal = null
25
28
  public translationMap: Map<string, string>;
26
29
 
30
+ PERMISSIONS = PERMISSIONS;
27
31
  constructor(
28
32
  public events: EventsService,
29
33
  public modalController: ModalController,
@@ -62,7 +66,7 @@ export class HeaderConversationsList implements OnInit {
62
66
  // }
63
67
 
64
68
  ngOnInit() {
65
- // console.log('DDP HEADER SUPPORT MODE ', this.supportMode)
69
+ console.log('DDP HEADER SUPPORT MODE ', this.roles)
66
70
  }
67
71
 
68
72
  // START @Output() //
@@ -5,7 +5,7 @@
5
5
  </div>
6
6
  <div class="navbar-right">
7
7
  <!-- test site -->
8
- <ng-container *ngIf="project">
8
+ <ng-container *ngIf="project && roles?.[PERMISSIONS.SIMULATE_CONV]">
9
9
  <button class="btn simulate-visitor-btn" (click)="testWidgetPage()">
10
10
  <i class="material-icons">play_arrow</i>
11
11
  <!-- {{translationsMap?.get('NAVBAR.SIMULATE_VISITOR')}} -->
@@ -23,7 +23,7 @@
23
23
  </ng-container>
24
24
 
25
25
  <!-- ------ PROJECTS DROPDOWN ------ -->
26
- <ng-container *ngIf="project">
26
+ <ng-container *ngIf="project && roles?.[PERMISSIONS.CHANGE_PROJECT]">
27
27
  <li>
28
28
  <button class="btn dropdown-toggle project-dropdown" (click)="openDropdownProjects = !openDropdownProjects">
29
29
  <span class="project-dropdown" style="text-transform: none"> {{ project?.id_project?.name }} </span>
@@ -49,7 +49,7 @@
49
49
  </li>
50
50
 
51
51
  <!-- ADD PROJECT -->
52
- <li id="navbar_create_prjct" *ngIf="MT === true" (click)="onClickDropdownOption('addProject')" class="add-project">
52
+ <li id="navbar_create_prjct" *ngIf="isVisibleMT" (click)="onClickDropdownOption('addProject')" class="add-project">
53
53
  <a>
54
54
  <i class="material-icons">add_circle_outline </i>
55
55
  {{translationsMap?.get('NAVBAR.ADD_PROJECT')}}
@@ -7,6 +7,10 @@ import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service
7
7
  import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance';
8
8
  import { Project } from 'src/chat21-core/models/projects';
9
9
  import { CustomTranslateService } from 'src/chat21-core/providers/custom-translate.service';
10
+ import { ProjectUsersService } from 'src/app/services/project_users/project-users.service';
11
+ import { ProjectUser } from 'src/chat21-core/models/projectUsers';
12
+ import { PERMISSIONS } from 'src/app/utils/permissions.constants';
13
+ import { getOSCode, hasRole } from 'src/app/utils/utils';
10
14
 
11
15
  @Component({
12
16
  selector: 'app-navbar',
@@ -30,10 +34,14 @@ export class NavbarComponent implements OnInit {
30
34
  public openDropdownProjects: boolean = false
31
35
  private public_Key: string;
32
36
  public isVisible: boolean;
33
- public MT: boolean;
37
+ public isVisibleMT: boolean;
34
38
 
39
+ public projectUser: ProjectUser;
40
+ public roles: { [key: string]: boolean }
41
+ PERMISSIONS = PERMISSIONS;
35
42
  constructor(
36
43
  private projectService: ProjectService,
44
+ public projectUsersService: ProjectUsersService,
37
45
  private tiledeskAuthService: TiledeskAuthService,
38
46
  private appConfigProvider: AppConfigProvider,
39
47
  private translateService: CustomTranslateService,
@@ -96,11 +104,14 @@ export class NavbarComponent implements OnInit {
96
104
  }
97
105
 
98
106
  getStoredProjectAndUserRole() {
99
- this.events.subscribe('storage:last_project',project =>{
107
+ this.events.subscribe('storage:last_project',async (project) =>{
100
108
  this.logger.log('[NAVBAR] stored_project ', project)
101
109
  if (project && project !== 'undefined') {
102
110
  this.project = project;
103
111
  this.USER_ROLE = project.role;
112
+ this.projectUser = await this.projectUsersService.getProjectUserByProjectId(project.id_project.id)
113
+ this.roles = this.checkRoles()
114
+ console.log('[SIDEBAR] roles ', this.roles)
104
115
  }
105
116
  })
106
117
  }
@@ -108,44 +119,24 @@ export class NavbarComponent implements OnInit {
108
119
  getOSCODE() {
109
120
  this.public_Key = this.appConfigProvider.getConfig().t2y12PruGU9wUtEGzBJfolMIgK;
110
121
  this.logger.log('[NAVBAR] AppConfigService getAppConfig public_Key', this.public_Key)
111
- this.logger.log('[NAVBAR] public_Key', this.public_Key)
112
-
113
- let keys = this.public_Key.split("-");
114
- // this.logger.log('PUBLIC-KEY (Navbar) - public_Key keys', keys)
115
-
116
- keys.forEach(key => {
117
- // this.logger.log('NavbarComponent public_Key key', key)
118
- if (key.includes("PAY")) {
119
- // this.logger.log('PUBLIC-KEY (Navbar) - key', key);
120
- let pay = key.split(":");
121
- // this.logger.log('PUBLIC-KEY (Navbar) - pay key&value', pay);
122
- if (pay[1] === "F") {
123
- this.isVisible = false;
124
- // this.logger.log('PUBLIC-KEY (Navbar) - pay isVisible', this.isVisible);
125
- } else {
126
- this.isVisible = true;
127
- // this.logger.log('PUBLIC-KEY (Navbar) - pay isVisible', this.isVisible);
128
- }
129
- }
130
-
131
- if (key.includes("MTT")) {
132
- // this.logger.log('PUBLIC-KEY (Navbar) - key', key);
133
- let mt = key.split(":");
134
- // this.logger.log('PUBLIC-KEY (Navbar) - mt key&value', mt);
135
- if (mt[1] === "F") {
136
- this.MT = false;
137
- // this.logger.log('PUBLIC-KEY (Navbar) - mt is', this.MT);
138
- } else {
139
- this.MT = true;
140
- // this.logger.log('PUBLIC-KEY (Navbar) - mt is', this.MT);
141
- }
142
- }
143
- });
122
+
123
+ this.isVisibleMT = getOSCode("MTT", this.public_Key);
124
+
125
+ }
126
+
127
+ checkRoles(): { [key: string]: boolean } {
128
+ const permissionKeys = [
129
+ 'CHANGE_PROJECT',
130
+ 'SIMULATE_CONV',
131
+ ] as const;
144
132
 
145
- if (!this.public_Key.includes("MTT")) {
146
- this.MT = false;
147
- // this.logger.log('PUBLIC-KEY (Navbar) - mt is', this.MT);
133
+ const roles: { [key: string]: boolean } = {};
134
+ for (const key of permissionKeys) {
135
+ const permission = PERMISSIONS[key];
136
+ roles[permission] = hasRole(this.projectUser, permission);
148
137
  }
138
+
139
+ return roles;
149
140
 
150
141
  }
151
142
 
@@ -85,17 +85,17 @@ export class ProjectItemComponent implements OnInit {
85
85
 
86
86
  connetWebsocket(tiledeskToken) {
87
87
 
88
- this.logger.log('[WEBSOCKET-JS] connetWebsocket called in [PROJECT-ITEM] tiledeskToken ', tiledeskToken)
89
- const appconfig = this.appConfigProvider.getConfig();
90
- this.logger.log('[WEBSOCKET-JS] connetWebsocket called in [PROJECT-ITEM] wsUrl ', appconfig.wsUrl)
91
- const WS_URL = appconfig.wsUrl + '?token=' + tiledeskToken
92
- this.logger.log('[WEBSOCKET-JS] connetWebsocket called in [PROJECT-ITEM] wsUrl ', WS_URL)
93
- this.webSocketJs.init(
94
- WS_URL,
95
- undefined,
96
- undefined,
97
- undefined
98
- );
88
+ // this.logger.log('[WEBSOCKET-JS] connetWebsocket called in [PROJECT-ITEM] tiledeskToken ', tiledeskToken)
89
+ // const appconfig = this.appConfigProvider.getConfig();
90
+ // this.logger.log('[WEBSOCKET-JS] connetWebsocket called in [PROJECT-ITEM] wsUrl ', appconfig.wsUrl)
91
+ // const WS_URL = appconfig.wsUrl + '?token=' + tiledeskToken
92
+ // this.logger.log('[WEBSOCKET-JS] connetWebsocket called in [PROJECT-ITEM] wsUrl ', WS_URL)
93
+ // this.webSocketJs.init(
94
+ // WS_URL,
95
+ // undefined,
96
+ // undefined,
97
+ // undefined
98
+ // );
99
99
 
100
100
  this.getLastProjectStoredAndSubscToWSAvailabilityAndConversations();
101
101
  }