@chat21/chat21-ionic 3.0.61-rc11 → 3.0.61-rc15
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 +22 -0
- package/angular.json +1 -0
- package/package.json +2 -1
- package/src/app/app-routing.module.ts +5 -0
- package/src/app/app.module.ts +6 -3
- package/src/app/chatlib/conversation-detail/ion-conversation-detail/ion-conversation-detail.component.html +36 -25
- package/src/app/chatlib/conversation-detail/ion-conversation-detail/ion-conversation-detail.component.scss +160 -50
- package/src/app/chatlib/conversation-detail/ion-conversation-detail/ion-conversation-detail.component.ts +101 -18
- package/src/app/chatlib/conversation-detail/message/bubble-message/bubble-message.component.html +21 -36
- package/src/app/chatlib/conversation-detail/message/bubble-message/bubble-message.component.scss +19 -7
- package/src/app/chatlib/conversation-detail/message/bubble-message/bubble-message.component.ts +35 -40
- package/src/app/components/conversation-detail/header-conversation-detail/header-conversation-detail.component.scss +2 -0
- package/src/app/components/conversation-detail/header-conversation-detail/header-conversation-detail.component.ts +28 -25
- package/src/app/components/conversation-detail/message-text-area/message-text-area.component.html +57 -20
- package/src/app/components/conversation-detail/message-text-area/message-text-area.component.scss +32 -9
- package/src/app/components/conversation-detail/message-text-area/message-text-area.component.ts +93 -24
- package/src/app/components/project-item/project-item.component.scss +1 -1
- package/src/app/components/sidebar/sidebar.component.html +36 -35
- package/src/app/components/sidebar/sidebar.component.ts +72 -26
- package/src/app/components/sidebar-user-details/sidebar-user-details.component.html +7 -0
- package/src/app/components/sidebar-user-details/sidebar-user-details.component.scss +13 -1
- package/src/app/components/sidebar-user-details/sidebar-user-details.component.ts +11 -7
- package/src/app/pages/conversation-detail/conversation-detail.module.ts +5 -1
- package/src/app/pages/conversation-detail/conversation-detail.page.html +19 -11
- package/src/app/pages/conversation-detail/conversation-detail.page.scss +28 -0
- package/src/app/pages/conversation-detail/conversation-detail.page.ts +221 -368
- package/src/app/pages/conversations-list/conversations-list.page.ts +6 -18
- package/src/app/pages/create-canned-response/create-canned-response-routing.module.ts +17 -0
- package/src/app/pages/create-canned-response/create-canned-response.module.ts +30 -0
- package/src/app/pages/create-canned-response/create-canned-response.page.html +150 -0
- package/src/app/pages/create-canned-response/create-canned-response.page.scss +55 -0
- package/src/app/pages/create-canned-response/create-canned-response.page.spec.ts +24 -0
- package/src/app/pages/create-canned-response/create-canned-response.page.ts +319 -0
- package/src/app/pages/create-requester/create-requester.page.html +1 -1
- package/src/app/pages/create-requester/create-requester.page.ts +1 -0
- package/src/app/pages/create-ticket/create-ticket.page.html +1 -1
- package/src/app/pages/create-ticket/create-ticket.page.ts +13 -4
- package/src/app/pages/profile-info/profile-info.page.html +2 -2
- package/src/app/pages/profile-info/profile-info.page.scss +12 -1
- package/src/app/services/tiledesk/tiledesk.service.ts +28 -0
- package/src/app/shared/shared.module.ts +1 -1
- package/src/assets/i18n/de.json +17 -3
- package/src/assets/i18n/en.json +17 -3
- package/src/assets/i18n/es.json +17 -3
- package/src/assets/i18n/fr.json +17 -3
- package/src/assets/i18n/it.json +17 -3
- package/src/assets/i18n/pt.json +17 -3
- package/src/assets/i18n/ru.json +17 -3
- package/src/assets/i18n/sr.json +17 -3
- package/src/assets/i18n/tr.json +17 -3
- package/src/chat21-core/providers/firebase/firebase-conversation-handler.ts +8 -3
- package/src/chat21-core/utils/utils-message.ts +19 -0
- package/src/global.scss +8 -0
|
@@ -291,7 +291,7 @@ export class ConversationListPage implements OnInit {
|
|
|
291
291
|
this.subscription.unsubscribe()
|
|
292
292
|
}
|
|
293
293
|
|
|
294
|
-
ionViewDidEnter() {}
|
|
294
|
+
ionViewDidEnter() { }
|
|
295
295
|
|
|
296
296
|
getLastProjectId(projectid: string) {
|
|
297
297
|
this.logger.log('[CONVS-LIST-PAGE] - GET LAST PROJECT ID', projectid)
|
|
@@ -1080,16 +1080,13 @@ export class ConversationListPage implements OnInit {
|
|
|
1080
1080
|
}
|
|
1081
1081
|
|
|
1082
1082
|
listenToCloseConvFromHeaderConversation() {
|
|
1083
|
-
this.events.subscribe('
|
|
1083
|
+
this.events.subscribe('conversation:closed', (convId) => {
|
|
1084
1084
|
this.logger.log('[CONVS-LIST-PAGE] hasclosedconversation convId', convId)
|
|
1085
1085
|
|
|
1086
1086
|
const conversation = this.conversations.find(
|
|
1087
1087
|
(conv) => conv.uid === convId,
|
|
1088
1088
|
)
|
|
1089
|
-
this.logger.log(
|
|
1090
|
-
'[CONVS-LIST-PAGE] hasclosedconversation conversation',
|
|
1091
|
-
conversation,
|
|
1092
|
-
)
|
|
1089
|
+
this.logger.log('[CONVS-LIST-PAGE] hasclosedconversation conversation', conversation)
|
|
1093
1090
|
this.onCloseConversation(conversation)
|
|
1094
1091
|
})
|
|
1095
1092
|
}
|
|
@@ -1099,10 +1096,7 @@ export class ConversationListPage implements OnInit {
|
|
|
1099
1096
|
// https://github.com/chat21/chat21-cloud-functions/blob/master/docs/api.md#delete-a-conversation
|
|
1100
1097
|
// ----------------------------------------------------------------------------------------------
|
|
1101
1098
|
onCloseConversation(conversation: ConversationModel) {
|
|
1102
|
-
this.logger.log(
|
|
1103
|
-
'[CONVS-LIST-PAGE] onCloseConversation conversation',
|
|
1104
|
-
conversation,
|
|
1105
|
-
)
|
|
1099
|
+
this.logger.log('[CONVS-LIST-PAGE] onCloseConversation conversation', conversation)
|
|
1106
1100
|
|
|
1107
1101
|
// -------------------------------------------------------------------------------------
|
|
1108
1102
|
// Fix the display of the message "No conversation yet" when a conversation is archived
|
|
@@ -1111,17 +1105,11 @@ export class ConversationListPage implements OnInit {
|
|
|
1111
1105
|
// -------------------------------------------------------------------------------------
|
|
1112
1106
|
this.loadingIsActive = false
|
|
1113
1107
|
// console.log('CONVS - CONV-LIST-PAGE onCloseConversation CONVS: ', conversation)
|
|
1114
|
-
this.logger.log(
|
|
1115
|
-
'[CONVS-LIST-PAGE] onCloseConversation loadingIsActive: ',
|
|
1116
|
-
this.loadingIsActive,
|
|
1117
|
-
)
|
|
1108
|
+
this.logger.log('[CONVS-LIST-PAGE] onCloseConversation loadingIsActive: ', this.loadingIsActive)
|
|
1118
1109
|
if (conversation) {
|
|
1119
1110
|
const conversationId = conversation.uid
|
|
1120
1111
|
|
|
1121
|
-
this.logger.log(
|
|
1122
|
-
'[CONVS-LIST-PAGE] onCloseConversation conversationId: ',
|
|
1123
|
-
conversationId,
|
|
1124
|
-
)
|
|
1112
|
+
this.logger.log( '[CONVS-LIST-PAGE] onCloseConversation conversationId: ', conversationId )
|
|
1125
1113
|
|
|
1126
1114
|
const conversationWith_segments = conversationId.split('-')
|
|
1127
1115
|
this.logger.log(
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { NgModule } from '@angular/core';
|
|
2
|
+
import { Routes, RouterModule } from '@angular/router';
|
|
3
|
+
|
|
4
|
+
import { CreateCannedResponsePage } from './create-canned-response.page';
|
|
5
|
+
|
|
6
|
+
const routes: Routes = [
|
|
7
|
+
{
|
|
8
|
+
path: '',
|
|
9
|
+
component: CreateCannedResponsePage
|
|
10
|
+
}
|
|
11
|
+
];
|
|
12
|
+
|
|
13
|
+
@NgModule({
|
|
14
|
+
imports: [RouterModule.forChild(routes)],
|
|
15
|
+
exports: [RouterModule],
|
|
16
|
+
})
|
|
17
|
+
export class CreateCannedResponsePageRoutingModule {}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { NgModule } from '@angular/core';
|
|
2
|
+
import { CommonModule } from '@angular/common';
|
|
3
|
+
import { FormsModule ,ReactiveFormsModule} from '@angular/forms';
|
|
4
|
+
|
|
5
|
+
import { IonicModule } from '@ionic/angular';
|
|
6
|
+
|
|
7
|
+
import { CreateCannedResponsePageRoutingModule } from './create-canned-response-routing.module';
|
|
8
|
+
|
|
9
|
+
import { CreateCannedResponsePage } from './create-canned-response.page';
|
|
10
|
+
import { TranslateLoader, TranslateModule} from '@ngx-translate/core';
|
|
11
|
+
import { createTranslateLoader } from '../../../chat21-core/utils/utils';
|
|
12
|
+
import { HttpClient } from '@angular/common/http';
|
|
13
|
+
@NgModule({
|
|
14
|
+
imports: [
|
|
15
|
+
CommonModule,
|
|
16
|
+
FormsModule,
|
|
17
|
+
ReactiveFormsModule,
|
|
18
|
+
IonicModule,
|
|
19
|
+
CreateCannedResponsePageRoutingModule,
|
|
20
|
+
TranslateModule.forChild({
|
|
21
|
+
loader: {
|
|
22
|
+
provide: TranslateLoader,
|
|
23
|
+
useFactory: (createTranslateLoader),
|
|
24
|
+
deps: [HttpClient]
|
|
25
|
+
}
|
|
26
|
+
})
|
|
27
|
+
],
|
|
28
|
+
declarations: [CreateCannedResponsePage]
|
|
29
|
+
})
|
|
30
|
+
export class CreateCannedResponsePageModule {}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
<ion-header>
|
|
2
|
+
<ion-toolbar>
|
|
3
|
+
<ion-title>{{'AddNewCannedResponse' | translate}}</ion-title>
|
|
4
|
+
|
|
5
|
+
<ion-buttons slot="end">
|
|
6
|
+
<ion-button ion-button fill="clear" (click)="closeModalCreateCannedResponseModal()">
|
|
7
|
+
<ion-icon slot="icon-only" name="close"></ion-icon>
|
|
8
|
+
</ion-button>
|
|
9
|
+
</ion-buttons>
|
|
10
|
+
</ion-toolbar>
|
|
11
|
+
</ion-header>
|
|
12
|
+
|
|
13
|
+
<ion-menu side="start" menu-id="custom" content-id="main" class="my-custom-menu">
|
|
14
|
+
<!-- <ion-header>
|
|
15
|
+
<ion-toolbar color="tertiary">
|
|
16
|
+
<ion-title>Custom Menu</ion-title>
|
|
17
|
+
</ion-toolbar>
|
|
18
|
+
</ion-header> -->
|
|
19
|
+
<ion-content>
|
|
20
|
+
<ion-list>
|
|
21
|
+
<ion-item button (click)="addRecipientNamePlaceholderToTheMsg()"
|
|
22
|
+
(mouseover)="onOverBtnAddRecipientNamePlaceholder()"
|
|
23
|
+
(mouseout)="onOutBtnAddRecipientNamePlaceholder()">
|
|
24
|
+
<ion-label>
|
|
25
|
+
{{'First_name_of_recipient' | translate}}
|
|
26
|
+
</ion-label>
|
|
27
|
+
</ion-item>
|
|
28
|
+
<ion-item button (click)="addAgentNamePlaceholderToTheMsg()"
|
|
29
|
+
(mouseover)="onOverBtnAddAgentNamePlaceholder()"
|
|
30
|
+
(mouseout)="onOutBtnAddAgentNamePlaceholder()">
|
|
31
|
+
<ion-label>
|
|
32
|
+
{{'First_name_of_agent' | translate}}
|
|
33
|
+
</ion-label>
|
|
34
|
+
</ion-item>
|
|
35
|
+
|
|
36
|
+
</ion-list>
|
|
37
|
+
<!-- <ion-note> </ion-note> -->
|
|
38
|
+
<ion-grid>
|
|
39
|
+
<ion-row>
|
|
40
|
+
<ion-col class="ion-padding">
|
|
41
|
+
<div class="ion-text-center">
|
|
42
|
+
<h6
|
|
43
|
+
*ngIf="mouseOverBtnAddRecipientNamePlaceholder === false && mouseOverBtnAddAgentNamePlaceholder === false"
|
|
44
|
+
ion-text class="note-text">
|
|
45
|
+
<!-- Seleziona una valore personalizzato da aggiungere al messaggio. -->
|
|
46
|
+
{{'SelectACustomizationToAddToYourMessage' | translate}}
|
|
47
|
+
</h6>
|
|
48
|
+
<h6
|
|
49
|
+
*ngIf="mouseOverBtnAddRecipientNamePlaceholder === true && mouseOverBtnAddAgentNamePlaceholder === false"
|
|
50
|
+
ion-text class="note-text">
|
|
51
|
+
<!-- Il nome della persona a cui l'agente sta rispondendo verrà aggiunto al messaggio. -->
|
|
52
|
+
{{'recipient_name_desc' | translate}}
|
|
53
|
+
</h6>
|
|
54
|
+
|
|
55
|
+
<h6
|
|
56
|
+
*ngIf="mouseOverBtnAddRecipientNamePlaceholder === false && mouseOverBtnAddAgentNamePlaceholder === true"
|
|
57
|
+
ion-text class="note-text">
|
|
58
|
+
<!-- Il nome dell'agente che sta rispondendo verrà aggiunto al messaggio. -->
|
|
59
|
+
{{'agent_name_desc' | translate }}
|
|
60
|
+
</h6>
|
|
61
|
+
|
|
62
|
+
</div>
|
|
63
|
+
</ion-col>
|
|
64
|
+
</ion-row>
|
|
65
|
+
</ion-grid>
|
|
66
|
+
|
|
67
|
+
</ion-content>
|
|
68
|
+
</ion-menu>
|
|
69
|
+
<!-- <ion-router-outlet id="menuContent"></ion-router-outlet> -->
|
|
70
|
+
|
|
71
|
+
<ion-content id="create-canned-response-content">
|
|
72
|
+
<form [formGroup]="validations_form" (ngSubmit)="onSubmit(validations_form.value)">
|
|
73
|
+
<ion-grid>
|
|
74
|
+
<ion-row>
|
|
75
|
+
<ion-col size="12">
|
|
76
|
+
<!-- ---------------------------------------------- -->
|
|
77
|
+
<!-- Canned response title -->
|
|
78
|
+
<!-- ---------------------------------------------- -->
|
|
79
|
+
<ion-item>
|
|
80
|
+
<ion-label class="custom-label-size" for="title" position="stacked" color="primary">
|
|
81
|
+
{{'Title' | translate}} *
|
|
82
|
+
</ion-label>
|
|
83
|
+
<ion-input placeholder="{{'EnterCannedResponseTitle' | translate}}" id="title" type="text" formControlName="title">
|
|
84
|
+
</ion-input>
|
|
85
|
+
</ion-item>
|
|
86
|
+
<div class="validation-errors">
|
|
87
|
+
<ng-container *ngFor="let validation of validation_messages.title">
|
|
88
|
+
<div class="error-message"
|
|
89
|
+
*ngIf="validations_form.get('title').hasError(validation.type) && (validations_form.get('title').dirty || validations_form.get('title').touched)">
|
|
90
|
+
<ion-icon name="information-circle-outline"></ion-icon>
|
|
91
|
+
<span class="validation-message"> {{ validation.message }} </span>
|
|
92
|
+
</div>
|
|
93
|
+
</ng-container>
|
|
94
|
+
</div>
|
|
95
|
+
</ion-col>
|
|
96
|
+
|
|
97
|
+
<!-- ---------------------------------------------- -->
|
|
98
|
+
<!-- Canned response Message -->
|
|
99
|
+
<!-- ---------------------------------------------- -->
|
|
100
|
+
<ion-col size="12">
|
|
101
|
+
<ion-item>
|
|
102
|
+
<ion-label class="custom-label-size" for="message" position="stacked" color="primary">
|
|
103
|
+
{{'Message' | translate}} *
|
|
104
|
+
</ion-label>
|
|
105
|
+
<ion-textarea placeholder="{{'WriteMsgToSendToYourVisitors' | translate}}"
|
|
106
|
+
(ngModelChange)="cannedResponseMessageChanged($event)" class="canned-response-texarea" rows="4"
|
|
107
|
+
id="message" type="text" formControlName="message"></ion-textarea>
|
|
108
|
+
</ion-item>
|
|
109
|
+
<div class="validation-errors">
|
|
110
|
+
<ng-container *ngFor="let validation of validation_messages.message">
|
|
111
|
+
<div class="error-message"
|
|
112
|
+
*ngIf="validations_form.get('message').hasError(validation.type) && (validations_form.get('message').dirty || validations_form.get('message').touched)">
|
|
113
|
+
<ion-icon name="information-circle-outline"></ion-icon>
|
|
114
|
+
<span class="validation-message"> {{ validation.message }} </span>
|
|
115
|
+
|
|
116
|
+
</div>
|
|
117
|
+
</ng-container>
|
|
118
|
+
</div>
|
|
119
|
+
</ion-col>
|
|
120
|
+
|
|
121
|
+
<!-- ---------------------------------------------- -->
|
|
122
|
+
<!-- Button Add personalisation -->
|
|
123
|
+
<!-- ---------------------------------------------- -->
|
|
124
|
+
<ion-col size="12" style="text-align: right;">
|
|
125
|
+
<ion-button ion-button fill="clear" size="small" (click)="openAddPersonalisationMenu()">
|
|
126
|
+
<span style="color:#999999">
|
|
127
|
+
<!-- Aggiungi personalizzazione -->
|
|
128
|
+
{{'AddCustomization' | translate}}
|
|
129
|
+
</span>
|
|
130
|
+
</ion-button>
|
|
131
|
+
</ion-col>
|
|
132
|
+
|
|
133
|
+
<!-- ---------------------------------------------- -->
|
|
134
|
+
<!-- Button Subbmit -->
|
|
135
|
+
<!-- ---------------------------------------------- -->
|
|
136
|
+
<ion-col size="12" style="text-align: center;">
|
|
137
|
+
<ion-button color="primary" class="submit-btn" type="submit" [disabled]="!validations_form.valid">
|
|
138
|
+
<ion-icon *ngIf="showSpinnerCreateCannedResponse === false" style="font-size: 1.9em;" slot="start"
|
|
139
|
+
name="add-circle-outline"></ion-icon>
|
|
140
|
+
<ion-spinner *ngIf="showSpinnerCreateCannedResponse === true"
|
|
141
|
+
style="color: #fff; margin: 0px 0.3em 0px -0.3em;" name="bubbles" duration="2"></ion-spinner>
|
|
142
|
+
{{'Add' | translate}}
|
|
143
|
+
</ion-button>
|
|
144
|
+
</ion-col>
|
|
145
|
+
</ion-row>
|
|
146
|
+
</ion-grid>
|
|
147
|
+
</form>
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
</ion-content>
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
#create-canned-response-content {
|
|
2
|
+
.validation-errors {
|
|
3
|
+
height: 20px;
|
|
4
|
+
// margin-bottom: 16px;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
.error-message {
|
|
8
|
+
// color: red;
|
|
9
|
+
// font-size: 14px;
|
|
10
|
+
// margin-left: 10px;
|
|
11
|
+
// margin-top: 10px;
|
|
12
|
+
ion-icon {
|
|
13
|
+
color: red;
|
|
14
|
+
font-size: 16px;
|
|
15
|
+
margin-left: 15px;
|
|
16
|
+
margin-right: 3px;
|
|
17
|
+
position: relative;
|
|
18
|
+
top: 3px;
|
|
19
|
+
}
|
|
20
|
+
.validation-message {
|
|
21
|
+
color: red;
|
|
22
|
+
font-size: 14px;
|
|
23
|
+
margin-top: 1px;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.submit-btn {
|
|
28
|
+
margin: 48px 12px 12px;
|
|
29
|
+
min-width: 150px;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
ion-textarea {
|
|
33
|
+
--placeholder-color: #d3d3d3;
|
|
34
|
+
--placeholder-opacity: 1;
|
|
35
|
+
}
|
|
36
|
+
ion-input {
|
|
37
|
+
--placeholder-color: #d3d3d3;
|
|
38
|
+
--placeholder-opacity: 1;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.my-custom-menu {
|
|
43
|
+
--width: 500px;
|
|
44
|
+
margin-top: 57px;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.note-text {
|
|
48
|
+
color: #a6a6a6;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.custom-label-size {
|
|
52
|
+
font-size: 1.2em;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
|
2
|
+
import { IonicModule } from '@ionic/angular';
|
|
3
|
+
|
|
4
|
+
import { CreateCannedResponsePage } from './create-canned-response.page';
|
|
5
|
+
|
|
6
|
+
describe('CreateCannedResponsePage', () => {
|
|
7
|
+
let component: CreateCannedResponsePage;
|
|
8
|
+
let fixture: ComponentFixture<CreateCannedResponsePage>;
|
|
9
|
+
|
|
10
|
+
beforeEach(async(() => {
|
|
11
|
+
TestBed.configureTestingModule({
|
|
12
|
+
declarations: [ CreateCannedResponsePage ],
|
|
13
|
+
imports: [IonicModule.forRoot()]
|
|
14
|
+
}).compileComponents();
|
|
15
|
+
|
|
16
|
+
fixture = TestBed.createComponent(CreateCannedResponsePage);
|
|
17
|
+
component = fixture.componentInstance;
|
|
18
|
+
fixture.detectChanges();
|
|
19
|
+
}));
|
|
20
|
+
|
|
21
|
+
it('should create', () => {
|
|
22
|
+
expect(component).toBeTruthy();
|
|
23
|
+
});
|
|
24
|
+
});
|
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
import { Component, Input, OnInit } from '@angular/core';
|
|
2
|
+
import { ModalController } from '@ionic/angular';
|
|
3
|
+
import { Validators, FormBuilder, FormGroup, FormControl } from '@angular/forms';
|
|
4
|
+
import { TranslateService } from '@ngx-translate/core';
|
|
5
|
+
import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service';
|
|
6
|
+
import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance';
|
|
7
|
+
import { TiledeskAuthService } from 'src/chat21-core/providers/tiledesk/tiledesk-auth.service';
|
|
8
|
+
import { TiledeskService } from 'src/app/services/tiledesk/tiledesk.service';
|
|
9
|
+
import { MenuController } from '@ionic/angular';
|
|
10
|
+
import { EventsService } from 'src/app/services/events-service';
|
|
11
|
+
import { ActivatedRoute } from '@angular/router';
|
|
12
|
+
|
|
13
|
+
@Component({
|
|
14
|
+
selector: 'app-create-canned-response',
|
|
15
|
+
templateUrl: './create-canned-response.page.html',
|
|
16
|
+
styleUrls: ['./create-canned-response.page.scss'],
|
|
17
|
+
})
|
|
18
|
+
export class CreateCannedResponsePage implements OnInit {
|
|
19
|
+
|
|
20
|
+
public canned_response_title: string;
|
|
21
|
+
public canned_response_message: string;
|
|
22
|
+
validations_form: FormGroup;
|
|
23
|
+
@Input() message: any
|
|
24
|
+
@Input() conversationWith: string;
|
|
25
|
+
logger: LoggerService = LoggerInstance.getInstance();
|
|
26
|
+
|
|
27
|
+
prjctID: string;
|
|
28
|
+
tiledeskToken: string;
|
|
29
|
+
showSpinnerCreateCannedResponse: boolean = false;
|
|
30
|
+
addWhiteSpaceBefore: boolean;
|
|
31
|
+
mouseOverBtnAddRecipientNamePlaceholder: boolean = false;
|
|
32
|
+
mouseOverBtnAddAgentNamePlaceholder: boolean = false;
|
|
33
|
+
conversation_id: string
|
|
34
|
+
// public conversationWith: string;
|
|
35
|
+
constructor(
|
|
36
|
+
public modalController: ModalController,
|
|
37
|
+
private formBuilder: FormBuilder,
|
|
38
|
+
private translate: TranslateService,
|
|
39
|
+
public tiledeskAuthService: TiledeskAuthService,
|
|
40
|
+
public tiledeskService: TiledeskService,
|
|
41
|
+
private menu: MenuController,
|
|
42
|
+
public events: EventsService,
|
|
43
|
+
private route: ActivatedRoute,
|
|
44
|
+
) {
|
|
45
|
+
// this.route.paramMap.subscribe((params) => {
|
|
46
|
+
// console.log('[CONVS-DETAIL] - constructor -> params: ', params)
|
|
47
|
+
// this.conversationWith = params.get('IDConv')
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
// })
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
ngOnInit() {
|
|
56
|
+
// this.getCurrentProjectId();
|
|
57
|
+
// console.log('[CREATE-CANNED-RES] - conversationWith ', this.conversationWith)
|
|
58
|
+
// console.log('[CREATE-CANNED-RES] - message ', this.message)
|
|
59
|
+
if (this.message) {
|
|
60
|
+
this.conversation_id = this.message.recipient
|
|
61
|
+
this.logger.log('[CREATE-CANNED-RES] - conversationWith get from @input message (passed by bubble-message)', this.conversation_id)
|
|
62
|
+
} else {
|
|
63
|
+
this.logger.log('[CREATE-CANNED-RES] - @input message is UNDEFINED')
|
|
64
|
+
}
|
|
65
|
+
if (this.conversationWith) {
|
|
66
|
+
this.conversation_id = this.conversationWith;
|
|
67
|
+
this.logger.log('[CREATE-CANNED-RES] - conversationWith get from @input conversationWith (passed by conversation detail) ', this.conversation_id)
|
|
68
|
+
} else {
|
|
69
|
+
this.logger.log('[CREATE-CANNED-RES] - @input conversationWith is UNDEFINED')
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
this.tiledeskToken = this.tiledeskAuthService.getTiledeskToken()
|
|
73
|
+
this.logger.log('[CREATE-CANNED-RES] tiledeskToken ', this.tiledeskToken)
|
|
74
|
+
this.getCurrentProjectId(this.conversation_id, this.tiledeskToken);
|
|
75
|
+
|
|
76
|
+
// const stored_project = localStorage.getItem('last_project')
|
|
77
|
+
// const storedPrjctObjct = JSON.parse(stored_project)
|
|
78
|
+
// this.logger.log('[CREATE-CANNED-RES] storedPrjctObjct ', storedPrjctObjct)
|
|
79
|
+
// if (storedPrjctObjct) {
|
|
80
|
+
// this.prjctID = storedPrjctObjct.id_project.id
|
|
81
|
+
// this.logger.log('[CREATE-CANNED-RES] this.prjctID ', this.prjctID)
|
|
82
|
+
// }
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
this.buildForm()
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
getCurrentProjectId(conversation_id, tiledeskToken) {
|
|
90
|
+
const conversationWith_segments = conversation_id.split('-')
|
|
91
|
+
// Removes the last element of the array if is = to the separator
|
|
92
|
+
if (
|
|
93
|
+
conversationWith_segments[conversationWith_segments.length - 1] === ''
|
|
94
|
+
) {
|
|
95
|
+
conversationWith_segments.pop()
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if (conversationWith_segments.length === 4) {
|
|
99
|
+
const lastArrayElement = conversationWith_segments[conversationWith_segments.length - 1]
|
|
100
|
+
this.logger.log('[CREATE-CANNED-RES] - lastArrayElement ', lastArrayElement)
|
|
101
|
+
this.logger.log('[CREATE-CANNED-RES]- lastArrayElement length', lastArrayElement.length)
|
|
102
|
+
if (lastArrayElement.length !== 32) {
|
|
103
|
+
conversationWith_segments.pop()
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
this.logger.log('[CREATE-CANNED-RES] - loadTagsCanned conversationWith_segments ', conversationWith_segments)
|
|
108
|
+
// let projectId = ''
|
|
109
|
+
|
|
110
|
+
if (conversationWith_segments.length === 4) {
|
|
111
|
+
this.prjctID = conversationWith_segments[2]
|
|
112
|
+
this.logger.log('[CREATE-CANNED-RES] - loadTagsCanned projectId ', this.prjctID)
|
|
113
|
+
} else {
|
|
114
|
+
this.getProjectIdByConversationWith(conversation_id, tiledeskToken)
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
getProjectIdByConversationWith(conversationWith: string, tiledeskToken: string) {
|
|
119
|
+
// const tiledeskToken = this.tiledeskAuthService.getTiledeskToken()
|
|
120
|
+
|
|
121
|
+
this.tiledeskService
|
|
122
|
+
.getProjectIdByConvRecipient(tiledeskToken, conversationWith)
|
|
123
|
+
.subscribe(
|
|
124
|
+
(res) => {
|
|
125
|
+
this.logger.log('[CREATE-CANNED-RES] - GET PROJECTID BY CONV RECIPIENT RES', res)
|
|
126
|
+
if (res) {
|
|
127
|
+
this.prjctID = res.id_project
|
|
128
|
+
this.logger.log('[CREATE-CANNED-RES] - GET PROJECTID BY CONV RECIPIENT projectId ', this.prjctID)
|
|
129
|
+
|
|
130
|
+
}
|
|
131
|
+
},
|
|
132
|
+
(error) => {
|
|
133
|
+
this.logger.error('[CREATE-CANNED-RES] - GET PROJECTID BY CONV RECIPIENT - ERROR ', error)
|
|
134
|
+
},
|
|
135
|
+
() => {
|
|
136
|
+
this.logger.log('[CREATE-CANNED-RES] - GET PROJECTID BY CONV RECIPIENT * COMPLETE *',)
|
|
137
|
+
},
|
|
138
|
+
)
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
buildForm() {
|
|
143
|
+
this.validations_form = this.formBuilder.group({
|
|
144
|
+
title: new FormControl('', Validators.required),
|
|
145
|
+
message: new FormControl('', Validators.required),
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
this.setValues()
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
setValues() {
|
|
152
|
+
if (this.message && this.message.text) {
|
|
153
|
+
let cannedTitle = ''
|
|
154
|
+
const titleMaxCharacters = 37
|
|
155
|
+
if (this.message.text.length > titleMaxCharacters) {
|
|
156
|
+
cannedTitle = this.message.text.substring(0, titleMaxCharacters) + '...'
|
|
157
|
+
} else {
|
|
158
|
+
cannedTitle = this.message.text
|
|
159
|
+
}
|
|
160
|
+
this.logger.log('[CREATE-CANNED-RES] - cannedTitle ', cannedTitle.trim())
|
|
161
|
+
this.logger.log('[CREATE-CANNED-RES] - cannedMsg ', this.message.text.trim())
|
|
162
|
+
this.validations_form.controls['title'].setValue(cannedTitle);
|
|
163
|
+
this.validations_form.controls['message'].setValue(this.message.text);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
validation_messages = {
|
|
169
|
+
'title': [
|
|
170
|
+
{ type: 'required', message: this.translate.instant('TitleIsRequired') }
|
|
171
|
+
],
|
|
172
|
+
'message': [
|
|
173
|
+
{ type: 'required', message: this.translate.instant('MessageIsRequired') }
|
|
174
|
+
],
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
onSubmit(values) {
|
|
178
|
+
this.logger.log('[CREATE-CANNED-RES] ON SUBMIT VALUES', values);
|
|
179
|
+
this.canned_response_title = values.title
|
|
180
|
+
this.canned_response_message = values.message
|
|
181
|
+
this.logger.log('[CREATE-CANNED-RES] ON SUBMIT canned_response_title', this.canned_response_title);
|
|
182
|
+
this.logger.log('[CREATE-CANNED-RES] ON SUBMIT canned_response_title', this.canned_response_message);
|
|
183
|
+
this.createResponse(this.canned_response_message, this.canned_response_title)
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
createResponse(canned_response_message, canned_response_title) {
|
|
187
|
+
this.showSpinnerCreateCannedResponse = true;
|
|
188
|
+
this.logger.log('[CREATE-CANNED-RES] - CREATE CANNED RESP - MSG ', canned_response_message);
|
|
189
|
+
this.logger.log('[CREATE-CANNED-RES] - CREATE CANNED RESP - TITLE ', canned_response_title);
|
|
190
|
+
|
|
191
|
+
this.tiledeskService.createCannedResponse(canned_response_message.trim(), canned_response_title.trim(), this.prjctID, this.tiledeskToken)
|
|
192
|
+
.subscribe((responses: any) => {
|
|
193
|
+
this.logger.log('[CREATE-CANNED-RES] - CREATE CANNED RESP - RES ', responses);
|
|
194
|
+
|
|
195
|
+
}, (error) => {
|
|
196
|
+
this.logger.error('[CREATE-CANNED-RES]- CREATE CANNED RESP - ERROR ', error);
|
|
197
|
+
this.showSpinnerCreateCannedResponse = false;
|
|
198
|
+
}, () => {
|
|
199
|
+
this.logger.log('[CREATE-CANNED-RES] - CREATE CANNED RESP * COMPLETE *');
|
|
200
|
+
this.showSpinnerCreateCannedResponse = false;
|
|
201
|
+
this.closeModalCreateCannedResponseModal()
|
|
202
|
+
this.events.publish('newcannedresponse:created', true);
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
openAddPersonalisationMenu() {
|
|
207
|
+
this.menu.enable(true, 'custom');
|
|
208
|
+
this.menu.open('custom');
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
addRecipientNamePlaceholderToTheMsg() {
|
|
212
|
+
this.menu.close('custom')
|
|
213
|
+
this.menu.enable(false, 'custom');
|
|
214
|
+
this.insertCustomField('$recipient_name')
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
onOverBtnAddRecipientNamePlaceholder() {
|
|
218
|
+
this.mouseOverBtnAddRecipientNamePlaceholder = true;
|
|
219
|
+
this.logger.log('[CREATE-CANNED-RES] - isOverRecipientName ', this.mouseOverBtnAddRecipientNamePlaceholder);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
onOutBtnAddRecipientNamePlaceholder() {
|
|
223
|
+
this.mouseOverBtnAddRecipientNamePlaceholder = false;
|
|
224
|
+
this.logger.log('[CREATE-CANNED-RES] - isOutRecipientName ', this.mouseOverBtnAddRecipientNamePlaceholder);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
addAgentNamePlaceholderToTheMsg() {
|
|
228
|
+
this.menu.close('custom')
|
|
229
|
+
this.menu.enable(false, 'custom');
|
|
230
|
+
this.insertCustomField('$agent_name')
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
onOverBtnAddAgentNamePlaceholder() {
|
|
234
|
+
this.mouseOverBtnAddAgentNamePlaceholder = true;
|
|
235
|
+
this.logger.log('[CREATE-CANNED-RES] - isOverAgentName ', this.mouseOverBtnAddAgentNamePlaceholder);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
onOutBtnAddAgentNamePlaceholder() {
|
|
239
|
+
this.mouseOverBtnAddAgentNamePlaceholder = false;
|
|
240
|
+
this.logger.log('[CREATE-CANNED-RES] - isOutAgentName ', this.mouseOverBtnAddAgentNamePlaceholder);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
cannedResponseMessageChanged($event) {
|
|
248
|
+
this.logger.log('[CREATE-CANNED-RES] - ON MSG CHANGED ', $event);
|
|
249
|
+
|
|
250
|
+
if (/\s$/.test($event)) {
|
|
251
|
+
this.logger.log('[CREATE-CANNED-RES] - ON MSG CHANGED - string contains space at last');
|
|
252
|
+
this.addWhiteSpaceBefore = false;
|
|
253
|
+
} else {
|
|
254
|
+
this.logger.log('[CREATE-CANNED-RES] - ON MSG CHANGED - string does not contain space at last');
|
|
255
|
+
// IS USED TO ADD A WHITE SPACE TO THE 'PERSONALIZATION' VALUE IF THE STRING DOES NOT CONTAIN SPACE AT LAST
|
|
256
|
+
this.addWhiteSpaceBefore = true;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
insertCustomField(customfieldValue: string) {
|
|
262
|
+
const elTextarea = <HTMLElement>document.querySelector('.canned-response-texarea');
|
|
263
|
+
this.logger.log('[CREATE-CANNED-RES] - GET TEXT AREA - elTextarea ', elTextarea);
|
|
264
|
+
if (elTextarea) {
|
|
265
|
+
this.insertAtCursor(elTextarea, customfieldValue)
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
insertAtCursor(myField, myValue) {
|
|
269
|
+
this.logger.log('[CREATE-CANNED-RES] - insertAtCursor - myValue ', myValue);
|
|
270
|
+
|
|
271
|
+
if (this.addWhiteSpaceBefore === true) {
|
|
272
|
+
myValue = ' ' + myValue;
|
|
273
|
+
this.logger.log('[CREATE-CANNED-RES] - GET TEXT AREA - QUI ENTRO myValue ', myValue);
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
//IE support
|
|
277
|
+
if (myField.selection) {
|
|
278
|
+
myField.focus();
|
|
279
|
+
let sel = myField.selection.createRange();
|
|
280
|
+
sel.text = myValue;
|
|
281
|
+
// this.cannedResponseMessage = sel.text;
|
|
282
|
+
}
|
|
283
|
+
//MOZILLA and others
|
|
284
|
+
else if (myField.selectionStart || myField.selectionStart == '0') {
|
|
285
|
+
var startPos = myField.selectionStart;
|
|
286
|
+
this.logger.log('[CREATE-CANNED-RES] - insertAtCursor - startPos ', startPos);
|
|
287
|
+
|
|
288
|
+
var endPos = myField.selectionEnd;
|
|
289
|
+
this.logger.log('[CREATE-CANNED-RES] - insertAtCursor - endPos ', endPos);
|
|
290
|
+
|
|
291
|
+
myField.value = myField.value.substring(0, startPos) + myValue + myField.value.substring(endPos, myField.value.length);
|
|
292
|
+
|
|
293
|
+
// place cursor at end of text in text input element
|
|
294
|
+
myField.focus();
|
|
295
|
+
var val = myField.value; //store the value of the element
|
|
296
|
+
myField.value = ''; //clear the value of the element
|
|
297
|
+
myField.value = val + ' '; //set that value back.
|
|
298
|
+
|
|
299
|
+
// this.cannedResponseMessage = myField.value;
|
|
300
|
+
|
|
301
|
+
// this.texareaIsEmpty = false;
|
|
302
|
+
// myField.select();
|
|
303
|
+
} else {
|
|
304
|
+
myField.value += myValue;
|
|
305
|
+
// this.cannedResponseMessage = myField.value;
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
|
|
310
|
+
async closeModalCreateCannedResponseModal() {
|
|
311
|
+
if (this.menu) {
|
|
312
|
+
this.menu.close('custom')
|
|
313
|
+
this.menu.enable(false, 'custom');
|
|
314
|
+
}
|
|
315
|
+
await this.modalController.getTop()
|
|
316
|
+
this.modalController.dismiss({ confirmed: true })
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
}
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
</ion-col>
|
|
53
53
|
<!-- expand="block" -->
|
|
54
54
|
<ion-col size="12" style="text-align: center;">
|
|
55
|
-
<ion-button color="primary" class="submit-btn" type="submit" [disabled]="!validations_form.valid" style="width:
|
|
55
|
+
<ion-button color="primary" class="submit-btn" type="submit" [disabled]="!validations_form.valid" style="min-width:253px">
|
|
56
56
|
<ion-icon *ngIf="showSpinnerCreateRequester === false" style="font-size: 1.9em;" slot="start" name="add-circle-outline"></ion-icon>
|
|
57
57
|
<ion-spinner *ngIf="showSpinnerCreateRequester === true" style="color: #fff; margin: 0px 0.3em 0px -0.3em;" name="bubbles" duration="2" ></ion-spinner>
|
|
58
58
|
{{'CreateNewRequester' | translate}}</ion-button>
|
|
@@ -23,6 +23,7 @@ export class CreateRequesterPage implements OnInit {
|
|
|
23
23
|
showSpinnerCreateRequester: boolean = false;
|
|
24
24
|
requester_id: string;
|
|
25
25
|
logger: LoggerService = LoggerInstance.getInstance();
|
|
26
|
+
|
|
26
27
|
constructor(
|
|
27
28
|
public modalController: ModalController,
|
|
28
29
|
private formBuilder: FormBuilder,
|