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

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 (47) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/angular.json +1 -0
  3. package/package.json +1 -1
  4. package/src/app/app.component.html +3 -1
  5. package/src/app/app.component.ts +50 -2
  6. package/src/app/components/canned-response/canned-response.component.scss +0 -2
  7. package/src/app/components/conversation-detail/message-text-area/message-text-area.component.html +23 -0
  8. package/src/app/components/conversation-detail/message-text-area/message-text-area.component.scss +30 -0
  9. package/src/app/components/conversation-detail/message-text-area/message-text-area.component.ts +26 -7
  10. package/src/app/components/conversation-info/info-group/info-group.component.ts +23 -21
  11. package/src/app/components/conversations-list/header-conversations-list/header-conversations-list.component.html +1 -1
  12. package/src/app/components/conversations-list/header-conversations-list/header-conversations-list.component.ts +5 -1
  13. package/src/app/components/navbar/navbar.component.html +3 -3
  14. package/src/app/components/navbar/navbar.component.ts +29 -38
  15. package/src/app/components/project-item/project-item.component.ts +11 -11
  16. package/src/app/components/sidebar/sidebar.component.html +65 -45
  17. package/src/app/components/sidebar/sidebar.component.ts +92 -117
  18. package/src/app/components/sidebar-user-details/sidebar-user-details.component.html +2 -2
  19. package/src/app/components/sidebar-user-details/sidebar-user-details.component.ts +10 -7
  20. package/src/app/pages/conversation-detail/conversation-detail.page.html +3 -1
  21. package/src/app/pages/conversation-detail/conversation-detail.page.ts +47 -5
  22. package/src/app/pages/conversations-list/conversations-list.page.html +2 -0
  23. package/src/app/pages/conversations-list/conversations-list.page.ts +36 -3
  24. package/src/app/services/global-settings/global-settings.service.ts +12 -3
  25. package/src/app/shared/shared.module.ts +11 -0
  26. package/src/app/utils/globals.ts +2 -0
  27. package/src/app/utils/permissions.constants.ts +14 -11
  28. package/src/assets/i18n/ar.json +11 -1
  29. package/src/assets/i18n/az.json +11 -1
  30. package/src/assets/i18n/de.json +11 -1
  31. package/src/assets/i18n/en.json +11 -1
  32. package/src/assets/i18n/es.json +11 -1
  33. package/src/assets/i18n/fr.json +11 -1
  34. package/src/assets/i18n/it.json +13 -3
  35. package/src/assets/i18n/kk.json +11 -1
  36. package/src/assets/i18n/pt.json +11 -1
  37. package/src/assets/i18n/ru.json +11 -1
  38. package/src/assets/i18n/sr.json +11 -1
  39. package/src/assets/i18n/sv.json +11 -1
  40. package/src/assets/i18n/tr.json +11 -1
  41. package/src/assets/i18n/uk.json +11 -1
  42. package/src/assets/i18n/uz.json +12 -1
  43. package/src/assets/js/agentDesktop-sdk.js +47 -0
  44. package/src/chat-config-template.json +1 -0
  45. package/src/chat-config.json +1 -0
  46. package/src/chat21-core/providers/tiledesk/tiledesk-auth.service.ts +3 -0
  47. package/src/chat21-core/utils/utils.ts +16 -2
package/CHANGELOG.md CHANGED
@@ -8,6 +8,45 @@
8
8
  ### **Copyrigth**:
9
9
  *Tiledesk SRL*
10
10
 
11
+ # 3.4.27-rc12
12
+ - **added**: ability to manage logOut option in sidebar-user-detail with tiledesk_logOut url query params
13
+
14
+ # 3.4.27-rc11
15
+ - **bug-fixed**: fixed infinite loading in contact list
16
+
17
+ # 3.4.27-rc10
18
+ - **added**: ability to manage header-conversation-list with roles
19
+ - **bug-fixed**: members in group list not loaded
20
+
21
+ # 3.4.27-rc9
22
+ - **bug-fixed**: Scrolling to the last message when opening a conversation
23
+ - **bug-fixed**: Loading in the conversation list disabled when removing the last conversation
24
+
25
+ # 3.4.27-rc8
26
+ - **added**: ability to open ticket to external service
27
+ - **added**: ticketSection env var
28
+
29
+ # 3.4.27-rc7
30
+ - **bug-fixed**: Scrolling to the last message when opening a conversation
31
+ - **bug-fixed**: Loading in the conversation list disabled when removing the last conversation
32
+
33
+ # 3.4.27-rc6
34
+ - **bug-fixed**: user for dashboard app is incorrect
35
+
36
+ # 3.4.27-rc5
37
+ - **added**: managed roles in sidebar e navbar
38
+ - **bug-fixed**: projectId and supportMode url is not saved in localstorage
39
+
40
+ # 3.4.27-rc4
41
+ - **bug-fixed**: extractUrls function is not able to detect url start with www or without https/http
42
+ - **bug-fixed**: if message is sent with keydown, error on domain check is not showed
43
+
44
+ # 3.4.27-rc3
45
+ - **bug-fixed**: cannot set user availability if supportMode is enabled and tiledesk_projectID url params is set
46
+
47
+ # 3.4.27-rc2
48
+ - **bug-fixed**: cannede responses role
49
+
11
50
  # 3.4.27-rc1
12
51
  - **added**: managed canned responses with roles
13
52
  - **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-rc12",
5
5
  "license": "MIT License",
6
6
  "homepage": "https://tiledesk.com/",
7
7
  "repository": {
@@ -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> </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}">
@@ -44,6 +44,8 @@ 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';
47
49
  import { ProjectUsersService } from './services/project_users/project-users.service';
48
50
 
49
51
  @Component({
@@ -299,6 +301,10 @@ export class AppComponent implements OnInit {
299
301
  this.zone = new NgZone({}); // a cosa serve?
300
302
 
301
303
  this.SUPPORT_MODE = this.g.supportMode
304
+ this.logger.info('[APP-COMP] this.SUPPORT_MODE', this.SUPPORT_MODE)
305
+
306
+ BRAND_BASE_INFO['LOGOUT_ENABLED'] = this.g.logOut
307
+ this.logger.info('[APP-COMP] this.logOut', BRAND_BASE_INFO['LOGOUT_ENABLED'])
302
308
  }
303
309
 
304
310
  });
@@ -867,7 +873,8 @@ export class AppComponent implements OnInit {
867
873
  // console.log('[APP-COMP] PLATFORM', PLATFORM_MOBILE, 'route.snapshot', this.route.snapshot);
868
874
  if (!IDConv) {
869
875
  this.logger.log('[APP-COMP] navigateByUrl -- conversations-list');
870
- this.router.navigateByUrl('conversations-list')
876
+ const queryString = window.location.search; // restituisce ad es. "?jwt=...&tiledesk_supportMode=false"
877
+ this.router.navigateByUrl('conversations-list' + queryString);
871
878
  }
872
879
  // this.router.navigateByUrl(pageUrl);
873
880
  // this.navService.setRoot(ConversationListPage, {});
@@ -891,6 +898,11 @@ export class AppComponent implements OnInit {
891
898
  if (IDConv && FullNameConv) {
892
899
  pageUrl += IDConv + '/' + FullNameConv + '/' + Convtype
893
900
  }
901
+
902
+ const queryParams = this.route.snapshot.queryParams;
903
+ const queryString = new URLSearchParams(queryParams).toString();
904
+ pageUrl += queryString ? `?${queryString}` : '';
905
+
894
906
  // replace(/\(/g, '%28').replace(/\)/g, '%29') -> used for the encoder of any round brackets
895
907
  this.router.navigateByUrl(pageUrl.replace(/\(/g, '%28').replace(/\)/g, '%29').replace( /#/g, "%23" ));
896
908
 
@@ -1182,11 +1194,14 @@ export class AppComponent implements OnInit {
1182
1194
  this.contactsService.initialize(serverBaseURL)
1183
1195
  // this.chatManager.startApp();
1184
1196
 
1197
+
1198
+ //INIT WEBSOCKET
1199
+ this.connetWebsocket(tiledeskToken)
1200
+
1185
1201
  // ----------------------------------------------
1186
1202
  // PUSH NOTIFICATIONS
1187
1203
  // ----------------------------------------------
1188
1204
  const pushEngine = this.appConfigProvider.getConfig().pushEngine
1189
-
1190
1205
  if (currentUser) {
1191
1206
  if (pushEngine && pushEngine !== 'none') {
1192
1207
  this.notificationsService.getNotificationPermissionAndSaveToken(currentUser.uid);
@@ -1208,6 +1223,24 @@ export class AppComponent implements OnInit {
1208
1223
  } catch (err) {
1209
1224
  this.logger.error('[APP-COMP] -> error:', err);
1210
1225
  }
1226
+
1227
+ // ----------------------------------------------
1228
+ // LAST PROJECT FROM URL
1229
+ // ----------------------------------------------
1230
+ if(this.g.projectID){
1231
+ this.projectService.getProjects().subscribe({ next: (projects: Project[]) => {
1232
+ const project = projects.find(prjct => prjct.id_project._id === this.g.projectID)
1233
+ if(project){
1234
+ this.logger.log('[APP-COMP] - GET PROJECT - project found with this.projectID', project);
1235
+ localStorage.setItem('last_project', JSON.stringify(project))
1236
+ this.events.publish('storage:last_project', project)
1237
+ }
1238
+ }, error: (error) => {
1239
+ this.logger.log('[APP-COMP] - GET PROJECT - project NOT found with this.projectID', this.g.projectID, error);
1240
+ }, complete: () => {
1241
+
1242
+ }});
1243
+ }
1211
1244
  }
1212
1245
 
1213
1246
 
@@ -1253,6 +1286,21 @@ export class AppComponent implements OnInit {
1253
1286
  myWindow.focus();
1254
1287
  }
1255
1288
 
1289
+ connetWebsocket(tiledeskToken) {
1290
+
1291
+ this.logger.log('[WEBSOCKET-JS] connetWebsocket called in [PROJECT-ITEM] tiledeskToken ', tiledeskToken)
1292
+ const appconfig = this.appConfigProvider.getConfig();
1293
+ this.logger.log('[WEBSOCKET-JS] connetWebsocket called in [PROJECT-ITEM] wsUrl ', appconfig.wsUrl)
1294
+ const WS_URL = appconfig.wsUrl + '?token=' + tiledeskToken
1295
+ this.logger.log('[WEBSOCKET-JS] connetWebsocket called in [PROJECT-ITEM] wsUrl ', WS_URL)
1296
+ this.webSocketJs.init(
1297
+ WS_URL,
1298
+ undefined,
1299
+ undefined,
1300
+ undefined
1301
+ );
1302
+ }
1303
+
1256
1304
 
1257
1305
  webSocketClose() {
1258
1306
  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
  }