@chat21/chat21-ionic 3.4.26-rc2 → 3.4.27-rc1
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 +6 -0
- package/package.json +1 -1
- package/src/app/app.component.ts +3 -0
- package/src/app/components/canned-response/canned-response.component.html +26 -23
- package/src/app/components/canned-response/canned-response.component.ts +3 -1
- package/src/app/components/conversation-detail/message-text-area/message-text-area.component.html +1 -1
- package/src/app/components/conversation-detail/message-text-area/message-text-area.component.ts +3 -0
- package/src/app/modals/create-ticket/create-ticket.page.ts +4 -2
- package/src/app/pages/conversation-detail/conversation-detail.page.html +4 -2
- package/src/app/pages/conversation-detail/conversation-detail.page.ts +45 -3
- package/src/app/services/project_users/project-users.service.spec.ts +16 -0
- package/src/app/services/project_users/project-users.service.ts +63 -0
- package/src/app/services/tiledesk/tiledesk.service.ts +0 -16
- package/src/app/utils/permissions.constants.ts +135 -0
- package/src/app/utils/project-utils.ts +2 -2
- package/src/app/utils/utils.ts +18 -1
- package/src/chat21-core/models/projectUsers.ts +19 -0
- package/src/chat21-core/providers/firebase/firebase-conversation-handler.ts +1 -1
- package/src/chat21-core/providers/mqtt/mqtt-conversation-handler.ts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,12 @@
|
|
|
8
8
|
### **Copyrigth**:
|
|
9
9
|
*Tiledesk SRL*
|
|
10
10
|
|
|
11
|
+
# 3.4.27-rc1
|
|
12
|
+
- **added**: managed canned responses with roles
|
|
13
|
+
- **changed**: name in info mesage
|
|
14
|
+
|
|
15
|
+
# 3.4.26 in PROD
|
|
16
|
+
|
|
11
17
|
# 3.4.26-rc2
|
|
12
18
|
- **removed**: archive button on list conversations if is not on mobile device
|
|
13
19
|
|
package/package.json
CHANGED
package/src/app/app.component.ts
CHANGED
|
@@ -44,6 +44,7 @@ import { conversationToMessage } from 'src/chat21-core/utils/utils-message';
|
|
|
44
44
|
import { ProjectService } from './services/projects/project.service';
|
|
45
45
|
import { ContactsService } from './services/contacts/contacts.service';
|
|
46
46
|
import { TiledeskService } from './services/tiledesk/tiledesk.service';
|
|
47
|
+
import { ProjectUsersService } from './services/project_users/project-users.service';
|
|
47
48
|
|
|
48
49
|
@Component({
|
|
49
50
|
selector: 'app-root',
|
|
@@ -142,6 +143,7 @@ export class AppComponent implements OnInit {
|
|
|
142
143
|
/**TILEDESK SERVICES */
|
|
143
144
|
private tiledeskService: TiledeskService,
|
|
144
145
|
private projectService: ProjectService,
|
|
146
|
+
private projectUsersService: ProjectUsersService,
|
|
145
147
|
private contactsService: ContactsService
|
|
146
148
|
) {
|
|
147
149
|
|
|
@@ -1176,6 +1178,7 @@ export class AppComponent implements OnInit {
|
|
|
1176
1178
|
|
|
1177
1179
|
this.tiledeskService.initialize(serverBaseURL)
|
|
1178
1180
|
this.projectService.initialize(serverBaseURL)
|
|
1181
|
+
this.projectUsersService.initialize(serverBaseURL)
|
|
1179
1182
|
this.contactsService.initialize(serverBaseURL)
|
|
1180
1183
|
// this.chatManager.startApp();
|
|
1181
1184
|
|
|
@@ -1,20 +1,30 @@
|
|
|
1
1
|
<div>
|
|
2
|
-
<div class="canned-list" *ngIf="
|
|
3
|
-
<
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
<
|
|
9
|
-
|
|
2
|
+
<div class="canned-list" *ngIf="!showLoading">
|
|
3
|
+
<span *ngIf="tagsCannedFilter.length > 0">
|
|
4
|
+
<ion-item button="true" [ngClass]="{'is_active_item': i == arrowkeyLocation}" lines="none"
|
|
5
|
+
class="canned-item no-ripple border" id="{{'canned-item_'+ i }}"
|
|
6
|
+
*ngFor="let canned of tagsCannedFilter; let i = index;"
|
|
7
|
+
(click)="onClickCannedFN(canned, $event)">
|
|
8
|
+
<div class="cannedContent">
|
|
9
|
+
<ion-input [class.readonly]="canned?.disabled" [readonly]="canned?.disabled" type="text" [(ngModel)]="canned.title" class="title" id="{{'titleCanned_'+canned._id}}" #title></ion-input>
|
|
10
|
+
<ion-input [class.readonly]="canned?.disabled" [readonly]="canned?.disabled" type="text" [(ngModel)]="canned.text" class="text truncate"></ion-input>
|
|
11
|
+
</div>
|
|
12
|
+
<!-- <ion-icon class="canned-item-icon" name="pin" src="assets/images/pin.svg" slot=end *ngIf="canned.pinned" (click)="onPinCanned(canned, $event)"></ion-icon>
|
|
13
|
+
<ion-icon class="canned-item-icon" name="pin" src="assets/images/pinned.svg" slot=end (click)="onUnPinCanned(canned, $event)"></ion-icon> -->
|
|
14
|
+
<ion-icon class="canned-item-icon" name="checkmark-sharp" slot=end *ngIf="(canned.createdBy === loggedUser.uid && !canned.disabled) && roles[PERMISSIONS.CANNED_RESPONSES_UPDATE]" (click)="onConfirmEditCanned(canned, $event)"></ion-icon>
|
|
15
|
+
<ion-icon class="canned-item-icon" name="pencil-sharp" slot=end *ngIf="(canned.createdBy === loggedUser.uid && canned.disabled) && roles[PERMISSIONS.CANNED_RESPONSES_UPDATE]" (click)="onEditCanned(canned, $event)"></ion-icon>
|
|
16
|
+
<ion-icon class="canned-item-icon" name="trash-bin-outline" slot=end *ngIf="(canned.createdBy === loggedUser.uid) && roles[PERMISSIONS.CANNED_RESPONSES_DELETE]" (click)="onDeleteCanned(canned, $event)"></ion-icon>
|
|
17
|
+
</ion-item>
|
|
18
|
+
</span>
|
|
19
|
+
<div class="no-data" *ngIf="tagsCannedFilter.length === 0">
|
|
20
|
+
<div class="container">
|
|
21
|
+
<ion-item button="false" lines="none" class="canned-item no-ripple border">
|
|
22
|
+
<ion-icon name="cloud-offline" slot="start"></ion-icon>
|
|
23
|
+
<ion-label>{{translationMap.get('THERE_ARE_NO_CANNED_RESPONSES_AVAILABLE')}}</ion-label>
|
|
24
|
+
</ion-item>
|
|
10
25
|
</div>
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
<ion-icon class="canned-item-icon" name="checkmark-sharp" slot=end *ngIf="canned.createdBy === loggedUser.uid && !canned.disabled" (click)="onConfirmEditCanned(canned, $event)"></ion-icon>
|
|
14
|
-
<ion-icon class="canned-item-icon" name="pencil-sharp" slot=end *ngIf="canned.createdBy === loggedUser.uid && canned.disabled" (click)="onEditCanned(canned, $event)"></ion-icon>
|
|
15
|
-
<ion-icon class="canned-item-icon" name="trash-bin-outline" slot=end *ngIf="canned.createdBy === loggedUser.uid" (click)="onDeleteCanned(canned, $event)"></ion-icon>
|
|
16
|
-
</ion-item>
|
|
17
|
-
<ion-item class="canned-item add-canned-response-wpr" button="true" lines="none" (click)="onClickAddCannedResponseFN()">
|
|
26
|
+
</div>
|
|
27
|
+
<ion-item *ngIf="roles[PERMISSIONS.CANNED_RESPONSES_CREATE]" class="canned-item add-canned-response-wpr" button="true" lines="none" (click)="onClickAddCannedResponseFN()">
|
|
18
28
|
<ion-icon class="add-canned-response-icon" name="flash-outline"></ion-icon>
|
|
19
29
|
<span class="add-canned-response-add-icon">+</span>
|
|
20
30
|
<label class="add-canned-response-label" >{{translationMap?.get('AddNewCannedResponse')}}</label>
|
|
@@ -33,12 +43,5 @@
|
|
|
33
43
|
<div class="label">{{translationMap.get('LABEL_LOADING')}}</div>
|
|
34
44
|
</div>
|
|
35
45
|
</div>
|
|
36
|
-
|
|
37
|
-
<div class="container">
|
|
38
|
-
<ion-item button="false" lines="none" class="canned-item no-ripple border">
|
|
39
|
-
<ion-icon name="cloud-offline" slot="start"></ion-icon>
|
|
40
|
-
<ion-label>{{translationMap.get('THERE_ARE_NO_CANNED_RESPONSES_AVAILABLE')}}</ion-label>
|
|
41
|
-
</ion-item>
|
|
42
|
-
</div>
|
|
43
|
-
</div>
|
|
46
|
+
|
|
44
47
|
</div>
|
|
@@ -9,6 +9,7 @@ import { TiledeskAuthService } from 'src/chat21-core/providers/tiledesk/tiledesk
|
|
|
9
9
|
import { compareValues, htmlEntities } from 'src/chat21-core/utils/utils';
|
|
10
10
|
import { getProjectIdSelectedConversation } from 'src/chat21-core/utils/utils-message';
|
|
11
11
|
import { PLAN_NAME } from 'src/chat21-core/utils/constants';
|
|
12
|
+
import { PERMISSIONS } from 'src/app/utils/permissions.constants';
|
|
12
13
|
|
|
13
14
|
@Component({
|
|
14
15
|
selector: 'app-canned-response',
|
|
@@ -21,7 +22,7 @@ export class CannedResponseComponent implements OnInit {
|
|
|
21
22
|
@Input() conversationWith: string;
|
|
22
23
|
@Input() conversationWithFullname: string;
|
|
23
24
|
@Input() currentString: string;
|
|
24
|
-
@Input()
|
|
25
|
+
@Input() roles: Array<string>;
|
|
25
26
|
@Input() stylesMap: Map<string, string>;
|
|
26
27
|
@Input() translationMap: Map<string, string>;
|
|
27
28
|
@Output() onLoadedCannedResponses = new EventEmitter<[any]>();
|
|
@@ -36,6 +37,7 @@ export class CannedResponseComponent implements OnInit {
|
|
|
36
37
|
|
|
37
38
|
public arrowkeyLocation = -1
|
|
38
39
|
|
|
40
|
+
PERMISSIONS = PERMISSIONS
|
|
39
41
|
|
|
40
42
|
private logger: LoggerService = LoggerInstance.getInstance();
|
|
41
43
|
constructor(
|
package/src/app/components/conversation-detail/message-text-area/message-text-area.component.html
CHANGED
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
<div class="buttons-left">
|
|
58
58
|
|
|
59
59
|
<!-- CANNED RESPONSES -->
|
|
60
|
-
<ng-container *ngIf="areVisibleCAR && supportMode">
|
|
60
|
+
<ng-container *ngIf="areVisibleCAR && supportMode && cannedSection">
|
|
61
61
|
<div class="canned-responses-btn-wpr" tooltip="{{translationMap?.get('CANNED_RESPONSES')}}" placement="top">
|
|
62
62
|
<ion-button ion-button fill="clear" class="canned-responses-btn" (click)="openCannedResponses()"
|
|
63
63
|
[disabled]="!conversationWith?.startsWith(CHANNEL_TYPE.SUPPORT_GROUP) || disableTextarea">
|
package/src/app/components/conversation-detail/message-text-area/message-text-area.component.ts
CHANGED
|
@@ -26,6 +26,7 @@ import { CopilotService } from 'src/app/services/copilot/copilot.service';
|
|
|
26
26
|
import { BRAND_BASE_INFO } from 'src/app/utils/utils-resources';
|
|
27
27
|
import { ProjectService } from 'src/app/services/projects/project.service';
|
|
28
28
|
import { Project } from 'src/chat21-core/models/projects';
|
|
29
|
+
import { ProjectUser } from 'src/chat21-core/models/projectUsers';
|
|
29
30
|
|
|
30
31
|
|
|
31
32
|
@Component({
|
|
@@ -49,6 +50,7 @@ export class MessageTextAreaComponent implements OnInit, AfterViewInit, OnChange
|
|
|
49
50
|
@ViewChild('fileInput', { static: false }) fileInput: any;
|
|
50
51
|
|
|
51
52
|
@Input() loggedUser: UserModel;
|
|
53
|
+
@Input() projectUser: ProjectUser;
|
|
52
54
|
@Input() conversationWith: string;
|
|
53
55
|
@Input() channelType: string;
|
|
54
56
|
@Input() channel: string;
|
|
@@ -62,6 +64,7 @@ export class MessageTextAreaComponent implements OnInit, AfterViewInit, OnChange
|
|
|
62
64
|
@Input() offlineMsgEmail: boolean;
|
|
63
65
|
@Input() whatsappTemplatesSection: boolean;
|
|
64
66
|
@Input() isOpenInfoConversation: boolean;
|
|
67
|
+
@Input() cannedSection: boolean;
|
|
65
68
|
@Input() stylesMap: Map<string, string>;
|
|
66
69
|
@Input() translationMap: Map<string, string>;
|
|
67
70
|
@Input() dropEvent: any;
|
|
@@ -9,6 +9,7 @@ import * as uuid from 'uuid';
|
|
|
9
9
|
import { EventsService } from 'src/app/services/events-service'
|
|
10
10
|
import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service';
|
|
11
11
|
import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance';
|
|
12
|
+
import { ProjectUsersService } from 'src/app/services/project_users/project-users.service'
|
|
12
13
|
|
|
13
14
|
@Component({
|
|
14
15
|
selector: 'app-create-ticket',
|
|
@@ -64,6 +65,7 @@ export class CreateTicketPage implements OnInit {
|
|
|
64
65
|
logger: LoggerService = LoggerInstance.getInstance();
|
|
65
66
|
constructor(
|
|
66
67
|
public modalController: ModalController,
|
|
68
|
+
public projectUsersService: ProjectUsersService,
|
|
67
69
|
public tiledeskService: TiledeskService,
|
|
68
70
|
public appConfigProvider: AppConfigProvider,
|
|
69
71
|
public events: EventsService
|
|
@@ -104,7 +106,7 @@ export class CreateTicketPage implements OnInit {
|
|
|
104
106
|
// Create the array of the project-users and contacts displayed in the combo box "Requester"
|
|
105
107
|
// -------------------------------------------------------------------------------------------
|
|
106
108
|
getProjectUsersAndContacts(projctid: string) {
|
|
107
|
-
const projectUsers = this.
|
|
109
|
+
const projectUsers = this.projectUsersService.getProjectUsersByProjectId(projctid)
|
|
108
110
|
const leads = this.tiledeskService.getAllLeadsActiveWithLimit(projctid,10000)
|
|
109
111
|
|
|
110
112
|
zip(projectUsers, leads).subscribe(
|
|
@@ -243,7 +245,7 @@ export class CreateTicketPage implements OnInit {
|
|
|
243
245
|
// -------------------------------------------------------------------------------------------------------------------
|
|
244
246
|
getProjectUserBotsAndDepts(projctid: string) {
|
|
245
247
|
// this.loadingAssignee = true;
|
|
246
|
-
const projectUsers = this.
|
|
248
|
+
const projectUsers = this.projectUsersService.getProjectUsersByProjectId( projctid)
|
|
247
249
|
const bots = this.tiledeskService.getAllBotByProjectId(projctid)
|
|
248
250
|
const depts = this.tiledeskService.getDeptsByProjectId(projctid)
|
|
249
251
|
|
|
@@ -173,7 +173,7 @@
|
|
|
173
173
|
<!-- ----------------------------------------------------------- -->
|
|
174
174
|
<app-canned-response *ngIf="SHOW_CANNED_RESPONSES"
|
|
175
175
|
id="canned"
|
|
176
|
-
[
|
|
176
|
+
[roles]="rolesCanned"
|
|
177
177
|
[conversationWith]="conversationWith"
|
|
178
178
|
[conversationWithFullname]="conversationWithFullname"
|
|
179
179
|
[currentString]="messageStr"
|
|
@@ -201,7 +201,8 @@
|
|
|
201
201
|
<!-- [tagsCannedFilter]="tagsCannedFilter" -->
|
|
202
202
|
<!-- openInfoConversation {{openInfoConversation}} - isMobile {{isMobile}} -->
|
|
203
203
|
<app-message-text-area *ngIf="(openInfoConversation === false && isMobile === true) || (openInfoConversation === true && isMobile === false) || (openInfoConversation === false && isMobile === false)"
|
|
204
|
-
[loggedUser]="loggedUser"
|
|
204
|
+
[loggedUser]="loggedUser"
|
|
205
|
+
[projectUser]="projectUser"
|
|
205
206
|
[conversationWith]="conversationWith"
|
|
206
207
|
[channelType]="channelType"
|
|
207
208
|
[channel]="conversation?.attributes?.request_channel"
|
|
@@ -213,6 +214,7 @@
|
|
|
213
214
|
[fileUploadAccept]="fileUploadAccept"
|
|
214
215
|
[emailSection]="isEmailEnabled"
|
|
215
216
|
[offlineMsgEmail]="offlineMsgEmail"
|
|
217
|
+
[cannedSection]="canShowCanned"
|
|
216
218
|
[whatsappTemplatesSection]="isWhatsappTemplatesEnabled"
|
|
217
219
|
[isOpenInfoConversation]="openInfoConversation"
|
|
218
220
|
[stylesMap]="styleMap"
|
|
@@ -83,7 +83,10 @@ import { WebsocketService } from 'src/app/services/websocket/websocket.service';
|
|
|
83
83
|
import { Project } from 'src/chat21-core/models/projects';
|
|
84
84
|
import { Globals } from 'src/app/utils/globals';
|
|
85
85
|
import { ProjectService } from 'src/app/services/projects/project.service';
|
|
86
|
-
import {
|
|
86
|
+
import { ProjectUsersService } from 'src/app/services/project_users/project-users.service';
|
|
87
|
+
import { ProjectUser } from 'src/chat21-core/models/projectUsers';
|
|
88
|
+
import { getOSCode, hasRole } from 'src/app/utils/utils';
|
|
89
|
+
import { PERMISSIONS } from 'src/app/utils/permissions.constants';
|
|
87
90
|
|
|
88
91
|
@Component({
|
|
89
92
|
selector: 'app-conversation-detail',
|
|
@@ -108,6 +111,7 @@ export class ConversationDetailPage implements OnInit, OnDestroy, AfterViewInit
|
|
|
108
111
|
private subscriptions: Array<any>
|
|
109
112
|
public tenant: string;
|
|
110
113
|
public loggedUser: UserModel
|
|
114
|
+
public projectUser: ProjectUser;
|
|
111
115
|
public conversationWith: string
|
|
112
116
|
public conversationWithFullname: string
|
|
113
117
|
public messages: Array<MessageModel> = []
|
|
@@ -137,6 +141,7 @@ export class ConversationDetailPage implements OnInit, OnDestroy, AfterViewInit
|
|
|
137
141
|
public tagsCannedFilter: Array<any> = [];
|
|
138
142
|
public SHOW_CANNED_RESPONSES: boolean = false
|
|
139
143
|
public canShowCanned: boolean = true
|
|
144
|
+
public rolesCanned: { [key: string]: boolean }
|
|
140
145
|
|
|
141
146
|
public SHOW_COPILOT_SUGGESTIONS: boolean = false;
|
|
142
147
|
|
|
@@ -240,6 +245,7 @@ export class ConversationDetailPage implements OnInit, OnDestroy, AfterViewInit
|
|
|
240
245
|
public toastController: ToastController,
|
|
241
246
|
public tiledeskService: TiledeskService,
|
|
242
247
|
public projectService: ProjectService,
|
|
248
|
+
public projectUsersService: ProjectUsersService,
|
|
243
249
|
private networkService: NetworkService,
|
|
244
250
|
private events: EventsService,
|
|
245
251
|
private webSocketService: WebsocketService,
|
|
@@ -534,7 +540,6 @@ export class ConversationDetailPage implements OnInit, OnDestroy, AfterViewInit
|
|
|
534
540
|
this.logger.log('[CONVS-DETAIL] - GET PROJECTID BY CONV RECIPIENT * COMPLETE *',)
|
|
535
541
|
})
|
|
536
542
|
}else {
|
|
537
|
-
this.canShowCanned = false;
|
|
538
543
|
this.offlineMsgEmail = false;
|
|
539
544
|
}
|
|
540
545
|
|
|
@@ -545,10 +550,13 @@ export class ConversationDetailPage implements OnInit, OnDestroy, AfterViewInit
|
|
|
545
550
|
this.logger.log('[CONVS-DETAIL] - GET PROJECTID BY CONV RECIPIENT RES', project)
|
|
546
551
|
if (project) {
|
|
547
552
|
const projectId = project.id_project
|
|
548
|
-
this.
|
|
553
|
+
this.projectUser = await this.projectUsersService.getProjectUserByProjectId(project._id)
|
|
549
554
|
this.offlineMsgEmail = this.checkOfflineMsgEmailIsEnabled(project)
|
|
550
555
|
this.isCopilotEnabled = this.projectPlanUtils.checkProjectProfileFeature(project, 'copilot');
|
|
551
556
|
this.fileUploadAccept = this.checkAcceptedUploadFile(project)
|
|
557
|
+
this.rolesCanned = this.checkCannedResponsesRoles(project)
|
|
558
|
+
this.canShowCanned = this.checkCannedResponses(project)
|
|
559
|
+
console.log('[CONVS-DETAIL] this.rolesCanned ', this.rolesCanned)
|
|
552
560
|
}
|
|
553
561
|
}, (error) => {
|
|
554
562
|
this.logger.error('[CONVS-DETAIL] - GET PROJECTID BY CONV RECIPIENT - ERROR ', error)
|
|
@@ -586,6 +594,40 @@ export class ConversationDetailPage implements OnInit, OnDestroy, AfterViewInit
|
|
|
586
594
|
return this.appConfigProvider.getConfig().fileUploadAccept
|
|
587
595
|
}
|
|
588
596
|
|
|
597
|
+
checkCannedResponses(project: Project): boolean {
|
|
598
|
+
let expires = this.projectPlanUtils.checkPlanIsExpired(project)
|
|
599
|
+
this.logger.log('[CONVS-DETAIL] checkCannedResponses expires ', expires)
|
|
600
|
+
if(expires){
|
|
601
|
+
return false
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
let hasRoleToShowCanned = this.rolesCanned[PERMISSIONS.CANNED_RESPONSES_READ]
|
|
605
|
+
this.logger.log('[CONVS-DETAIL] checkCannedResponses hasRoleToShowCanned ', hasRoleToShowCanned)
|
|
606
|
+
if(hasRoleToShowCanned){
|
|
607
|
+
return true
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
return true
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
checkCannedResponsesRoles(project: Project): { [key: string]: boolean } {
|
|
614
|
+
const permissionKeys = [
|
|
615
|
+
'CANNED_RESPONSES_CREATE',
|
|
616
|
+
'CANNED_RESPONSES_READ',
|
|
617
|
+
'CANNED_RESPONSES_UPDATE',
|
|
618
|
+
'CANNED_RESPONSES_DELETE',
|
|
619
|
+
] as const;
|
|
620
|
+
|
|
621
|
+
const roles: { [key: string]: boolean } = {};
|
|
622
|
+
for (const key of permissionKeys) {
|
|
623
|
+
const permission = PERMISSIONS[key];
|
|
624
|
+
roles[permission] = hasRole(this.projectUser, permission);
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
return roles;
|
|
628
|
+
|
|
629
|
+
}
|
|
630
|
+
|
|
589
631
|
// getProjectIdSelectedConversation(conversationWith: string): string{
|
|
590
632
|
// const conversationWith_segments = conversationWith.split('-')
|
|
591
633
|
// // Removes the last element of the array if is = to the separator
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { TestBed } from '@angular/core/testing';
|
|
2
|
+
|
|
3
|
+
import { ProjectUsersService } from './project-users.service';
|
|
4
|
+
|
|
5
|
+
describe('ProjectUsersService', () => {
|
|
6
|
+
let service: ProjectUsersService;
|
|
7
|
+
|
|
8
|
+
beforeEach(() => {
|
|
9
|
+
TestBed.configureTestingModule({});
|
|
10
|
+
service = TestBed.inject(ProjectUsersService);
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
it('should be created', () => {
|
|
14
|
+
expect(service).toBeTruthy();
|
|
15
|
+
});
|
|
16
|
+
});
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { HttpClient, HttpHeaders } from '@angular/common/http';
|
|
2
|
+
import { Injectable } from '@angular/core';
|
|
3
|
+
import { Observable } from 'rxjs';
|
|
4
|
+
import { map } from 'rxjs/operators';
|
|
5
|
+
import { ProjectUser } from 'src/chat21-core/models/projectUsers';
|
|
6
|
+
import { AppStorageService } from 'src/chat21-core/providers/abstract/app-storage.service';
|
|
7
|
+
import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service';
|
|
8
|
+
import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance';
|
|
9
|
+
|
|
10
|
+
@Injectable({
|
|
11
|
+
providedIn: 'root'
|
|
12
|
+
})
|
|
13
|
+
export class ProjectUsersService {
|
|
14
|
+
|
|
15
|
+
private SERVER_BASE_URL: string;
|
|
16
|
+
private tiledeskToken: string;
|
|
17
|
+
|
|
18
|
+
private logger: LoggerService = LoggerInstance.getInstance();
|
|
19
|
+
constructor(
|
|
20
|
+
public http: HttpClient,
|
|
21
|
+
public appStorageService: AppStorageService
|
|
22
|
+
) {}
|
|
23
|
+
|
|
24
|
+
initialize(serverBaseUrl: string) {
|
|
25
|
+
this.logger.log('[TILEDESK-PROJECT_USERS-SERV] - initialize serverBaseUrl', serverBaseUrl);
|
|
26
|
+
this.SERVER_BASE_URL = serverBaseUrl;
|
|
27
|
+
this.tiledeskToken = this.appStorageService.getItem('tiledeskToken')
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
public getProjectUsersByProjectId(project_id: string): Observable<ProjectUser[]> {
|
|
31
|
+
const url = this.SERVER_BASE_URL + project_id + '/project_users/';
|
|
32
|
+
this.logger.log('[TILEDESK-SERVICE] - GET PROJECT-USER URL', url);
|
|
33
|
+
|
|
34
|
+
const httpOptions = {
|
|
35
|
+
headers: new HttpHeaders({
|
|
36
|
+
'Content-Type': 'application/json',
|
|
37
|
+
Authorization: this.tiledeskToken
|
|
38
|
+
})
|
|
39
|
+
};
|
|
40
|
+
return this.http.get(url, httpOptions).pipe(map((res: any) => {
|
|
41
|
+
this.logger.log('[TILEDESK-SERVICE] - GET PROJECT-USER RES ', res);
|
|
42
|
+
return res
|
|
43
|
+
}))
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
public getProjectUserByProjectId(project_id: string): Promise<ProjectUser> {
|
|
47
|
+
const url = this.SERVER_BASE_URL + project_id + '/project_users/me';
|
|
48
|
+
this.logger.log('[TILEDESK-SERVICE]- GET PROJECT-USER BY USER-ID - URL', url);
|
|
49
|
+
|
|
50
|
+
const httpOptions = {
|
|
51
|
+
headers: new HttpHeaders({
|
|
52
|
+
'Content-Type': 'application/json',
|
|
53
|
+
Authorization: this.tiledeskToken
|
|
54
|
+
})
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
return this.http.get(url, httpOptions).pipe(map((res: any) => {
|
|
58
|
+
this.logger.log('[TILEDESK-SERVICE] - GET PROJECT-USER RES ', res);
|
|
59
|
+
return res[0]
|
|
60
|
+
})).toPromise();
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
}
|
|
@@ -93,22 +93,6 @@ export class TiledeskService {
|
|
|
93
93
|
}))
|
|
94
94
|
}
|
|
95
95
|
|
|
96
|
-
public getProjectUsersByProjectId(project_id: string) {
|
|
97
|
-
const url = this.SERVER_BASE_URL + project_id + '/project_users/';
|
|
98
|
-
this.logger.log('[TILEDESK-SERVICE] - GET PROJECT-USER URL', url);
|
|
99
|
-
|
|
100
|
-
const httpOptions = {
|
|
101
|
-
headers: new HttpHeaders({
|
|
102
|
-
'Content-Type': 'application/json',
|
|
103
|
-
Authorization: this.tiledeskToken
|
|
104
|
-
})
|
|
105
|
-
};
|
|
106
|
-
return this.http.get(url, httpOptions).pipe(map((res: any) => {
|
|
107
|
-
this.logger.log('[TILEDESK-SERVICE] - GET PROJECT-USER RES ', res);
|
|
108
|
-
return res
|
|
109
|
-
}))
|
|
110
|
-
}
|
|
111
|
-
|
|
112
96
|
public getAllLeadsActiveWithLimit(project_id: string, limit: number) {
|
|
113
97
|
const url = this.SERVER_BASE_URL + project_id + '/leads?limit=' + limit + '&with_fullname=true';
|
|
114
98
|
this.logger.log('[TILEDESK-SERVICE] - GET ALL ACTIVE LEADS (LIMIT 10000) - URL', url);
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
|
|
2
|
+
export const PERMISSIONS = {
|
|
3
|
+
REQUEST_READ_ALL: 'request_read_all',
|
|
4
|
+
REQUEST_READ_GROUP: 'request_read_group',
|
|
5
|
+
REQUEST_READ_MY: 'request_read_my',
|
|
6
|
+
|
|
7
|
+
INBOX_READ: 'inbox_read',
|
|
8
|
+
REQUEST_UPDATE: 'request_update',
|
|
9
|
+
REQUEST_SEND: 'request_send',
|
|
10
|
+
REQUEST_CREATE_TICKET: 'request_create_ticket',
|
|
11
|
+
REQUEST_CLOSE: 'request_close',
|
|
12
|
+
REQUEST_JOIN: 'request_join',
|
|
13
|
+
REQUEST_REOPEN: 'request_reopen',
|
|
14
|
+
REQUEST_DELETE: 'request_delete',
|
|
15
|
+
REQUEST_UPDATE_STATUS: 'request_update_status',
|
|
16
|
+
REQUEST_UPDATE_PRIORITY: 'request_update_priority',
|
|
17
|
+
REQUEST_UPDATE_FOLLOWERS: 'request_update_followers',
|
|
18
|
+
REQUEST_UPDATE_SMART_ASSIGNMENT: 'request_update_smart_assignment',
|
|
19
|
+
REQUEST_UPDATE_TAGS: 'request_update_tags',
|
|
20
|
+
REQUEST_UPDATE_NOTES: 'request_update_notes',
|
|
21
|
+
REQUEST_REASSIGN:'request_reassign',
|
|
22
|
+
REQUEST_ADD:'request_add',
|
|
23
|
+
REQUEST_LEFT: 'request_left',
|
|
24
|
+
REQUEST_TRANSCRIPT_SEND: 'request_transcript_send',
|
|
25
|
+
|
|
26
|
+
HISTORY_READ: 'history_read',
|
|
27
|
+
|
|
28
|
+
AUTOMATIONSLOG_READ: "automationslog_read",
|
|
29
|
+
AUTOMATIONSLOG_CREATE: "automationslog_create",
|
|
30
|
+
|
|
31
|
+
KB_READ: 'kb_read',
|
|
32
|
+
KB_CONTENTS_ADD:'kb_contents_add',
|
|
33
|
+
KB_CONTENT_UPDATE: 'kb_content_update',
|
|
34
|
+
KB_CONTENT_REINDEX: 'kb_content_reindex',
|
|
35
|
+
KB_CONTENT_CHECK_STATUS: 'kb_content_check_status',
|
|
36
|
+
KB_NAMESPACE_ADD:'kb_namespace_add',
|
|
37
|
+
KB_SETTINGS_EDIT:'kb_settings_edit',
|
|
38
|
+
KB_DELETE: 'kb_delete',
|
|
39
|
+
KB_CONTENTS_EXPORT: 'kb_contents_export',
|
|
40
|
+
// KB_NAMESPACE_DELETE:'kb_namespace_delete',
|
|
41
|
+
// KB_CONTENTS_DELETE:'kb_contents_delete',
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
FLOWS_READ: 'flows_read',
|
|
46
|
+
FLOW_ADD: 'flow_add',
|
|
47
|
+
FLOW_EDIT: 'flow_edit',
|
|
48
|
+
FLOW_TEST: 'flow_test',
|
|
49
|
+
FLOW_DUPLICATE: 'flow_duplicate',
|
|
50
|
+
FLOW_DELETE: 'flow_delete',
|
|
51
|
+
FLOW_SHARE: 'flow_share',
|
|
52
|
+
FLOW_EXPORT: 'flow_export',
|
|
53
|
+
FLOW_WEBHOOK_COPY:"flow_webhook_copy",
|
|
54
|
+
FLOW_WEBHOOK_EDIT:"flow_webhook_edit",
|
|
55
|
+
FLOW_WEBHOOK_DELETE:"flow_webhook_delete",
|
|
56
|
+
// FLOW_VIEW_MESSAGE_GRAPH: 'flow_view_message_graph',
|
|
57
|
+
|
|
58
|
+
LEADS_READ: 'leads_read',
|
|
59
|
+
LEAD_UPDATE: 'lead_update',
|
|
60
|
+
LEAD_RESTORE: 'lead_restore',
|
|
61
|
+
LEAD_TRASH: 'lead_trash',
|
|
62
|
+
LEAD_DELETE: 'lead_delete',
|
|
63
|
+
LEADS_EXPORT: 'leads_export',
|
|
64
|
+
LEAD_BAN: 'lead_ban',
|
|
65
|
+
LEAD_UNBAN: 'lead_unban',
|
|
66
|
+
|
|
67
|
+
ANALYTICS_READ: 'analytics_read',
|
|
68
|
+
ACTIVITIES_READ: 'activities_read',
|
|
69
|
+
|
|
70
|
+
WIDGETSETUP_READ: 'widgetsetup_read',
|
|
71
|
+
INSTALLATION_READ: 'installation_read',
|
|
72
|
+
TRANSLATIONS_READ: 'translations_read',
|
|
73
|
+
|
|
74
|
+
DEPARTMENTS_LIST_READ: 'department_list_read',
|
|
75
|
+
DEPARTMENT_DETAIL_READ: 'department_detail_read',
|
|
76
|
+
DEPARTMENT_CREATE_READ: 'department_create_read',
|
|
77
|
+
|
|
78
|
+
TEAMMATES_READ: 'teammates_read',
|
|
79
|
+
TEAMMATES_DETAILS_READ: 'teammates_detail_read',
|
|
80
|
+
TEAMMATES_CREATE: 'teammates_create',
|
|
81
|
+
ROLES_READ: 'roles_read',
|
|
82
|
+
GROUPS_READ: 'groups_read',
|
|
83
|
+
|
|
84
|
+
TEAMMATE_STATUS_UPDATE: 'teammate_status_update',
|
|
85
|
+
|
|
86
|
+
EMAIL_TICKETING_READ:'email_ticketing_read',
|
|
87
|
+
EMAIL_TICKETING_UPDATE:'email_ticketing_update',
|
|
88
|
+
|
|
89
|
+
CANNED_RESPONSES_READ:'canned_responses_read',
|
|
90
|
+
CANNED_RESPONSES_UPDATE:'canned_responses_update',
|
|
91
|
+
CANNED_RESPONSES_CREATE:'canned_responses_create',
|
|
92
|
+
CANNED_RESPONSES_DELETE:'canned_responses_delete',
|
|
93
|
+
|
|
94
|
+
TAGS_READ:'tags_read',
|
|
95
|
+
TAG_CREATE:'tag_create',
|
|
96
|
+
TAG_DELETE:'tag_delete',
|
|
97
|
+
TAG_UPDATE:'tag_update',
|
|
98
|
+
|
|
99
|
+
HOURS_READ: 'hours_read',
|
|
100
|
+
HOURS_UPDATE: 'hours_update',
|
|
101
|
+
HOURS_DELETE: 'hours_delete',
|
|
102
|
+
HOURS_CREATE: 'hours_create',
|
|
103
|
+
|
|
104
|
+
INTEGRATIONS_READ: 'integrations_read',
|
|
105
|
+
INTEGRATIONS_UPDATE: 'integrations_update',
|
|
106
|
+
|
|
107
|
+
APPS_READ:'apps_read',
|
|
108
|
+
APPS_UPDATE:'apps_update',
|
|
109
|
+
|
|
110
|
+
PROJECTSETTINGS_GENERAL_READ: 'projectsettings_general_read',
|
|
111
|
+
PROJECTSETTINGS_GENERAL_UPDATE: 'projectsettings_general_update',
|
|
112
|
+
|
|
113
|
+
PROJECTSETTINGS_SUBSCRIPTION_READ: 'projectsettings_subscription_read',
|
|
114
|
+
|
|
115
|
+
PROJECTSETTINGS_DEVELOPER_READ: 'projectsettings_developer_read',
|
|
116
|
+
PROJECTSETTINGS_DEVELOPER_UPDATE: 'projectsettings_developer_update',
|
|
117
|
+
|
|
118
|
+
PROJECTSETTINGS_SMARTASSIGNMENT_READ: 'projectsettings_smartassignment_read',
|
|
119
|
+
PROJECTSETTINGS_SMARTASSIGNMENT_UPDATE: 'projectsettings_smartassignment_update',
|
|
120
|
+
|
|
121
|
+
PROJECTSETTINGS_NOTIFICATION_READ: 'projectsettings_notification_read',
|
|
122
|
+
|
|
123
|
+
PROJECTSETTINGS_SECURITY_READ: 'projectsettings_security_read',
|
|
124
|
+
|
|
125
|
+
PROJECTSETTINGS_BANNED_READ: 'projectsettings_banned_read',
|
|
126
|
+
|
|
127
|
+
PROJECTSETTINGS_ADVANCED_READ: 'projectsettings_advanced_read',
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
ACCESS_LISTS: 'accessLists',
|
|
131
|
+
PROFILE_PAGES: 'profilePages',
|
|
132
|
+
LEAD_DATA: 'leadData',
|
|
133
|
+
IMPORT_DATA: 'importData',
|
|
134
|
+
MANAGE_TAGS: 'manageTags'
|
|
135
|
+
};
|
|
@@ -129,9 +129,9 @@ export class ProjectPlanUtils {
|
|
|
129
129
|
|
|
130
130
|
//case PAYMENT plan
|
|
131
131
|
if(project && project.isActiveSubscription && project.profile.type=== 'payment'){
|
|
132
|
-
check = true
|
|
133
|
-
}else if(project && !project.isActiveSubscription && project.profile.type=== 'payment'){
|
|
134
132
|
check = false
|
|
133
|
+
}else if(project && !project.isActiveSubscription && project.profile.type=== 'payment'){
|
|
134
|
+
check = true
|
|
135
135
|
}
|
|
136
136
|
|
|
137
137
|
return check
|
package/src/app/utils/utils.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
+
import { ProjectUser } from "src/chat21-core/models/projectUsers";
|
|
2
|
+
|
|
1
3
|
export function getOSCode(key: string, token: string): boolean {
|
|
2
4
|
|
|
3
5
|
if (token) {
|
|
4
6
|
const keys: String[] = token.split("-");
|
|
5
7
|
|
|
6
8
|
let element = keys.find(el => el.includes(key))
|
|
7
|
-
console.log('keys', keys)
|
|
9
|
+
// console.log('keys', keys)
|
|
8
10
|
if(element){
|
|
9
11
|
element = element.split(":")[1]
|
|
10
12
|
if(element && element === "F"){
|
|
@@ -21,4 +23,19 @@ export function getOSCode(key: string, token: string): boolean {
|
|
|
21
23
|
}
|
|
22
24
|
|
|
23
25
|
return false
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
export function hasRole(projectUser: ProjectUser, role: string ): boolean {
|
|
30
|
+
let roles = ['owner', 'admin', 'agent'];
|
|
31
|
+
if(roles.includes(projectUser.role)){
|
|
32
|
+
return true
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if(Array.isArray(projectUser.rolePermissions) && projectUser.rolePermissions.includes(role)){
|
|
36
|
+
return true
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return false
|
|
40
|
+
|
|
24
41
|
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export interface ProjectUser {
|
|
2
|
+
_id?: string;
|
|
3
|
+
updatedAt?: any;
|
|
4
|
+
createdAt?: any;
|
|
5
|
+
id_project?: string;
|
|
6
|
+
user_available?: boolean;
|
|
7
|
+
role?: string;
|
|
8
|
+
createdBy?: string;
|
|
9
|
+
is_group_member?: boolean;
|
|
10
|
+
// id_user?: string;
|
|
11
|
+
isAuthenticated?: boolean;
|
|
12
|
+
isBusy?: boolean;
|
|
13
|
+
status?: string;
|
|
14
|
+
id_user?: any;
|
|
15
|
+
rolePermissions?: string[];
|
|
16
|
+
profileStatus?: string;
|
|
17
|
+
presence?: { [key: string]: string}
|
|
18
|
+
__v?: any;
|
|
19
|
+
}
|
|
@@ -392,7 +392,7 @@ export class FirebaseConversationHandler extends ConversationHandlerService {
|
|
|
392
392
|
verb = INFO_SUPPORT_USER_ADDED_VERB;
|
|
393
393
|
complement = INFO_SUPPORT_USER_ADDED_COMPLEMENT;
|
|
394
394
|
} else {
|
|
395
|
-
// other user has been added to the group (and he has not a
|
|
395
|
+
// other user has been added to the group (and he has not a firstname, so use hes useruid)
|
|
396
396
|
subject = message.attributes.messagelabel.parameters.member_id;
|
|
397
397
|
verb = INFO_SUPPORT_USER_ADDED_VERB;
|
|
398
398
|
complement = INFO_SUPPORT_USER_ADDED_COMPLEMENT;
|
|
@@ -370,7 +370,7 @@ export class MQTTConversationHandler extends ConversationHandlerService {
|
|
|
370
370
|
verb = INFO_SUPPORT_USER_ADDED_VERB;
|
|
371
371
|
complement = INFO_SUPPORT_USER_ADDED_COMPLEMENT;
|
|
372
372
|
} else {
|
|
373
|
-
// other user has been added to the group (and he has not a
|
|
373
|
+
// other user has been added to the group (and he has not a firstname, so use hes useruid)
|
|
374
374
|
subject = message.attributes.messagelabel.parameters.member_id;
|
|
375
375
|
verb = INFO_SUPPORT_USER_ADDED_VERB;
|
|
376
376
|
complement = INFO_SUPPORT_USER_ADDED_COMPLEMENT;
|