@chat21/chat21-ionic 3.0.59 → 3.0.60-rc8

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 (49) hide show
  1. package/CHANGELOG.md +50 -1
  2. package/deploy_pre.sh +45 -6
  3. package/deploy_prod.sh +34 -9
  4. package/env.sample +1 -1
  5. package/package.json +1 -1
  6. package/src/app/app.component.ts +51 -50
  7. package/src/app/app.module.ts +2 -2
  8. package/src/app/chatlib/conversation-detail/message/bubble-message/bubble-message.component.ts +62 -36
  9. package/src/app/chatlib/list-conversations-component/ion-list-conversations/ion-list-conversations.component.html +1 -1
  10. package/src/app/chatlib/list-conversations-component/ion-list-conversations/ion-list-conversations.component.ts +42 -13
  11. package/src/app/components/conversation-detail/message-text-area/message-text-area.component.html +64 -39
  12. package/src/app/components/conversation-detail/message-text-area/message-text-area.component.scss +50 -2
  13. package/src/app/components/conversation-detail/message-text-area/message-text-area.component.ts +80 -94
  14. package/src/app/components/image-viewer/image-viewer.component.scss +2 -2
  15. package/src/app/components/project-item/project-item.component.html +140 -118
  16. package/src/app/components/project-item/project-item.component.scss +145 -83
  17. package/src/app/components/project-item/project-item.component.ts +67 -26
  18. package/src/app/pages/conversation-detail/conversation-detail.module.ts +3 -1
  19. package/src/app/pages/conversation-detail/conversation-detail.page.html +9 -3
  20. package/src/app/pages/conversation-detail/conversation-detail.page.ts +201 -86
  21. package/src/app/pages/conversations-list/conversations-list.page.html +11 -5
  22. package/src/app/pages/conversations-list/conversations-list.page.scss +12 -1
  23. package/src/app/pages/conversations-list/conversations-list.page.ts +27 -7
  24. package/src/app/pages/unassigned-conversations/unassigned-conversations.page.html +16 -11
  25. package/src/app/pages/unassigned-conversations/unassigned-conversations.page.scss +157 -63
  26. package/src/app/pages/unassigned-conversations/unassigned-conversations.page.ts +51 -16
  27. package/src/app/services/app-config.ts +14 -14
  28. package/src/app/services/websocket/websocket-js.ts +7 -4
  29. package/src/app/services/websocket/websocket.service.ts +1 -1
  30. package/src/app/shared/shared.module.ts +8 -7
  31. package/src/assets/i18n/de.json +208 -0
  32. package/src/assets/i18n/en.json +24 -7
  33. package/src/assets/i18n/es.json +208 -0
  34. package/src/assets/i18n/fr.json +208 -0
  35. package/src/assets/i18n/it.json +42 -33
  36. package/src/assets/i18n/pt.json +208 -0
  37. package/src/assets/i18n/ru.json +208 -0
  38. package/src/assets/i18n/tr.json +208 -0
  39. package/src/assets/js/chat21client.js +16 -3
  40. package/src/chat-config-mqtt.json +2 -1
  41. package/src/chat-config-pre-test.json +2 -0
  42. package/src/chat-config-template.json +1 -0
  43. package/src/chat-config.json +1 -0
  44. package/src/chat21-core/providers/firebase/firebase-conversation-handler.ts +54 -43
  45. package/src/chat21-core/providers/firebase/firebase-conversations-handler.ts +23 -0
  46. package/src/chat21-core/providers/mqtt/mqtt-archivedconversations-handler.ts +1 -1
  47. package/src/chat21-core/utils/constants.ts +2 -0
  48. package/src/chat21-core/utils/utils.ts +12 -1
  49. package/src/global.scss +4 -0
@@ -9,6 +9,7 @@ import { CustomTranslateService } from 'src/chat21-core/providers/custom-transla
9
9
  import { TiledeskAuthService } from 'src/chat21-core/providers/tiledesk/tiledesk-auth.service';
10
10
  import { TiledeskService } from 'src/app/services/tiledesk/tiledesk.service';
11
11
  import { WebSocketJs } from 'src/app/services/websocket/websocket-js';
12
+ import { AppConfigProvider } from 'src/app/services/app-config';
12
13
 
13
14
  @Component({
14
15
  selector: 'app-project-item',
@@ -17,6 +18,7 @@ import { WebSocketJs } from 'src/app/services/websocket/websocket-js';
17
18
  })
18
19
  export class ProjectItemComponent implements OnInit {
19
20
  @Output() projectIdEvent = new EventEmitter<string>()
21
+ @Output() openUnsevedConvsEvent = new EventEmitter<any>()
20
22
 
21
23
  private unsubscribe$: Subject<any> = new Subject<any>();
22
24
  project: any;
@@ -30,6 +32,16 @@ export class ProjectItemComponent implements OnInit {
30
32
  private logger: LoggerService = LoggerInstance.getInstance();
31
33
  window_width_is_60: boolean;
32
34
  newInnerWidth: any;
35
+ avaialble_status_for_tooltip: string;
36
+ tooltipOptions = {
37
+ 'show-delay': 500,
38
+ 'tooltip-class': 'chat-tooltip',
39
+ 'theme': 'light',
40
+ 'shadow': false,
41
+ 'hide-delay-mobile': 0,
42
+ 'hideDelayAfterClick': 3000,
43
+ 'hide-delay': 200
44
+ };
33
45
 
34
46
  constructor(
35
47
  public wsService: WebsocketService,
@@ -38,41 +50,79 @@ export class ProjectItemComponent implements OnInit {
38
50
  public tiledeskAuthService: TiledeskAuthService,
39
51
  public tiledeskService: TiledeskService,
40
52
  public webSocketJs: WebSocketJs,
53
+ private appConfigProvider: AppConfigProvider,
41
54
  ) { }
42
55
 
43
56
  ngOnInit() {
44
- this.getLastProjectStoredAndSubscToWSAvailabilityAndConversations();
45
- this.getStoredToken();
57
+ this.getStoredTokenAndConnectWS();
46
58
  this.getStoredCurrenUser();
47
59
  this.translations();
48
60
  this.listenToPostMsgs();
49
61
  this.onInitWindowWidth();
62
+ // console.log('[PROJECT-ITEM] - on INIT')
63
+ }
64
+
65
+ openUnservedConvs() {
66
+ this.openUnsevedConvsEvent.emit('notificationsorprjctbtn')
67
+ }
68
+ openUnservedConvsAndGoToProjectList() {
69
+ this.openUnsevedConvsEvent.emit('pinbtn')
70
+ }
71
+
72
+ getStoredTokenAndConnectWS() {
73
+ this.tiledeskToken = this.appStorageService.getItem('tiledeskToken');
74
+ this.logger.log('[PROJECT-ITEM] - STORED TILEDEK TOKEN ', this.tiledeskToken)
75
+ this.connetWebsocket(this.tiledeskToken)
76
+ }
77
+
78
+ connetWebsocket(tiledeskToken) {
79
+
80
+ this.logger.log('[WEBSOCKET-JS] connetWebsocket called in [PROJECT-ITEM] tiledeskToken ', tiledeskToken)
81
+ const appconfig = this.appConfigProvider.getConfig();
82
+ this.logger.log('[WEBSOCKET-JS] connetWebsocket called in [PROJECT-ITEM] wsUrl ', appconfig.wsUrl)
83
+ const WS_URL = appconfig.wsUrl + '?token=' + tiledeskToken
84
+ this.logger.log('[WEBSOCKET-JS] connetWebsocket called in [PROJECT-ITEM] wsUrl ', WS_URL)
85
+ this.webSocketJs.init(
86
+ WS_URL,
87
+ undefined,
88
+ undefined,
89
+ undefined
90
+ );
50
91
 
92
+ this.getLastProjectStoredAndSubscToWSAvailabilityAndConversations();
51
93
  }
52
94
 
53
95
  listenToPostMsgs() {
54
96
  window.addEventListener("message", (event) => {
55
97
  // console.log("[PROJECT-ITEM] post message event ", event);
56
98
 
57
- if (event && event.data && event.data) {
99
+ if (event && event.data) {
58
100
  // console.log("[PROJECT-ITEM] message event data ", event.data);
59
101
  if (event.data === 'hasChangedProject') {
60
102
  this.unservedRequestCount = 0;
61
103
  if (this.project) {
62
- this.webSocketJs.unsubscribe('/' + this.project.id_project._id + '/requests');
104
+ this.webSocketJs.unsubscribe('/' + this.project.id_project._id + '/requests');
63
105
  }
64
106
  this.getLastProjectStoredAndSubscToWSAvailabilityAndConversations();
65
-
66
107
  }
67
108
  }
68
109
  })
69
110
  }
70
111
 
112
+
71
113
  public translations() {
72
114
  const keys = [
73
115
  'Available',
74
116
  'Unavailable',
75
- 'Busy'
117
+ 'Busy',
118
+ 'VIEW_ALL_CONVERSATIONS',
119
+ 'CONVERSATIONS_IN_QUEUE',
120
+ 'CONVERSATION_IN_QUEUE',
121
+ 'NO_CONVERSATION_IN_QUEUE',
122
+ 'PINNED_PROJECT',
123
+ 'CHANGE_PINNED_PROJECT',
124
+ "CHANGE_TO_YOUR_STATUS_TO_AVAILABLE",
125
+ "CHANGE_TO_YOUR_STATUS_TO_UNAVAILABLE"
76
126
  ];
77
127
  this.translationMap = this.translateService.translateLanguage(keys);
78
128
  }
@@ -93,21 +143,6 @@ export class ProjectItemComponent implements OnInit {
93
143
  const actualWidth = window.innerWidth;
94
144
  this.logger.log('[PROJECT-ITEM] - ACTUAL Width ', actualWidth);
95
145
 
96
-
97
-
98
- // if (actualWidth <= 150) {
99
- // this.window_width_is_60 = true;
100
- // } else {
101
- // this.window_width_is_60 = false;
102
- // }
103
- }
104
-
105
-
106
-
107
- getStoredToken() {
108
- this.tiledeskToken = this.appStorageService.getItem('tiledeskToken');
109
- this.logger.log('[PROJECT-ITEM] - STORED TILEDEK TOKEN ', this.tiledeskToken)
110
-
111
146
  }
112
147
 
113
148
  getStoredCurrenUser() {
@@ -134,9 +169,9 @@ export class ProjectItemComponent implements OnInit {
134
169
  if (!stored_project) {
135
170
  this.logger.log('PROJECT-ITEM - THERE IS NOT STORED LAST PROJECT ', stored_project)
136
171
  const tiledeskToken = this.appStorageService.getItem('tiledeskToken');
137
- this.logger.log('[INFO-CONTENT-COMP] - GET PROJECTS - tiledeskToken', tiledeskToken);
172
+ this.logger.log('[PROJECT-ITEM] - GET PROJECTS - tiledeskToken', tiledeskToken);
138
173
  this.tiledeskService.getProjects(tiledeskToken).subscribe(projects => {
139
- this.logger.log('[INFO-CONTENT-COMP] - GET PROJECTS - RES', projects);
174
+ this.logger.log('[PROJECT-ITEM - GET PROJECTS - RES', projects);
140
175
 
141
176
  this.logger.log('[INFO-CONTENT-COMP] - GET PROJECTS - RES this.project', this.project);
142
177
 
@@ -147,7 +182,7 @@ export class ProjectItemComponent implements OnInit {
147
182
  }
148
183
 
149
184
  }, (error) => {
150
- this.logger.error('[INFO-CONTENT-COMP] - GET PROJECTS - ERROR ', error);
185
+ this.logger.error('[PROJECT-ITEM] - GET PROJECTS - ERROR ', error);
151
186
 
152
187
  }, () => {
153
188
  this.logger.log('[INFO-CONTENT-COMP] - GET PROJECTS * COMPLETE *');
@@ -175,7 +210,6 @@ export class ProjectItemComponent implements OnInit {
175
210
  this.logger.log('[PROJECT-ITEM] - user_role ', user_role)
176
211
  this.projectIdEvent.emit(project.id_project._id)
177
212
 
178
-
179
213
  if (user_role === 'agent') {
180
214
  this.ROLE_IS_AGENT = true;
181
215
 
@@ -206,6 +240,13 @@ export class ProjectItemComponent implements OnInit {
206
240
  if (project.id_project._id === projectUser['id_project']) {
207
241
  project['ws_projct_user_available'] = projectUser['user_available'];
208
242
  project['ws_projct_user_isBusy'] = projectUser['isBusy']
243
+ if (this.translationMap) {
244
+ if (projectUser['user_available'] === true) {
245
+ this.avaialble_status_for_tooltip = this.translationMap.get('CHANGE_TO_YOUR_STATUS_TO_UNAVAILABLE')
246
+ } else {
247
+ this.avaialble_status_for_tooltip = this.translationMap.get('CHANGE_TO_YOUR_STATUS_TO_AVAILABLE')
248
+ }
249
+ }
209
250
  }
210
251
 
211
252
  }, (error) => {
@@ -255,7 +296,7 @@ export class ProjectItemComponent implements OnInit {
255
296
  // this.logger.log('NAVBAR - UPDATE-UNSERVED-REQUEST-COUNT request agents', r.agents)
256
297
  // *bug fix: when the user is an agent also for the unserved we have to consider if he is present in agents
257
298
  // && this.ROLE_IS_AGENT === true
258
- if (r['status'] === 100 ) {
299
+ if (r['status'] === 100) {
259
300
  if (this.hasmeInAgents(r['agents']) === true) {
260
301
  count = count + 1;
261
302
  }
@@ -40,6 +40,7 @@ import { NgxLinkifyjsModule } from 'ngx-linkifyjs';
40
40
  CommonModule,
41
41
  FormsModule,
42
42
  IonicModule,
43
+ TooltipModule,
43
44
  ConversationDetailPageRoutingModule,
44
45
  TranslateModule.forChild({
45
46
  loader: {
@@ -51,7 +52,8 @@ import { NgxLinkifyjsModule } from 'ngx-linkifyjs';
51
52
  SharedModule,
52
53
  NgxLinkifyjsModule,
53
54
  ],
54
- entryComponents: [MessageTextAreaComponent],
55
+ // entryComponents: [MessageTextAreaComponent],
56
+ entryComponents: [],
55
57
  declarations: [
56
58
  ConversationDetailPage,
57
59
  HeaderConversationDetailComponent,
@@ -10,8 +10,8 @@
10
10
  <ion-grid style="height: 100%;">
11
11
  <ion-row class="ion-justify-content-center ion-align-items-center" style="height: 100%; flex-direction: column">
12
12
  <span *ngIf="isOnline === true"
13
- style="color: #92949c; font-size: 16px;line-height: 18px;margin-top: -160px;">{{'PleaseSelectChatToStartMessaging'
14
- | translate }}</span>
13
+ style="color: #92949c; font-size: 16px;line-height: 18px;margin-top: -160px;">
14
+ {{'PleaseSelectChatToStartMessaging' | translate }}</span>
15
15
 
16
16
  <span *ngIf="isOnline === false"
17
17
  style="color: #92949c; font-size: 16px;line-height: 18px;margin-top: -160px;">Internet is slow or not working</span>
@@ -149,16 +149,22 @@
149
149
  </ion-item>
150
150
  </ion-list>
151
151
  </div>
152
+
153
+
154
+
155
+
152
156
  <!-- (eventReplaceMessageWithCanned)="replaceTagInMessage($event)" -->
153
157
  <!-- [tagsCannedFilter]="tagsCannedFilter" -->
154
158
  <!-- openInfoConversation {{openInfoConversation}} - isMobile {{isMobile}} -->
155
159
  <app-message-text-area
156
160
  *ngIf="(openInfoConversation === false && isMobile === true) || (openInfoConversation === true && isMobile === false) || (openInfoConversation === false && isMobile === false)"
157
-
161
+ [tagsCannedCount]="tagsCannedCount"
162
+ [areVisibleCAR]="areVisibleCAR"
158
163
  [loggedUser]="loggedUser"
159
164
  [conversationWith]="conversationWith"
160
165
  [tagsCannedFilter]="tagsCannedFilter"
161
166
  (eventChangeTextArea)="returnChangeTextArea($event)"
167
+ (hasClickedOpenCannedResponses)="hasClickedOpenCannedResponses($event)"
162
168
  (eventSendMessage)="returnSendMessage($event)"
163
169
  [translationMap]="translationMap"
164
170
  [fileUploadAccept]="appConfigProvider.getConfig().fileUploadAccept"
@@ -92,6 +92,7 @@ export class ConversationDetailPage implements OnInit, OnDestroy, AfterViewInit
92
92
  public conv_type: string;
93
93
 
94
94
  public tagsCanned: any = [];
95
+ public tagsCannedCount: number
95
96
  public tagsCannedFilter: any = [];
96
97
  public HIDE_CANNED_RESPONSES: boolean = false;
97
98
 
@@ -104,7 +105,8 @@ export class ConversationDetailPage implements OnInit, OnDestroy, AfterViewInit
104
105
  MESSAGE_TYPE_OTHERS = MESSAGE_TYPE_OTHERS;
105
106
 
106
107
  arrowkeyLocation = -1;
107
-
108
+ public_Key: any;
109
+ areVisibleCAR: boolean
108
110
  //SOUND
109
111
  setTimeoutSound: any;
110
112
  audio: any
@@ -180,7 +182,7 @@ export class ConversationDetailPage implements OnInit, OnDestroy, AfterViewInit
180
182
  this.conversationWithFullname = params.get('FullNameConv');
181
183
  this.conv_type = params.get('Convtype');
182
184
 
183
- this.events.publish('supportconvid:haschanged', this.conversationWith);
185
+ this.events.publish('supportconvid:haschanged', this.conversationWith);
184
186
  });
185
187
 
186
188
  }
@@ -206,6 +208,37 @@ export class ConversationDetailPage implements OnInit, OnDestroy, AfterViewInit
206
208
  // }
207
209
  // });
208
210
  this.watchToConnectionStatus();
211
+ this.getOSCODE()
212
+ }
213
+
214
+
215
+ getOSCODE() {
216
+ this.public_Key = this.appConfigProvider.getConfig().t2y12PruGU9wUtEGzBJfolMIgK;
217
+ this.logger.log('[CONVS-DETAIL] AppConfigService getAppConfig public_Key', this.public_Key);
218
+
219
+ let keys = this.public_Key.split("-");
220
+ this.logger.log('[CONVS-DETAIL] PUBLIC-KEY - public_Key keys', keys)
221
+
222
+ keys.forEach(key => {
223
+
224
+
225
+ if (key.includes("CAR")) {
226
+ let car = key.split(":");
227
+ if (car[1] === "F") {
228
+ this.areVisibleCAR = false;
229
+ this.logger.log('[CONVS-DETAIL] PUBLIC-KEY - areVisibleCAR', this.areVisibleCAR)
230
+ } else {
231
+ this.areVisibleCAR = true;
232
+ this.logger.log('[CONVS-DETAIL] PUBLIC-KEY - areVisibleCAR', this.areVisibleCAR)
233
+ }
234
+ }
235
+
236
+ });
237
+
238
+ if (!this.public_Key.includes("CAR")) {
239
+ this.areVisibleCAR = false;
240
+ this.logger.log('[CONVS-DETAIL] PUBLIC-KEY - areVisibleCAR', this.areVisibleCAR)
241
+ }
209
242
  }
210
243
 
211
244
  watchToConnectionStatus() {
@@ -327,6 +360,7 @@ export class ConversationDetailPage implements OnInit, OnDestroy, AfterViewInit
327
360
  this.subscriptions = [];
328
361
  this.setHeightTextArea();
329
362
  this.tagsCanned = []; // list of canned
363
+
330
364
  this.messages = []; // list messages of conversation
331
365
  this.isFileSelected = false; // indicates if a file has been selected (image to upload)
332
366
  this.openInfoMessage = false; // indicates whether the info message panel is open
@@ -415,7 +449,13 @@ export class ConversationDetailPage implements OnInit, OnDestroy, AfterViewInit
415
449
  'FAILED_TO_UPLOAD_THE_FORMAT_IS NOT_SUPPORTED',
416
450
  'NO_INFORMATION_AVAILABLE',
417
451
  'CONTACT_ID',
418
- 'USER_ID'
452
+ 'USER_ID',
453
+ "UPLOAD",
454
+ "CANNED_RESPONSES",
455
+ "NO_CANNED_RESPONSES",
456
+ "YES_CANNED_RESPONSES",
457
+ "THERE_ARE_NO_CANNED_RESPONSES_AVAILABLE",
458
+ "TO_CREATE_THEM_GO_TO_THE_PROJECT"
419
459
  ];
420
460
 
421
461
  this.translationMap = this.customTranslateService.translateLanguage(keys);
@@ -433,6 +473,7 @@ export class ConversationDetailPage implements OnInit, OnDestroy, AfterViewInit
433
473
  'INFO_SUPPORT_USER_ADDED_VERB',
434
474
  'INFO_SUPPORT_CHAT_REOPENED',
435
475
  'INFO_SUPPORT_CHAT_CLOSED',
476
+ 'INFO_A_NEW_SUPPORT_REQUEST_HAS_BEEN_ASSIGNED_TO_YOU',
436
477
  'LABEL_TODAY',
437
478
  'LABEL_TOMORROW',
438
479
  'LABEL_LAST_ACCESS',
@@ -892,90 +933,93 @@ export class ConversationDetailPage implements OnInit, OnDestroy, AfterViewInit
892
933
  // ----------------------------------------------------------
893
934
  // DISPLAY CANNED RESPONSES if message.lastIndexOf("/")
894
935
  // ----------------------------------------------------------
895
- setTimeout(() => {
896
- if (this.conversationWith.startsWith("support-group")) {
897
-
898
- const pos = message.lastIndexOf("/");
899
- // console.log("[CONVS-DETAIL] - returnChangeTextArea - canned responses pos of / (using lastIndexOf) ", pos);
900
-
901
- // test
902
- // var rest = message.substring(0, message.lastIndexOf("/") + 1);
903
- // var last = message.substring(message.lastIndexOf("/") + 1, message.length);
904
- // console.log('[CONVS-DETAIL] - returnChangeTextArea rest', rest);
905
- // console.log('[CONVS-DETAIL] - returnChangeTextArea last', last);
906
- // console.log('[CONVS-DETAIL] - returnChangeTextArea last', last.length);
907
- // if (last.length === 1 && last.trim() === '') {
908
- // console.log('[CONVS-DETAIL] - returnChangeTextArea last is a white space ');
909
- // } else if (last.length === 1 && last.trim() !== '') {
910
- // console.log('[CONVS-DETAIL] - returnChangeTextArea last is NOT space ');
911
- // }
912
-
913
-
914
- if (pos >= 0) {
915
- var strSearch = message.substr(pos + 1);
916
- this.logger.log("[CONVS-DETAIL] - returnChangeTextArea - canned responses strSearch ", strSearch);
917
-
918
- // --------------------------------------------
919
- // Load canned responses
920
- // --------------------------------------------
921
- this.loadTagsCanned(strSearch, this.conversationWith);
922
-
923
- // ------------------------------------------------------------------------------------------------------------------------------------------
924
- // Hide / display Canned when the SLASH has POSITION POS 0 and checking if there is a space after the SLASH (in this case it will be hidden)
925
- // ------------------------------------------------------------------------------------------------------------------------------------------
926
-
927
- var after_slash = message.substring(message.lastIndexOf("/") + 1, message.length);
928
- if (pos === 0 && after_slash.length === 1 && after_slash.trim() === '') {
929
- this.logger.log('[CONVS-DETAIL] - returnChangeTextArea after_slash --> there is a white space after ');
930
- this.HIDE_CANNED_RESPONSES = true
931
- this.tagsCannedFilter = []
932
- } else if (pos === 0 && after_slash.length === 0) {
933
- this.logger.log('[CONVS-DETAIL] - returnChangeTextArea after_slash --> there is NOT a white space after');
934
- this.HIDE_CANNED_RESPONSES = false
935
- }
936
-
937
-
938
- if (pos > 0) {
936
+ if (this.areVisibleCAR) {
937
+ setTimeout(() => {
938
+ if (this.conversationWith.startsWith("support-group")) {
939
+
940
+ const pos = message.lastIndexOf("/");
941
+ // console.log("[CONVS-DETAIL] - returnChangeTextArea - canned responses pos of / (using lastIndexOf) ", pos);
942
+
943
+ // test
944
+ // var rest = message.substring(0, message.lastIndexOf("/") + 1);
945
+ // var last = message.substring(message.lastIndexOf("/") + 1, message.length);
946
+ // console.log('[CONVS-DETAIL] - returnChangeTextArea rest', rest);
947
+ // console.log('[CONVS-DETAIL] - returnChangeTextArea last', last);
948
+ // console.log('[CONVS-DETAIL] - returnChangeTextArea last', last.length);
949
+ // if (last.length === 1 && last.trim() === '') {
950
+ // console.log('[CONVS-DETAIL] - returnChangeTextArea last is a white space ');
951
+ // } else if (last.length === 1 && last.trim() !== '') {
952
+ // console.log('[CONVS-DETAIL] - returnChangeTextArea last is NOT space ');
953
+ // }
954
+
955
+
956
+ if (pos >= 0) {
957
+ var strSearch = message.substr(pos + 1);
958
+ this.logger.log("[CONVS-DETAIL] - returnChangeTextArea - canned responses strSearch ", strSearch);
959
+
960
+ // --------------------------------------------
961
+ // Load canned responses
962
+ // --------------------------------------------
963
+ this.loadTagsCanned(strSearch, this.conversationWith);
939
964
 
940
965
  // ------------------------------------------------------------------------------------------------------------------------------------------
941
- // Hide / display Canned when the SLASH has POSITION POS > and checking if there is a space after the SLASH (in this case they it be hidden)
942
- // and if there is not a space before the SLASH (in this it will be hidden)
966
+ // Hide / display Canned when the SLASH has POSITION POS 0 and checking if there is a space after the SLASH (in this case it will be hidden)
943
967
  // ------------------------------------------------------------------------------------------------------------------------------------------
944
968
 
945
- let beforeSlash = message.substr(pos - 1)
946
- let afterSlash = message.substr(pos + 1)
947
- this.logger.log('[CONVS-DETAIL] - returnChangeTextArea * POS ', pos);
948
-
949
- this.logger.log('[CONVS-DETAIL] - returnChangeTextArea --> beforeSlash', beforeSlash);
950
- this.logger.log('[CONVS-DETAIL] - returnChangeTextArea --> afterSlash', afterSlash);
951
- var afterSlashParts = afterSlash.split("/")
952
- var beforeSlashParts = beforeSlash.split("/")
953
- this.logger.log('[CONVS-DETAIL] - returnChangeTextArea --> afterSlash parts', afterSlashParts);
954
- this.logger.log('[CONVS-DETAIL] - returnChangeTextArea --> beforeSlash parts', beforeSlashParts);
955
-
956
- if (beforeSlashParts.length === 2) {
957
- if (beforeSlashParts[0].indexOf(' ') >= 0 && afterSlashParts[0] === '') {
958
- this.HIDE_CANNED_RESPONSES = false
959
- this.logger.log('[CONVS-DETAIL] - returnChangeTextArea --> beforeSlash there is a white space After Not');
960
- // if (beforeSlashParts[0].indexOf(' ') >= 0 && afterSlashParts[0].indexOf(' ') >= 0)
961
- } else if (beforeSlashParts[0].indexOf(' ') < 0 && afterSlashParts[0] === '') {
962
- this.HIDE_CANNED_RESPONSES = true;
963
- this.tagsCannedFilter = []
964
- this.logger.log('[CONVS-DETAIL] - returnChangeTextArea --> beforeSlash not thete is a white space After Not');
965
- } else if (beforeSlashParts[0].indexOf(' ') >= 0 && afterSlashParts[0] === ' ') {
966
- this.logger.log('[CONVS-DETAIL] - returnChangeTextArea --> beforeSlash not thete is a white space After YES');
967
- this.HIDE_CANNED_RESPONSES = true;
968
- this.tagsCannedFilter = []
969
+ var after_slash = message.substring(message.lastIndexOf("/") + 1, message.length);
970
+ if (pos === 0 && after_slash.length === 1 && after_slash.trim() === '') {
971
+ this.logger.log('[CONVS-DETAIL] - returnChangeTextArea after_slash --> there is a white space after ');
972
+ this.HIDE_CANNED_RESPONSES = true
973
+ this.tagsCannedFilter = []
974
+ } else if (pos === 0 && after_slash.length === 0) {
975
+ this.logger.log('[CONVS-DETAIL] - returnChangeTextArea after_slash --> there is NOT a white space after');
976
+ this.HIDE_CANNED_RESPONSES = false
977
+ }
978
+
979
+
980
+ if (pos > 0) {
981
+
982
+ // ------------------------------------------------------------------------------------------------------------------------------------------
983
+ // Hide / display Canned when the SLASH has POSITION POS > and checking if there is a space after the SLASH (in this case they it be hidden)
984
+ // and if there is not a space before the SLASH (in this it will be hidden)
985
+ // ------------------------------------------------------------------------------------------------------------------------------------------
986
+
987
+ let beforeSlash = message.substr(pos - 1)
988
+ let afterSlash = message.substr(pos + 1)
989
+ this.logger.log('[CONVS-DETAIL] - returnChangeTextArea * POS ', pos);
990
+
991
+ this.logger.log('[CONVS-DETAIL] - returnChangeTextArea --> beforeSlash', beforeSlash);
992
+ this.logger.log('[CONVS-DETAIL] - returnChangeTextArea --> afterSlash', afterSlash);
993
+ var afterSlashParts = afterSlash.split("/")
994
+ var beforeSlashParts = beforeSlash.split("/")
995
+ this.logger.log('[CONVS-DETAIL] - returnChangeTextArea --> afterSlash parts', afterSlashParts);
996
+ this.logger.log('[CONVS-DETAIL] - returnChangeTextArea --> beforeSlash parts', beforeSlashParts);
997
+
998
+ if (beforeSlashParts.length === 2) {
999
+ if (beforeSlashParts[0].indexOf(' ') >= 0 && afterSlashParts[0] === '') {
1000
+ this.HIDE_CANNED_RESPONSES = false
1001
+ this.logger.log('[CONVS-DETAIL] - returnChangeTextArea --> beforeSlash there is a white space After Not');
1002
+ // if (beforeSlashParts[0].indexOf(' ') >= 0 && afterSlashParts[0].indexOf(' ') >= 0)
1003
+ } else if (beforeSlashParts[0].indexOf(' ') < 0 && afterSlashParts[0] === '') {
1004
+ this.HIDE_CANNED_RESPONSES = true;
1005
+ this.tagsCannedFilter = []
1006
+ this.logger.log('[CONVS-DETAIL] - returnChangeTextArea --> beforeSlash not thete is a white space After Not');
1007
+ } else if (beforeSlashParts[0].indexOf(' ') >= 0 && afterSlashParts[0] === ' ') {
1008
+ this.logger.log('[CONVS-DETAIL] - returnChangeTextArea --> beforeSlash not thete is a white space After YES');
1009
+ this.HIDE_CANNED_RESPONSES = true;
1010
+ this.tagsCannedFilter = []
1011
+ }
969
1012
  }
970
1013
  }
971
- }
972
1014
 
973
1015
 
974
- } else {
975
- this.tagsCannedFilter = [];
1016
+ } else {
1017
+ this.tagsCannedFilter = [];
1018
+ }
976
1019
  }
977
- }
978
- }, 300);
1020
+ }, 300);
1021
+
1022
+ }
979
1023
  // ./ CANNED RESPONSES //
980
1024
 
981
1025
  } catch (err) {
@@ -983,6 +1027,8 @@ export class ConversationDetailPage implements OnInit, OnDestroy, AfterViewInit
983
1027
  }
984
1028
  }
985
1029
 
1030
+
1031
+
986
1032
  // ----------------------------------------------------------
987
1033
  // @ CANNED RESPONSES methods
988
1034
  // ----------------------------------------------------------
@@ -1052,7 +1098,8 @@ export class ConversationDetailPage implements OnInit, OnDestroy, AfterViewInit
1052
1098
  this.logger.log('[CONVS-DETAIL] - loadTagsCanned getCannedResponses RES', res);
1053
1099
 
1054
1100
  this.tagsCanned = res
1055
-
1101
+ this.tagsCannedCount = res.length
1102
+ this.logger.log('[CONVS-DETAIL] - loadTagsCanned getCannedResponses tagsCannedCount', this.tagsCannedCount);
1056
1103
  if (this.HIDE_CANNED_RESPONSES === false) {
1057
1104
  this.showTagsCanned(strSearch);
1058
1105
  }
@@ -1082,10 +1129,12 @@ export class ConversationDetailPage implements OnInit, OnDestroy, AfterViewInit
1082
1129
  strReplace = "<b class='highlight-search-string'>" + strSearch + "</b>";
1083
1130
  }
1084
1131
  for (var i = 0; i < this.tagsCannedFilter.length; i++) {
1085
-
1086
1132
  const textCanned = "<div class='cannedText'>" + this.replacePlaceholderInCanned(this.tagsCannedFilter[i].text) + "</div>";
1087
1133
  this.tagsCannedFilter[i].title = "<div class='cannedContent'><div class='cannedTitle'>" + this.tagsCannedFilter[i].title.toString().replace(strSearch, strReplace.trim()) + "</div>" + textCanned + '</div>';
1088
-
1134
+ }
1135
+ if (this.tagsCannedCount === 0) {
1136
+ const nocanned = { 'title': "<div class='cannedContent'><div class='cannedTitle nocannedTitle'>" + this.translationMap.get('THERE_ARE_NO_CANNED_RESPONSES_AVAILABLE') + ".</div><div class='cannedText'>" + this.translationMap.get('TO_CREATE_THEM_GO_TO_THE_PROJECT') + "</div></div>", "text": "There are no canned responses available" }
1137
+ this.tagsCannedFilter.push(nocanned)
1089
1138
  }
1090
1139
  }
1091
1140
 
@@ -1101,10 +1150,7 @@ export class ConversationDetailPage implements OnInit, OnDestroy, AfterViewInit
1101
1150
 
1102
1151
  replacePlaceholderInCanned(str) {
1103
1152
  this.logger.log('[CONVS-DETAIL] - replacePlaceholderInCanned str ', str);
1104
-
1105
-
1106
1153
  str = str.replace('$recipient_name', this.conversationWithFullname);
1107
-
1108
1154
  if (this.loggedUser && this.loggedUser.fullname) {
1109
1155
  str = str.replace('$agent_name', this.loggedUser.fullname);
1110
1156
  }
@@ -1129,8 +1175,6 @@ export class ConversationDetailPage implements OnInit, OnDestroy, AfterViewInit
1129
1175
  this.arrowkeyLocation = -1
1130
1176
  this.tagsCannedFilter = [];
1131
1177
  this.logger.log("[CONVS-DETAIL] replaceTagInMessage canned text ", canned.text);
1132
- // // prendo val input
1133
-
1134
1178
 
1135
1179
 
1136
1180
  // replace text
@@ -1153,6 +1197,77 @@ export class ConversationDetailPage implements OnInit, OnDestroy, AfterViewInit
1153
1197
  }
1154
1198
 
1155
1199
 
1200
+ hasClickedOpenCannedResponses($event) {
1201
+ this.logger.log('[CONVS-DETAIL] - hasClickedOpenCannedResponses ', $event)
1202
+ const elTextArea = this.rowTextArea['el'];
1203
+ const textArea = elTextArea.getElementsByTagName('ion-textarea')[0];
1204
+
1205
+ this.logger.log("[CONVS-DETAIL] hasClickedOpenCannedResponses textArea ", textArea);
1206
+ this.logger.log("[CONVS-DETAIL] hasClickedOpenCannedResponses textArea value", textArea.value)
1207
+ this.insertAtCursor(textArea, '/');
1208
+ // console.log('[CONVS-DETAIL] hasClickedOpenCannedResponses textArea.value', textArea.value)
1209
+ // setTimeout(() => {
1210
+ // // if (textArea.value === '/') {
1211
+ // // textArea.focus();
1212
+ // textArea.setFocus();
1213
+ // // }
1214
+ // }, 1500);
1215
+
1216
+ this.setCaretPosition(textArea)
1217
+ }
1218
+
1219
+ setCaretPosition(ctrl) {
1220
+ ctrl.value.trim()
1221
+ ctrl.setFocus();
1222
+ }
1223
+
1224
+ insertAtCursor(myField, myValue) {
1225
+ this.logger.log('[CONVS-DETAIL] - insertAtCursor - myValue ', myValue);
1226
+ this.logger.log('[CONVS-DETAIL] - insertAtCursor - myField ', myField);
1227
+
1228
+
1229
+ // myValue = ' ' + myValue;
1230
+
1231
+ // console.log('[CONVS-DETAIL] - GET TEXT AREA - Here yes myValue ', myValue);
1232
+ // console.log('[CONVS-DETAIL] - GET TEXT AREA - Here yes textArea value length', myField.value.length);
1233
+
1234
+ if (myField.value.length > 0) {
1235
+ myValue = ' ' + myValue;
1236
+ }
1237
+
1238
+ //IE support
1239
+ if (myField.selection) {
1240
+ myField.focus();
1241
+ let sel = myField.selection.createRange();
1242
+ sel.text = myValue;
1243
+ // this.cannedResponseMessage = sel.text;
1244
+ }
1245
+ //MOZILLA and others
1246
+ else if (myField.selectionStart || myField.selectionStart == '0') {
1247
+ var startPos = myField.selectionStart;
1248
+ this.logger.log('[CONVS-DETAIL] - insertAtCursor - startPos ', startPos);
1249
+
1250
+ var endPos = myField.selectionEnd;
1251
+ this.logger.log('[CONVS-DETAIL] - insertAtCursor - endPos ', endPos);
1252
+
1253
+ myField.value = myField.value.substring(0, startPos) + myValue + myField.value.substring(endPos, myField.value.length);
1254
+
1255
+ // place cursor at end of text in text input element
1256
+ myField.focus();
1257
+ var val = myField.value; //store the value of the element
1258
+ myField.value = ''; //clear the value of the element
1259
+ myField.value = val + ' '; //set that value back.
1260
+
1261
+ // this.cannedResponseMessage = myField.value;
1262
+
1263
+ // this.texareaIsEmpty = false;
1264
+ // myField.select();
1265
+ } else {
1266
+ myField.value += myValue;
1267
+ // this.cannedResponseMessage = myField.value;
1268
+ }
1269
+ }
1270
+
1156
1271
  @HostListener('document:keydown', ['$event'])
1157
1272
  handleKeyboardEvent(event: KeyboardEvent) {
1158
1273
  // this.logger.log("CONVERSATION-DETAIL handleKeyboardEvent event.key ", event.key);