@chat21/chat21-ionic 3.0.61-rc8 → 3.0.61

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 (89) hide show
  1. package/CHANGELOG.md +71 -0
  2. package/README.md +6 -0
  3. package/angular.json +2 -0
  4. package/config.xml +0 -1
  5. package/deploy_pre.sh +1 -1
  6. package/deploy_prod.sh +1 -1
  7. package/env.sample +1 -1
  8. package/package.json +4 -4
  9. package/src/app/app-routing.module.ts +15 -0
  10. package/src/app/app.component.ts +12 -9
  11. package/src/app/app.module.ts +11 -3
  12. package/src/app/chatlib/conversation-detail/ion-conversation-detail/ion-conversation-detail.component.html +36 -25
  13. package/src/app/chatlib/conversation-detail/ion-conversation-detail/ion-conversation-detail.component.scss +160 -50
  14. package/src/app/chatlib/conversation-detail/ion-conversation-detail/ion-conversation-detail.component.ts +108 -18
  15. package/src/app/chatlib/conversation-detail/message/bubble-message/bubble-message.component.html +21 -36
  16. package/src/app/chatlib/conversation-detail/message/bubble-message/bubble-message.component.scss +19 -7
  17. package/src/app/chatlib/conversation-detail/message/bubble-message/bubble-message.component.ts +35 -40
  18. package/src/app/chatlib/conversation-detail/message/message-attachment/message-attachment.component.scss +1 -1
  19. package/src/app/chatlib/list-conversations-component/list-conversations/list-conversations.component.ts +13 -10
  20. package/src/app/components/conversation-detail/header-conversation-detail/header-conversation-detail.component.html +3 -2
  21. package/src/app/components/conversation-detail/header-conversation-detail/header-conversation-detail.component.scss +2 -0
  22. package/src/app/components/conversation-detail/header-conversation-detail/header-conversation-detail.component.ts +142 -71
  23. package/src/app/components/conversation-detail/message-text-area/message-text-area.component.html +57 -20
  24. package/src/app/components/conversation-detail/message-text-area/message-text-area.component.scss +32 -9
  25. package/src/app/components/conversation-detail/message-text-area/message-text-area.component.ts +98 -24
  26. package/src/app/components/ddp-header/ddp-header.component.html +9 -2
  27. package/src/app/components/ddp-header/ddp-header.component.ts +93 -18
  28. package/src/app/components/project-item/project-item.component.html +1 -1
  29. package/src/app/components/project-item/project-item.component.scss +1 -1
  30. package/src/app/components/project-item/project-item.component.ts +3 -3
  31. package/src/app/components/sidebar/sidebar.component.html +65 -52
  32. package/src/app/components/sidebar/sidebar.component.scss +23 -0
  33. package/src/app/components/sidebar/sidebar.component.ts +74 -26
  34. package/src/app/components/sidebar-user-details/sidebar-user-details.component.html +20 -9
  35. package/src/app/components/sidebar-user-details/sidebar-user-details.component.scss +20 -3
  36. package/src/app/components/sidebar-user-details/sidebar-user-details.component.ts +24 -8
  37. package/src/app/pages/conversation-detail/conversation-detail.module.ts +5 -1
  38. package/src/app/pages/conversation-detail/conversation-detail.page.html +19 -10
  39. package/src/app/pages/conversation-detail/conversation-detail.page.scss +28 -0
  40. package/src/app/pages/conversation-detail/conversation-detail.page.ts +229 -389
  41. package/src/app/pages/conversations-list/conversations-list.page.ts +646 -454
  42. package/src/app/pages/create-canned-response/create-canned-response-routing.module.ts +17 -0
  43. package/src/app/pages/create-canned-response/create-canned-response.module.ts +30 -0
  44. package/src/app/pages/create-canned-response/create-canned-response.page.html +150 -0
  45. package/src/app/pages/create-canned-response/create-canned-response.page.scss +55 -0
  46. package/src/app/pages/create-canned-response/create-canned-response.page.spec.ts +24 -0
  47. package/src/app/pages/create-canned-response/create-canned-response.page.ts +319 -0
  48. package/src/app/pages/create-requester/create-requester-routing.module.ts +17 -0
  49. package/src/app/pages/create-requester/create-requester.module.ts +28 -0
  50. package/src/app/pages/create-requester/create-requester.page.html +67 -0
  51. package/src/app/pages/create-requester/create-requester.page.scss +30 -0
  52. package/src/app/pages/create-requester/create-requester.page.spec.ts +24 -0
  53. package/src/app/pages/create-requester/create-requester.page.ts +138 -0
  54. package/src/app/pages/create-ticket/create-ticket-routing.module.ts +17 -0
  55. package/src/app/pages/create-ticket/create-ticket.module.ts +28 -0
  56. package/src/app/pages/create-ticket/create-ticket.page.html +171 -0
  57. package/src/app/pages/create-ticket/create-ticket.page.scss +52 -0
  58. package/src/app/pages/create-ticket/create-ticket.page.spec.ts +24 -0
  59. package/src/app/pages/create-ticket/create-ticket.page.ts +432 -0
  60. package/src/app/pages/loader-preview/loader-preview.page.ts +2 -11
  61. package/src/app/pages/profile-info/profile-info.page.html +2 -2
  62. package/src/app/pages/profile-info/profile-info.page.scss +12 -1
  63. package/src/app/services/tiledesk/tiledesk.service.ts +190 -0
  64. package/src/app/shared/shared.module.ts +1 -1
  65. package/src/assets/i18n/de.json +37 -1
  66. package/src/assets/i18n/en.json +37 -1
  67. package/src/assets/i18n/es.json +38 -2
  68. package/src/assets/i18n/fr.json +38 -2
  69. package/src/assets/i18n/it.json +38 -2
  70. package/src/assets/i18n/pt.json +38 -2
  71. package/src/assets/i18n/ru.json +38 -2
  72. package/src/assets/i18n/sr.json +38 -2
  73. package/src/assets/i18n/tr.json +37 -1
  74. package/src/assets/images/default-avatar-x-select.png +0 -0
  75. package/src/assets/images/priority_icons/high.svg +3 -0
  76. package/src/assets/images/priority_icons/high_v2.svg +14 -0
  77. package/src/assets/images/priority_icons/low.svg +10 -0
  78. package/src/assets/images/priority_icons/low_v2.svg +14 -0
  79. package/src/assets/images/priority_icons/medium.svg +16 -0
  80. package/src/assets/images/priority_icons/medium_v2.svg +11 -0
  81. package/src/assets/images/priority_icons/urgent.svg +4 -0
  82. package/src/assets/images/priority_icons/urgent_v2.svg +16 -0
  83. package/src/chat-config-mqtt.json +25 -16
  84. package/src/chat-config-template.json +5 -4
  85. package/src/chat-config.json +1 -0
  86. package/src/chat21-core/providers/firebase/firebase-conversation-handler.ts +8 -3
  87. package/src/chat21-core/utils/constants.ts +2 -0
  88. package/src/chat21-core/utils/utils-message.ts +19 -0
  89. package/src/global.scss +33 -9
@@ -0,0 +1,67 @@
1
+ <ion-header>
2
+ <ion-toolbar>
3
+ <ion-title> {{'CreateNewRequester' | translate}} </ion-title>
4
+ <ion-buttons slot="end">
5
+ <ion-button ion-button fill="clear" (click)="closeModalAddNewRequester()">
6
+ <ion-icon slot="icon-only" name="close"></ion-icon>
7
+ </ion-button>
8
+ </ion-buttons>
9
+ </ion-toolbar>
10
+ </ion-header>
11
+
12
+ <ion-content class="ion-padding">
13
+
14
+
15
+
16
+ <form [formGroup]="validations_form" (ngSubmit)="onSubmit(validations_form.value)">
17
+ <ion-grid>
18
+ <ion-row>
19
+ <ion-col size="12">
20
+
21
+ <ion-item>
22
+ <ion-label position="floating" color="primary">{{'Name' | translate}} *</ion-label>
23
+ <ion-input type="text" formControlName="name"></ion-input>
24
+ </ion-item>
25
+ <div class="validation-errors">
26
+ <ng-container *ngFor="let validation of validation_messages.name">
27
+ <div class="error-message"
28
+ *ngIf="validations_form.get('name').hasError(validation.type) && (validations_form.get('name').dirty || validations_form.get('name').touched)">
29
+ <ion-icon name="information-circle-outline"></ion-icon>
30
+ <span class="validation-message"> {{ validation.message }} </span>
31
+ </div>
32
+ </ng-container>
33
+ </div>
34
+ </ion-col>
35
+
36
+
37
+ <ion-col size="12">
38
+ <ion-item>
39
+ <ion-label position="floating" color="primary">Email</ion-label>
40
+ <ion-input type="text" formControlName="email"></ion-input>
41
+ </ion-item>
42
+ <div class="validation-errors">
43
+ <ng-container *ngFor="let validation of validation_messages.email">
44
+ <div class="error-message"
45
+ *ngIf="validations_form.get('email').hasError(validation.type) && (validations_form.get('email').dirty || validations_form.get('email').touched)">
46
+ <ion-icon name="information-circle-outline"></ion-icon>
47
+ <span class="validation-message"> {{ validation.message }} </span>
48
+
49
+ </div>
50
+ </ng-container>
51
+ </div>
52
+ </ion-col>
53
+ <!-- expand="block" -->
54
+ <ion-col size="12" style="text-align: center;">
55
+ <ion-button color="primary" class="submit-btn" type="submit" [disabled]="!validations_form.valid" style="min-width:253px">
56
+ <ion-icon *ngIf="showSpinnerCreateRequester === false" style="font-size: 1.9em;" slot="start" name="add-circle-outline"></ion-icon>
57
+ <ion-spinner *ngIf="showSpinnerCreateRequester === true" style="color: #fff; margin: 0px 0.3em 0px -0.3em;" name="bubbles" duration="2" ></ion-spinner>
58
+ {{'CreateNewRequester' | translate}}</ion-button>
59
+ </ion-col>
60
+ </ion-row>
61
+ </ion-grid>
62
+ </form>
63
+
64
+
65
+
66
+
67
+ </ion-content>
@@ -0,0 +1,30 @@
1
+ ion-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
+ }
30
+ }
@@ -0,0 +1,24 @@
1
+ import { async, ComponentFixture, TestBed } from '@angular/core/testing';
2
+ import { IonicModule } from '@ionic/angular';
3
+
4
+ import { CreateRequesterPage } from './create-requester.page';
5
+
6
+ describe('CreateRequesterPage', () => {
7
+ let component: CreateRequesterPage;
8
+ let fixture: ComponentFixture<CreateRequesterPage>;
9
+
10
+ beforeEach(async(() => {
11
+ TestBed.configureTestingModule({
12
+ declarations: [ CreateRequesterPage ],
13
+ imports: [IonicModule.forRoot()]
14
+ }).compileComponents();
15
+
16
+ fixture = TestBed.createComponent(CreateRequesterPage);
17
+ component = fixture.componentInstance;
18
+ fixture.detectChanges();
19
+ }));
20
+
21
+ it('should create', () => {
22
+ expect(component).toBeTruthy();
23
+ });
24
+ });
@@ -0,0 +1,138 @@
1
+ import { Component, Input, OnInit } from '@angular/core';
2
+ import { Validators, FormBuilder, FormGroup, FormControl} from '@angular/forms';
3
+ import { ModalController } from '@ionic/angular'
4
+ import { TranslateService } from '@ngx-translate/core';
5
+ import { TiledeskService } from 'src/app/services/tiledesk/tiledesk.service';
6
+ import { TiledeskAuthService } from 'src/chat21-core/providers/tiledesk/tiledesk-auth.service';
7
+ import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service';
8
+ import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance';
9
+ @Component({
10
+ selector: 'app-create-requester',
11
+ templateUrl: './create-requester.page.html',
12
+ styleUrls: ['./create-requester.page.scss'],
13
+ })
14
+ export class CreateRequesterPage implements OnInit {
15
+ public new_user_name: string;
16
+ public new_user_email : string;
17
+
18
+ validations_form: FormGroup;
19
+ @Input() projectUserAndLeadsArray: any
20
+
21
+ prjctID: string;
22
+ tiledeskToken: string;
23
+ showSpinnerCreateRequester: boolean = false;
24
+ requester_id: string;
25
+ logger: LoggerService = LoggerInstance.getInstance();
26
+
27
+ constructor(
28
+ public modalController: ModalController,
29
+ private formBuilder: FormBuilder,
30
+ public tiledeskService: TiledeskService,
31
+ public tiledeskAuthService: TiledeskAuthService,
32
+ private translate: TranslateService,
33
+ ) { }
34
+
35
+ ngOnInit() {
36
+ this.logger.log('[CREATE-REQUESTER] projectUserAndLeadsArray ', this.projectUserAndLeadsArray)
37
+ const stored_project = localStorage.getItem('last_project')
38
+ const storedPrjctObjct = JSON.parse(stored_project)
39
+ this.logger.log('[CREATE-REQUESTER] storedPrjctObjct ', storedPrjctObjct)
40
+ if (storedPrjctObjct) {
41
+ this.prjctID = storedPrjctObjct.id_project.id
42
+ this.logger.log('[CREATE-REQUESTER] this.prjctID ', this.prjctID)
43
+ }
44
+ this.tiledeskToken = this.tiledeskAuthService.getTiledeskToken()
45
+ this.logger.log('[CREATE-REQUESTER] tiledeskToken ', this.tiledeskToken)
46
+
47
+ this.buildForm()
48
+
49
+ }
50
+
51
+ buildForm() {
52
+ this.validations_form = this.formBuilder.group({
53
+
54
+ name: new FormControl('', Validators.required),
55
+
56
+ email: new FormControl('', Validators.compose([
57
+ Validators.pattern('^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+.[a-zA-Z0-9-.]+$')
58
+ ])),
59
+
60
+ });
61
+ }
62
+
63
+ validation_messages = {
64
+ 'name': [
65
+ { type: 'required', message: this.translate.instant('NameIsRequired') }
66
+ ],
67
+
68
+ 'email': [
69
+ { type: 'pattern', message: this.translate.instant('EnterValidEmail') }
70
+ ],
71
+ };
72
+
73
+ onSubmit(values){
74
+ this.logger.log('[CREATE-REQUESTER] ON SUBMIT VALUSES' , values);
75
+ this.new_user_name = values.name
76
+ this.new_user_email = values.email
77
+ this.createProjectUserAndThenNewLead(this.new_user_name, this.new_user_email)
78
+ }
79
+
80
+ createProjectUserAndThenNewLead(new_user_name, new_user_email) {
81
+ this.showSpinnerCreateRequester = true;
82
+ this.logger.log('[CREATE-REQUESTER] - CREATE-NEW-USER name ', new_user_name);
83
+ this.logger.log('[CREATE-REQUESTER] - CREATE-NEW-USER email ', new_user_email);
84
+
85
+
86
+ this.tiledeskService.createNewProjectUserToGetNewLeadID(this.prjctID, this.tiledeskToken).subscribe(res => {
87
+ this.logger.log('[CREATE-REQUESTER] - CREATE-NEW-USER - CREATE-PROJECT-USER ', res);
88
+ this.logger.log('[CREATE-REQUESTER] - CREATE-NEW-USER - CREATE-PROJECT-USER UUID ', res.uuid_user);
89
+ if (res) {
90
+ if (res.uuid_user) {
91
+ let new_lead_id = res.uuid_user
92
+ this.createNewContact(new_lead_id, new_user_name, new_user_email, this.prjctID, this.tiledeskToken)
93
+ }
94
+ }
95
+ }, error => {
96
+ this.showSpinnerCreateRequester = false;
97
+ this.logger.error('[CREATE-REQUESTER] - CREATE-NEW-USER - CREATE-PROJECT-USER - ERROR: ', error);
98
+ }, () => {
99
+
100
+ this.logger.log('[CREATE-REQUESTER] - CREATE-NEW-USER - CREATE-PROJECT-USER - COMPLETE');
101
+ });
102
+ }
103
+
104
+
105
+ createNewContact(lead_id: string, lead_name: string, lead_email: string, projecId: string, tiledeskToken: string) {
106
+ this.tiledeskService.createNewLead(lead_id, lead_name, lead_email, projecId, tiledeskToken ).subscribe(lead => {
107
+ this.logger.log('[CREATE-REQUESTER] - CREATE-NEW-USER - CREATE-NEW-LEAD - RES ', lead);
108
+ this.projectUserAndLeadsArray.push({ id: lead.lead_id, name: lead.fullname, role: 'lead', email: lead_email, requestertype: 'lead', requester_id: lead._id});
109
+ this.requester_id = lead._id
110
+ // this.projectUserAndLeadsArray.push({ id: lead.lead_id, name: lead.fullname + ' (lead)' });
111
+ // this.projectUserAndLeadsArray = this.projectUserAndLeadsArray.slice(0);
112
+ this.logger.log('[CREATE-REQUESTER]- CREATE-NEW-USER - projectUserAndLeadsArray AFTERT NEW LEAD CREATION : ', this.projectUserAndLeadsArray);
113
+ }, error => {
114
+ this.showSpinnerCreateRequester = false;
115
+ this.logger.error('[CREATE-REQUESTER]- CREATE-NEW-USER - CREATE-NEW-LEAD - ERROR: ', error);
116
+ }, () => {
117
+
118
+ this.closeModalAddNewRequester( this.projectUserAndLeadsArray, lead_id, this.requester_id)
119
+ // -------------------------------------------------
120
+ // When is cmpleted the creation of the new reqester
121
+ // -------------------------------------------------
122
+ // this.displayCreateNewUserModal = 'none'
123
+ // this.displayInternalRequestModal = 'block'
124
+
125
+ // Auto select the new lead crerated in the select Requester
126
+ // this.selectedRequester = lead_id
127
+ this.logger.log('[WS-REQUESTS-LIST] - CREATE-NEW-USER - CREATE-NEW-LEAD * COMPLETE *');
128
+ });
129
+ }
130
+
131
+ async closeModalAddNewRequester( projectUserAndLeadsArray?: any, lead_id?: string, requester_id?: string) {
132
+ this.logger.log('[CREATE-REQUESTER]', this.modalController)
133
+ this.logger.log( '[CREATE-REQUESTER] .getTop()',this.modalController.getTop())
134
+ await this.modalController.getTop()
135
+ this.modalController.dismiss({updatedProjectUserAndLeadsArray: projectUserAndLeadsArray, selectedRequester: lead_id, requester_type: 'lead', requester_id: requester_id })
136
+ }
137
+
138
+ }
@@ -0,0 +1,17 @@
1
+ import { NgModule } from '@angular/core';
2
+ import { Routes, RouterModule } from '@angular/router';
3
+
4
+ import { CreateTicketPage } from './create-ticket.page';
5
+
6
+ const routes: Routes = [
7
+ {
8
+ path: '',
9
+ component: CreateTicketPage
10
+ }
11
+ ];
12
+
13
+ @NgModule({
14
+ imports: [RouterModule.forChild(routes)],
15
+ exports: [RouterModule],
16
+ })
17
+ export class CreateTicketPageRoutingModule {}
@@ -0,0 +1,28 @@
1
+ import { NgModule } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+ import { FormsModule } from '@angular/forms';
4
+ import { IonicModule } from '@ionic/angular';
5
+ import { CreateTicketPageRoutingModule } from './create-ticket-routing.module';
6
+ import { CreateTicketPage } from './create-ticket.page';
7
+ import { NgSelectModule } from '@ng-select/ng-select';
8
+ import { TranslateLoader, TranslateModule} from '@ngx-translate/core';
9
+ import { createTranslateLoader } from '../../../chat21-core/utils/utils';
10
+ import { HttpClient } from '@angular/common/http';
11
+ @NgModule({
12
+ imports: [
13
+ CommonModule,
14
+ FormsModule,
15
+ IonicModule,
16
+ CreateTicketPageRoutingModule,
17
+ NgSelectModule,
18
+ TranslateModule.forChild({
19
+ loader: {
20
+ provide: TranslateLoader,
21
+ useFactory: (createTranslateLoader),
22
+ deps: [HttpClient]
23
+ }
24
+ })
25
+ ],
26
+ declarations: [CreateTicketPage]
27
+ })
28
+ export class CreateTicketPageModule {}
@@ -0,0 +1,171 @@
1
+ <ion-header>
2
+ <ion-toolbar>
3
+ <ion-title>{{'CreateTicket' | translate}}</ion-title>
4
+ <ion-buttons slot="end">
5
+ <ion-button ion-button fill="clear" (click)="closeModalCreateTicketModal()">
6
+ <ion-icon slot="icon-only" name="close"></ion-icon>
7
+ </ion-button>
8
+ </ion-buttons>
9
+ </ion-toolbar>
10
+ </ion-header>
11
+
12
+ <ion-content >
13
+
14
+ <ion-grid class="ion-grid-custom-padding" [ngClass]="{'center-content': ticketCreationCompleted === true }">
15
+ <ion-row *ngIf="ticketCreationCompleted === false">
16
+ <ion-col size="12">
17
+ <!-- // with custom search {{'SelectRequester' | translate}}-->
18
+ <!-- {{ projectUserAndLeadsArray | json}} -->
19
+ <ion-label class="custom-create-ticket-label">{{'Requester' | translate }}</ion-label>
20
+ <ion-label [ngClass]="{'open-requester-details-disable': !selectedRequester}" class="custom-create-ticket-label-to-left"
21
+ (click)="openRequesterDetails()">
22
+ {{'ViewRequesterDetails' | translate }}
23
+ <span class="material-icons" style="color: #0f62ff; vertical-align: middle;font-size: 16px;">
24
+ open_in_new
25
+ </span>
26
+ </ion-label>
27
+ <ng-select class="create-ticket-custom-select" name="users_and_leads" [items]="projectUserAndLeadsArray"
28
+ bindLabel="name" bindValue="id" [(ngModel)]="selectedRequester" [virtualScroll]="true"
29
+ [searchFn]="customSearchFn" (change)="selectRequester($event)" placeholder="{{'SelectRequester' | translate}}"
30
+ [loading]=loadingRequesters loadingText='Loading...'>
31
+
32
+ <ng-template ng-label-tmp let-item="item">
33
+ <!-- ---------------------------------------- -->
34
+ <!-- Usecase Firebase -->
35
+ <!-- ---------------------------------------- -->
36
+ <img *ngIf="item.requestertype === 'agent' && UPLOAD_ENGINE_IS_FIREBASE" height="24" width="24"
37
+ style="border-radius:50%; object-fit: cover; vertical-align: middle;"
38
+ src="https://firebasestorage.googleapis.com/v0/b/{{storageBucket}}/o/profiles%2F{{item.id}}%2Fphoto.jpg?alt=media"
39
+ alt="" onerror="this.src='assets/images/default-avatar-x-select.png'">
40
+
41
+ <!-- ---------------------------------------- -->
42
+ <!-- Usecase Native -->
43
+ <!-- ---------------------------------------- -->
44
+ <img *ngIf="item.requestertype === 'agent' && !UPLOAD_ENGINE_IS_FIREBASE" height="24" width="24"
45
+ style="border-radius:50%;object-fit: cover;vertical-align: middle;"
46
+ src="{{baseUrl}}images?path=uploads%2Fusers%2F{{item.id}}%2Fimages%2Fthumbnails_200_200-photo.jpg" alt=""
47
+ onerror="this.src='assets/images/default-avatar-x-select.png'">
48
+
49
+ <img *ngIf="item.requestertype === 'lead'" height="24" width="24"
50
+ style="border-radius:50%;object-fit: cover;vertical-align: middle;"
51
+ src="assets/images/default-avatar-x-select.png" alt="">
52
+ <span style="font-weight: 400;">
53
+ {{ item.name }}
54
+ </span>
55
+ <span class="requester-role-or-type">
56
+ ({{item.role}})
57
+ </span>
58
+
59
+ </ng-template>
60
+ <ng-template ng-option-tmp let-item="item" let-search="searchTerm" let-index="index">
61
+ <!-- ---------------------------------------- -->
62
+ <!-- Usecase Firebase -->
63
+ <!-- ---------------------------------------- -->
64
+ <img *ngIf="item.requestertype === 'agent' && UPLOAD_ENGINE_IS_FIREBASE" height="24" width="24"
65
+ style="border-radius:50%;object-fit: cover;vertical-align: middle;"
66
+ src="https://firebasestorage.googleapis.com/v0/b/{{storageBucket}}/o/profiles%2F{{item.id}}%2Fphoto.jpg?alt=media"
67
+ alt="" onerror="this.src='assets/images/default-avatar-x-select.png'">
68
+
69
+ <!-- ---------------------------------------- -->
70
+ <!-- Usecase Native -->
71
+ <!-- ---------------------------------------- -->
72
+ <img *ngIf="item.requestertype === 'agent' && !UPLOAD_ENGINE_IS_FIREBASE" height="24" width="24"
73
+ style="border-radius:50%;object-fit: cover;vertical-align: middle;"
74
+ src="{{baseUrl}}images?path=uploads%2Fusers%2F{{item.id}}%2Fimages%2Fthumbnails_200_200-photo.jpg" alt=""
75
+ onerror="this.src='assets/images/default-avatar-x-select.png'">
76
+
77
+ <img *ngIf="item.requestertype === 'lead'" height="24" width="24"
78
+ style="border-radius:50%; object-fit: cover;vertical-align: middle;"
79
+ src="assets/images/default-avatar-x-select.png" alt="">
80
+ <span style="font-weight: 400;">
81
+ {{ item.name }}
82
+ </span>
83
+ <span class="requester-role-or-type">
84
+ ({{item.role}})
85
+ </span>
86
+ <br />
87
+ <small style="font-weight:400;font-size: 13px; margin-left: 28px; position: relative;top: -3px;">
88
+ {{ item.email }}
89
+ </small>
90
+ </ng-template>
91
+
92
+ <ng-template ng-footer-tmp>
93
+ <div style="cursor:pointer" (click)="presentModalAddNewRequester()">
94
+ <span class="material-icons" style="vertical-align: middle; color:#0f62ff"> add </span>
95
+ <span style="color:#0f62ff">
96
+ {{'AddRequester' | translate}}
97
+ </span>
98
+ </div>
99
+ </ng-template>
100
+
101
+ </ng-select>
102
+ </ion-col>
103
+
104
+ <ion-col size="12">
105
+ <ion-label class="custom-create-ticket-label" position="stacked">{{ 'Subject' | translate }} *</ion-label>
106
+ <ion-input [(ngModel)]="ticket_subject" type="text" class="custom-ion-input"></ion-input>
107
+ </ion-col>
108
+
109
+ <ion-col size="12">
110
+ <ion-label class="custom-create-ticket-label">{{ 'SelectAssignee' | translate }}</ion-label>
111
+ <ng-select class="create-ticket-custom-select" name="assignee" [(ngModel)]="assignee_id" [searchable]="true" [clearable]="false"
112
+ placeholder="{{ 'SelectAssignee' | translate }}" (change)="selectedAssignee()" [loading]=loadingAssignee
113
+ loadingText='Loading...'>
114
+ <ng-option *ngFor="let assignee of projectUserBotsAndDeptsArray" [value]="assignee.id">
115
+ {{assignee.name}}
116
+ </ng-option>
117
+ </ng-select>
118
+ </ion-col>
119
+
120
+ <ion-col size="12">
121
+ <ion-label class="custom-create-ticket-label">{{ 'Priority' | translate }}</ion-label>
122
+ <ng-select class="create-ticket-custom-select" [items]="priority" bindLabel="name" bindValue="name" [clearable]="false" [hideSelected]="true"
123
+ [(ngModel)]="selectedPriority" (change)="onChangeSelectedPriority(selectedPriority)">
124
+ <ng-template ng-label-tmp let-item="item">
125
+ <img style="width: 15px;height: 15px; vertical-align: middle;" height="15" width="15" [src]="item.avatar" />
126
+ {{item.name | translate}}
127
+ </ng-template>
128
+ <ng-template ng-option-tmp let-item="item" let-index="index">
129
+ <img style="width: 15px;height: 15px;vertical-align: middle;" height="15" width="15" [src]="item.avatar" />
130
+ {{item.name | translate }}
131
+ </ng-template>
132
+ </ng-select>
133
+
134
+ </ion-col>
135
+
136
+ <ion-col size="12">
137
+ <ion-label class="custom-create-ticket-label">{{ 'Message' | translate }} *</ion-label>
138
+ <ion-textarea [(ngModel)]="ticket_message" type="text" class="custom-ion-textarea" rows="2" placeholder=""></ion-textarea>
139
+ </ion-col>
140
+ <!-- expand="block" -->
141
+ <ion-col size="12" style="text-align: center;">
142
+
143
+ <!-- <ion-icon *ngIf="showSpinnerCreateTicket === false" style="font-size: 1.9em;" slot="start" name="checkmark-outline"></ion-icon> -->
144
+ <ion-button style="min-width: 153px;" color="primary" class="submit-btn" type="submit" (click)="createTicket()" [disabled]="ticket_subject === undefined || ticket_message === undefined || ticket_subject?.length === 0 || ticket_message?.length === 0">
145
+ <ion-icon *ngIf="showSpinnerCreateTicket === false" style="font-size: 1.9em;" slot="start" name="add-circle-outline"></ion-icon>
146
+ <ion-spinner *ngIf="showSpinnerCreateTicket === true" style="color: #fff; margin: 0px 0.3em 0px -0.3em;" name="bubbles" duration="2" ></ion-spinner>
147
+ {{'CreateTicket' | translate}}
148
+ </ion-button>
149
+ </ion-col>
150
+
151
+ </ion-row>
152
+ <!-- class="ion-align-items-center" -->
153
+ <ion-row style="text-align: center;" *ngIf="ticketCreationCompleted === true">
154
+ <ion-col size="12">
155
+ <ion-icon style="font-size: 3em;" color="success" name="checkmark-outline"></ion-icon>
156
+ </ion-col>
157
+ <ion-col size="12">
158
+ <label> {{'TicketSuccessfullyCreated' | translate }}</label>
159
+ </ion-col>
160
+ <ion-col size="12" class="ion-padding-vertical">
161
+ <ion-button color="success" class="submit-btn" type="submit" (click)="closeModalCreateTicketModal()">
162
+ {{'Continue' | translate }}
163
+ </ion-button>
164
+ </ion-col>
165
+
166
+ </ion-row>
167
+
168
+ </ion-grid>
169
+
170
+ </ion-content>
171
+
@@ -0,0 +1,52 @@
1
+ .requester-role-or-type {
2
+ font-size: 12px;
3
+ font-weight: 400;
4
+ color: rgba(0, 0, 0, 0.54);
5
+ }
6
+
7
+ .custom-ion-input {
8
+ border-radius: 4px;
9
+ border: 1px solid #ccc;
10
+ height: 36px;
11
+ color: #333;
12
+ background-color: #fff;
13
+ margin-top: 5px;
14
+ }
15
+
16
+ .custom-ion-textarea {
17
+ border-radius: 4px;
18
+ border: 1px solid #ccc;
19
+ color: #333;
20
+ background-color: #fff;
21
+ margin-top: 5px !important;
22
+ }
23
+
24
+ .custom-create-ticket-label {
25
+ font-size: 14px;
26
+ color: #7695a5;
27
+ font-weight: 500;
28
+ }
29
+
30
+ .custom-create-ticket-label-to-left {
31
+ font-size: 14px;
32
+ color: #0f62ff;
33
+ font-weight: 500;
34
+ float: right;
35
+ cursor: pointer;
36
+ }
37
+
38
+ .open-requester-details-disable {
39
+ // cursor: not-allowed;
40
+ // opacity: 0.5;
41
+ display: none;
42
+ }
43
+ .ion-grid-custom-padding {
44
+ padding: 5px 25px;
45
+ height: 100%;
46
+ }
47
+
48
+ .center-content {
49
+ display: flex;
50
+ align-items: center;
51
+ justify-content: center;
52
+ }
@@ -0,0 +1,24 @@
1
+ import { async, ComponentFixture, TestBed } from '@angular/core/testing';
2
+ import { IonicModule } from '@ionic/angular';
3
+
4
+ import { CreateTicketPage } from './create-ticket.page';
5
+
6
+ describe('CreateTicketPage', () => {
7
+ let component: CreateTicketPage;
8
+ let fixture: ComponentFixture<CreateTicketPage>;
9
+
10
+ beforeEach(async(() => {
11
+ TestBed.configureTestingModule({
12
+ declarations: [ CreateTicketPage ],
13
+ imports: [IonicModule.forRoot()]
14
+ }).compileComponents();
15
+
16
+ fixture = TestBed.createComponent(CreateTicketPage);
17
+ component = fixture.componentInstance;
18
+ fixture.detectChanges();
19
+ }));
20
+
21
+ it('should create', () => {
22
+ expect(component).toBeTruthy();
23
+ });
24
+ });