@chat21/chat21-ionic 3.4.31 → 3.4.32-rc10
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 +167 -2
- package/angular.json +1 -0
- package/package.json +1 -1
- package/src/app/app.component.html +3 -1
- package/src/app/app.component.ts +72 -11
- package/src/app/chatlib/list-conversations-component/ion-list-conversations/ion-list-conversations.component.html +14 -2
- package/src/app/chatlib/list-conversations-component/ion-list-conversations/ion-list-conversations.component.scss +39 -2
- package/src/app/chatlib/list-conversations-component/list-conversations.module.ts +14 -0
- package/src/app/components/canned-response/canned-response.component.html +26 -23
- package/src/app/components/canned-response/canned-response.component.scss +0 -2
- 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 +24 -1
- package/src/app/components/conversation-detail/message-text-area/message-text-area.component.scss +30 -0
- package/src/app/components/conversation-detail/message-text-area/message-text-area.component.ts +29 -7
- package/src/app/components/conversation-info/info-content/info-content.component.ts +2 -2
- package/src/app/components/conversation-info/info-group/info-group.component.ts +23 -21
- package/src/app/components/conversations-list/header-conversations-list/header-conversations-list.component.html +1 -1
- package/src/app/components/conversations-list/header-conversations-list/header-conversations-list.component.ts +5 -1
- package/src/app/components/navbar/navbar.component.html +35 -9
- package/src/app/components/navbar/navbar.component.scss +71 -1
- package/src/app/components/navbar/navbar.component.ts +100 -42
- package/src/app/components/project-item/project-item.component.ts +79 -52
- package/src/app/components/sidebar/sidebar.component.html +65 -45
- package/src/app/components/sidebar/sidebar.component.ts +110 -117
- package/src/app/components/sidebar-user-details/sidebar-user-details.component.html +52 -11
- package/src/app/components/sidebar-user-details/sidebar-user-details.component.scss +304 -17
- package/src/app/components/sidebar-user-details/sidebar-user-details.component.ts +217 -27
- package/src/app/modals/create-ticket/create-ticket.page.ts +4 -2
- package/src/app/pages/conversation-detail/conversation-detail.page.html +7 -3
- package/src/app/pages/conversation-detail/conversation-detail.page.ts +89 -5
- package/src/app/pages/conversations-list/conversations-list.module.ts +3 -5
- package/src/app/pages/conversations-list/conversations-list.page.html +2 -0
- package/src/app/pages/conversations-list/conversations-list.page.ts +120 -26
- package/src/app/pages/unassigned-conversations/unassigned-conversations.module.ts +16 -4
- package/src/app/pages/unassigned-conversations/unassigned-conversations.page.html +43 -17
- package/src/app/pages/unassigned-conversations/unassigned-conversations.page.scss +25 -1
- package/src/app/pages/unassigned-conversations/unassigned-conversations.page.ts +279 -13
- package/src/app/pipe/filter.pipe.spec.ts +8 -0
- package/src/app/pipe/filter.pipe.ts +15 -0
- package/src/app/pipe/find.pipe.spec.ts +8 -0
- package/src/app/pipe/find.pipe.ts +15 -0
- package/src/app/services/global-settings/global-settings.service.ts +11 -3
- package/src/app/services/nav-proxy.service.ts +0 -1
- 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/projects/project.service.ts +2 -1
- package/src/app/services/tiledesk/tiledesk.service.ts +24 -0
- package/src/app/services/triggerEvents/triggerEvents.ts +40 -0
- package/src/app/services/websocket/websocket-js.ts +59 -534
- package/src/app/services/websocket/websocket-js_old.ts +578 -0
- package/src/app/services/websocket/websocket.service.ts +67 -14
- package/src/app/services/websocket/websocket.worker.ts +242 -0
- package/src/app/shared/shared.module.ts +26 -10
- package/src/app/utils/globals.ts +2 -0
- package/src/app/utils/permissions.constants.ts +138 -0
- package/src/app/utils/project-utils.ts +2 -2
- package/src/app/utils/utils.ts +18 -1
- package/src/assets/i18n/ar.json +11 -1
- package/src/assets/i18n/az.json +11 -1
- package/src/assets/i18n/de.json +11 -1
- package/src/assets/i18n/en.json +11 -1
- package/src/assets/i18n/es.json +11 -1
- package/src/assets/i18n/fr.json +11 -1
- package/src/assets/i18n/it.json +13 -3
- package/src/assets/i18n/kk.json +11 -1
- package/src/assets/i18n/pt.json +11 -1
- package/src/assets/i18n/ru.json +11 -1
- package/src/assets/i18n/sr.json +11 -1
- package/src/assets/i18n/sv.json +11 -1
- package/src/assets/i18n/tr.json +11 -1
- package/src/assets/i18n/uk.json +11 -1
- package/src/assets/i18n/uz.json +12 -1
- package/src/assets/js/agentDesktop-sdk.js +55 -0
- package/src/assets/js/chat21client.js +36 -0
- package/src/assets/js/mqtt-keepalive-worker.js +53 -0
- package/src/assets/test.html +5 -2
- package/src/chat-config-template.json +1 -0
- package/src/chat-config.json +1 -0
- package/src/chat21-core/models/projectUsers.ts +19 -0
- package/src/chat21-core/models/project_user.ts +2 -1
- package/src/chat21-core/models/projects.ts +1 -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/src/chat21-core/providers/tiledesk/tiledesk-auth.service.ts +3 -0
- package/src/chat21-core/utils/constants.ts +6 -0
- package/src/chat21-core/utils/convertRequestToConversation.ts +2 -2
- package/src/chat21-core/utils/utils.ts +53 -3
- package/src/variables.scss +3 -0
package/src/app/components/conversation-detail/message-text-area/message-text-area.component.html
CHANGED
|
@@ -22,6 +22,13 @@
|
|
|
22
22
|
{{translationMap?.get('WHATSAPP.LABEL_TEMPLATES')}}
|
|
23
23
|
</ion-button>
|
|
24
24
|
</div>
|
|
25
|
+
<!-- OPEN TICKET -->
|
|
26
|
+
<div *ngIf="ticketSection" class="section-option" id="template" tooltip="{{translationMap?.get('TICKET.OPEN_TICKET')}}" placement="top">
|
|
27
|
+
<ion-button fill="clear" [class.active]="section==='ticket'" (click)="onOpenSection('ticket')" [disabled]="channelType === 'direct'">
|
|
28
|
+
<ion-icon name="ticket"></ion-icon>
|
|
29
|
+
{{translationMap?.get('TICKET.OPEN_TICKET')}}
|
|
30
|
+
</ion-button>
|
|
31
|
+
</div>
|
|
25
32
|
</div>
|
|
26
33
|
|
|
27
34
|
<div class="footerContainerAlert">
|
|
@@ -50,6 +57,22 @@
|
|
|
50
57
|
</ion-col>
|
|
51
58
|
</ion-row>
|
|
52
59
|
|
|
60
|
+
<ion-row id="ticket" [style.display]="section==='ticket'? 'flex': 'none'">
|
|
61
|
+
<ion-col col-auto>
|
|
62
|
+
<div class="placeholder">{{translationMap.get('TICKET.DESCRIPTION')}}</div>
|
|
63
|
+
<div class="buttons-container">
|
|
64
|
+
<ion-button name="add" size="small" (click)="onClickTicket('open')">
|
|
65
|
+
<ion-icon name="add"></ion-icon>
|
|
66
|
+
{{translationMap?.get('TICKET.CONFIRM')}}
|
|
67
|
+
</ion-button>
|
|
68
|
+
<ion-button size="small" color="danger" (click)="onClickTicket('close')">
|
|
69
|
+
<ion-icon name="close"></ion-icon>
|
|
70
|
+
{{translationMap?.get('TICKET.CLOSE')}}
|
|
71
|
+
</ion-button>
|
|
72
|
+
</div>
|
|
73
|
+
</ion-col>
|
|
74
|
+
</ion-row>
|
|
75
|
+
|
|
53
76
|
<ion-row id="message-text-area" [style.display]="section==='chat' || section ==='templates' || section ==='copilot'? 'flex': 'none'">
|
|
54
77
|
|
|
55
78
|
<ion-col col-auto style="display: flex;">
|
|
@@ -57,7 +80,7 @@
|
|
|
57
80
|
<div class="buttons-left">
|
|
58
81
|
|
|
59
82
|
<!-- CANNED RESPONSES -->
|
|
60
|
-
<ng-container *ngIf="areVisibleCAR && supportMode">
|
|
83
|
+
<ng-container *ngIf="areVisibleCAR && supportMode && cannedSection">
|
|
61
84
|
<div class="canned-responses-btn-wpr" tooltip="{{translationMap?.get('CANNED_RESPONSES')}}" placement="top">
|
|
62
85
|
<ion-button ion-button fill="clear" class="canned-responses-btn" (click)="openCannedResponses()"
|
|
63
86
|
[disabled]="!conversationWith?.startsWith(CHANNEL_TYPE.SUPPORT_GROUP) || disableTextarea">
|
package/src/app/components/conversation-detail/message-text-area/message-text-area.component.scss
CHANGED
|
@@ -183,6 +183,36 @@
|
|
|
183
183
|
}
|
|
184
184
|
}
|
|
185
185
|
|
|
186
|
+
#ticket{
|
|
187
|
+
text-align: center;
|
|
188
|
+
font-size: 12px;
|
|
189
|
+
|
|
190
|
+
.buttons-container{
|
|
191
|
+
display: flex;
|
|
192
|
+
justify-content: center;
|
|
193
|
+
gap: 10px;
|
|
194
|
+
|
|
195
|
+
ion-button{
|
|
196
|
+
font-size: 12px;
|
|
197
|
+
--padding-top: 4px;
|
|
198
|
+
--padding-bottom: 4px;
|
|
199
|
+
--padding-start: 6px;
|
|
200
|
+
--padding-end: 6px;
|
|
201
|
+
--ripple-color: transparent;
|
|
202
|
+
text-transform: unset;
|
|
203
|
+
height: auto;
|
|
204
|
+
|
|
205
|
+
ion-icon{
|
|
206
|
+
margin-right: 4px;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
&[name="add"]{
|
|
210
|
+
--background: var(--basic-blue);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
186
216
|
#fileInput {
|
|
187
217
|
position: absolute;
|
|
188
218
|
opacity: 0;
|
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;
|
|
@@ -61,16 +63,20 @@ export class MessageTextAreaComponent implements OnInit, AfterViewInit, OnChange
|
|
|
61
63
|
@Input() emailSection: boolean;
|
|
62
64
|
@Input() offlineMsgEmail: boolean;
|
|
63
65
|
@Input() whatsappTemplatesSection: boolean;
|
|
66
|
+
@Input() ticketSection: boolean
|
|
64
67
|
@Input() isOpenInfoConversation: boolean;
|
|
68
|
+
@Input() cannedSection: boolean;
|
|
65
69
|
@Input() stylesMap: Map<string, string>;
|
|
66
70
|
@Input() translationMap: Map<string, string>;
|
|
67
71
|
@Input() dropEvent: any;
|
|
68
72
|
@Input() disableTextarea: boolean;
|
|
73
|
+
@Input() roles: Array<string>;
|
|
69
74
|
@Output() eventChangeTextArea = new EventEmitter<{msg: string, offsetHeight: number}>();
|
|
70
75
|
@Output() eventSendMessage = new EventEmitter<{msg: string, type: string, metadata?: Object, attributes?: Object}>();
|
|
71
76
|
@Output() onClickOpenCannedResponses = new EventEmitter<boolean>();
|
|
72
77
|
@Output() onPresentModalScrollToBottom = new EventEmitter<boolean>();
|
|
73
78
|
@Output() onOpenFooterSection = new EventEmitter<string>();
|
|
79
|
+
@Output() onOpenTicket = new EventEmitter<boolean>();
|
|
74
80
|
|
|
75
81
|
public project: Project;
|
|
76
82
|
public conversationEnabled = false;
|
|
@@ -293,6 +299,17 @@ export class MessageTextAreaComponent implements OnInit, AfterViewInit, OnChange
|
|
|
293
299
|
this.prensentTemplateModal();
|
|
294
300
|
}
|
|
295
301
|
|
|
302
|
+
onClickTicket(option: "open" | "close"){
|
|
303
|
+
this.logger.log('[CONVS-DETAIL][MSG-TEXT-AREA] - onClickTicket', option);
|
|
304
|
+
switch(option){
|
|
305
|
+
case "open":
|
|
306
|
+
this.onOpenTicket.emit();
|
|
307
|
+
case "close":
|
|
308
|
+
this.section = 'chat'
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
}
|
|
312
|
+
|
|
296
313
|
|
|
297
314
|
/**
|
|
298
315
|
*
|
|
@@ -575,8 +592,10 @@ export class MessageTextAreaComponent implements OnInit, AfterViewInit, OnChange
|
|
|
575
592
|
if (!text.includes("/")) {
|
|
576
593
|
this.logger.log('[CONVS-DETAIL][MSG-TEXT-AREA] onKeydown - SEND MESSAGE 1 message: ', message);
|
|
577
594
|
this.logger.log("[CONVS-DETAIL] replaceTagInMessage onKeydown in msg-texarea SEND MESSAGE 1 message: ", message);
|
|
578
|
-
|
|
595
|
+
|
|
579
596
|
this.sendMessage(text);
|
|
597
|
+
// this.messageString = '';
|
|
598
|
+
|
|
580
599
|
this.countClicks = 0
|
|
581
600
|
} else if (text.includes("/") && pos === 0 && this.countClicks > 1 && this.tagsCannedFilter.length > 0) {
|
|
582
601
|
this.logger.log('[CONVS-DETAIL][MSG-TEXT-AREA] onKeydown - tagsCannedFilter.length 2: ', this.tagsCannedFilter.length);
|
|
@@ -588,9 +607,10 @@ export class MessageTextAreaComponent implements OnInit, AfterViewInit, OnChange
|
|
|
588
607
|
this.logger.log("[CONVS-DETAIL] replaceTagInMessage onKeydown in msg-texarea SEND MESSAGE 2 this.countClicks: ", this.countClicks);
|
|
589
608
|
this.logger.log("[CONVS-DETAIL][MSG-TEXT-AREA] onKeydown in msg-texarea SEND MESSAGE 2 this.countClicks: ", this.countClicks);
|
|
590
609
|
this.logger.log('[CONVS-DETAIL][MSG-TEXT-AREA] onKeydown - SEND MESSAGE 2 message: ', message);
|
|
591
|
-
|
|
592
|
-
|
|
610
|
+
|
|
593
611
|
this.sendMessage(text);
|
|
612
|
+
// this.messageString = '';
|
|
613
|
+
|
|
594
614
|
this.countClicks = 0
|
|
595
615
|
} else if (text.includes("/") && pos > 0 && this.countClicks > 1 && this.tagsCannedFilter.length > 0 && text.substr(-1) !== '/') {
|
|
596
616
|
this.logger.log('[CONVS-DETAIL][MSG-TEXT-AREA] onKeydown - tagsCannedFilter.length 3: ', this.tagsCannedFilter.length);
|
|
@@ -602,17 +622,19 @@ export class MessageTextAreaComponent implements OnInit, AfterViewInit, OnChange
|
|
|
602
622
|
this.logger.log("[CONVS-DETAIL] replaceTagInMessage onKeydown in msg-texarea SEND MESSAGE 2 this.countClicks: ", this.countClicks);
|
|
603
623
|
this.logger.log("[CONVS-DETAIL][MSG-TEXT-AREA] onKeydown in msg-texarea SEND MESSAGE 2 this.countClicks: ", this.countClicks);
|
|
604
624
|
this.logger.log('[CONVS-DETAIL][MSG-TEXT-AREA] onKeydown - SEND MESSAGE 2 message: ', message);
|
|
605
|
-
|
|
606
|
-
|
|
625
|
+
|
|
607
626
|
this.sendMessage(text);
|
|
627
|
+
// this.messageString = '';
|
|
628
|
+
|
|
608
629
|
this.countClicks = 0
|
|
609
630
|
} else if (text.includes("/") && this.tagsCannedFilter.length === 0) {
|
|
610
631
|
this.logger.log('[CONVS-DETAIL][MSG-TEXT-AREA] onKeydown - tagsCannedFilter.length 3: ', this.tagsCannedFilter.length);
|
|
611
632
|
this.logger.log('[CONVS-DETAIL][MSG-TEXT-AREA] onKeydown - SEND MESSAGE 3 message: ', message);
|
|
612
633
|
this.logger.log("[CONVS-DETAIL] replaceTagInMessage onKeydown in msg-texarea SEND MESSAGE 3 message: ", message);
|
|
613
|
-
|
|
614
|
-
|
|
634
|
+
|
|
615
635
|
this.sendMessage(text);
|
|
636
|
+
// this.messageString = '';
|
|
637
|
+
|
|
616
638
|
this.countClicks = 0
|
|
617
639
|
|
|
618
640
|
}
|
|
@@ -70,8 +70,8 @@ export class InfoContentComponent implements OnInit {
|
|
|
70
70
|
this.route.paramMap.subscribe(params => {
|
|
71
71
|
this.logger.log('[INFO-CONTENT-COMP] initialize params: ', params);
|
|
72
72
|
this.conversationWith = params.get('IDConv');
|
|
73
|
-
this.conversationWithFullname = params.get('FullNameConv');
|
|
74
|
-
this.conv_type = params.get('Convtype');
|
|
73
|
+
this.conversationWithFullname = decodeURIComponent(params.get('FullNameConv'));
|
|
74
|
+
this.conv_type = decodeURIComponent(params.get('Convtype'));
|
|
75
75
|
|
|
76
76
|
const conversationWith_segments = this.conversationWith.split('-');
|
|
77
77
|
|
|
@@ -151,27 +151,29 @@ export class InfoGroupComponent implements OnInit, AfterViewInit, OnChanges {
|
|
|
151
151
|
});
|
|
152
152
|
|
|
153
153
|
this.contactsService.loadContactDetail(key).pipe(takeUntil(this.unsubscribe$)).subscribe(user => {
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
154
|
+
if(user){
|
|
155
|
+
this.logger.log('InfoGroupComponent group detail loadContactDetail RES', user);
|
|
156
|
+
// this.logger.log('InfoGroupComponent group detail this.presenceService.BSIsOnline.value()', this.presenceService.BSIsOnline.getValue);
|
|
157
|
+
|
|
158
|
+
user.imageurl = this.imageRepoService.getImagePhotoUrl(key)
|
|
159
|
+
// this.member_array.push({ userid: user.uid, avatar: user.avatar, color: user.color, email: user.email, fullname: user.fullname, imageurl: user.imageurl, userOnline: isOnline })
|
|
160
|
+
var index = this.member_array.findIndex(m => m.userid === user.uid);
|
|
161
|
+
this.logger.log('InfoGroupComponent member_array first of push index', index);
|
|
162
|
+
this.logger.log('InfoGroupComponent member_array first of push', this.member_array);
|
|
163
|
+
if (index === -1) {
|
|
164
|
+
this.member_array.push(
|
|
165
|
+
{
|
|
166
|
+
userid: user.uid,
|
|
167
|
+
avatar: user.avatar,
|
|
168
|
+
color: user.color,
|
|
169
|
+
email: user.email,
|
|
170
|
+
fullname: user.fullname,
|
|
171
|
+
imageurl: user.imageurl,
|
|
172
|
+
userOnline: members_isonline_array[user.uid]['isSignin']
|
|
173
|
+
})
|
|
174
|
+
} else {
|
|
175
|
+
this.logger.log('InfoGroupComponent member already exist in member_array');
|
|
176
|
+
}
|
|
175
177
|
}
|
|
176
178
|
}, (error) => {
|
|
177
179
|
this.logger.error('InfoGroupComponent group detail loadContactDetail - ERROR ', error);
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
<!-- <ion-icon name="file-tray-full-outline"></ion-icon> -->
|
|
35
35
|
</ion-button>
|
|
36
36
|
|
|
37
|
-
<ion-button *ngIf="writeto_btn" ion-button fill="clear" (click)="onOpenContactsDirectory($event)"
|
|
37
|
+
<ion-button *ngIf="writeto_btn && isVisibleCNT && roles?.[PERMISSIONS.LEADS_READ]" ion-button fill="clear" (click)="onOpenContactsDirectory($event)"
|
|
38
38
|
tooltip="{{translationMap?.get('ViewContactsList')}}" placement="bottom">
|
|
39
39
|
<ion-icon slot="icon-only" name="create-outline"></ion-icon>
|
|
40
40
|
<!-- <ion-icon slot="icon-only" name="people-outline"></ion-icon> -->
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { PERMISSIONS } from 'src/app/utils/permissions.constants';
|
|
1
2
|
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core'
|
|
2
3
|
import { ModalController } from '@ionic/angular'
|
|
3
4
|
import { EventsService } from 'src/app/services/events-service'
|
|
@@ -17,6 +18,8 @@ export class HeaderConversationsList implements OnInit {
|
|
|
17
18
|
@Input() sound_btn: string;
|
|
18
19
|
@Input() isMobile: boolean;
|
|
19
20
|
@Input() isVisibleTKT: boolean = true;
|
|
21
|
+
@Input() isVisibleCNT: boolean = true;;
|
|
22
|
+
@Input() roles: Array<string>;
|
|
20
23
|
@Output() onSoundChange = new EventEmitter<string>()
|
|
21
24
|
@Output() openContactsDirectory = new EventEmitter()
|
|
22
25
|
@Output() openProfileInfo = new EventEmitter()
|
|
@@ -24,6 +27,7 @@ export class HeaderConversationsList implements OnInit {
|
|
|
24
27
|
createTicketModal = null
|
|
25
28
|
public translationMap: Map<string, string>;
|
|
26
29
|
|
|
30
|
+
PERMISSIONS = PERMISSIONS;
|
|
27
31
|
constructor(
|
|
28
32
|
public events: EventsService,
|
|
29
33
|
public modalController: ModalController,
|
|
@@ -62,7 +66,7 @@ export class HeaderConversationsList implements OnInit {
|
|
|
62
66
|
// }
|
|
63
67
|
|
|
64
68
|
ngOnInit() {
|
|
65
|
-
|
|
69
|
+
console.log('DDP HEADER SUPPORT MODE ', this.roles)
|
|
66
70
|
}
|
|
67
71
|
|
|
68
72
|
// START @Output() //
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
</div>
|
|
6
6
|
<div class="navbar-right">
|
|
7
7
|
<!-- test site -->
|
|
8
|
-
<ng-container *ngIf="project">
|
|
8
|
+
<ng-container *ngIf="project && roles?.[PERMISSIONS.SIMULATE_CONV]">
|
|
9
9
|
<button class="btn simulate-visitor-btn" (click)="testWidgetPage()">
|
|
10
10
|
<i class="material-icons">play_arrow</i>
|
|
11
11
|
<!-- {{translationsMap?.get('NAVBAR.SIMULATE_VISITOR')}} -->
|
|
@@ -23,9 +23,9 @@
|
|
|
23
23
|
</ng-container>
|
|
24
24
|
|
|
25
25
|
<!-- ------ PROJECTS DROPDOWN ------ -->
|
|
26
|
-
<ng-container *ngIf="project">
|
|
26
|
+
<ng-container *ngIf="project && roles?.[PERMISSIONS.CHANGE_PROJECT]">
|
|
27
27
|
<li>
|
|
28
|
-
<button class="btn dropdown-toggle project-dropdown" (click)="
|
|
28
|
+
<button class="btn dropdown-toggle project-dropdown" (click)="toggleProjectsDropdown()">
|
|
29
29
|
<span class="project-dropdown" style="text-transform: none"> {{ project?.id_project?.name }} </span>
|
|
30
30
|
<i class="material-icons" style="margin-right: 3px;">arrow_drop_down</i>
|
|
31
31
|
</button>
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
</li>
|
|
50
50
|
|
|
51
51
|
<!-- ADD PROJECT -->
|
|
52
|
-
<li id="navbar_create_prjct" *ngIf="
|
|
52
|
+
<li id="navbar_create_prjct" *ngIf="isVisibleMT" (click)="onClickDropdownOption('addProject')" class="add-project">
|
|
53
53
|
<a>
|
|
54
54
|
<i class="material-icons">add_circle_outline </i>
|
|
55
55
|
{{translationsMap?.get('NAVBAR.ADD_PROJECT')}}
|
|
@@ -71,9 +71,22 @@
|
|
|
71
71
|
<!-- *ngFor="let prjct of projects?.slice().reverse() | slice:0:5; let i=index" -->
|
|
72
72
|
<li *ngFor="let prjct of projects?.slice() | slice:0:5; let i=index" style="cursor: pointer">
|
|
73
73
|
<a (click)="goToHome(prjct?.id_project?._id, prjct?.id_project?.name)"
|
|
74
|
-
[ngClass]="{'li-selected' : prjct?.id_project?._id === project?.id_project?.id }"
|
|
75
|
-
|
|
76
|
-
<span>
|
|
74
|
+
[ngClass]="{'li-selected' : prjct?.id_project?._id === project?.id_project?.id }"
|
|
75
|
+
class="project-item-row">
|
|
76
|
+
<span class="project-item-name">{{ prjct?.id_project?.name }}</span>
|
|
77
|
+
<span class="project-item-status project-item-status-wrapper"
|
|
78
|
+
[attr.title]="translationsMap?.get(prjct?.teammateStatus?.label) || prjct?.teammateStatus?.name"
|
|
79
|
+
(click)="toggleStatusDropdown($event, prjct)">
|
|
80
|
+
<img style="width: 15px; height: 15px; position: relative; top: 1px; cursor: pointer;" height="15" width="15" [src]="prjct?.teammateStatus?.avatar" />
|
|
81
|
+
<div class="status-dropdown status-dropdown-fixed" *ngIf="openStatusDropdownProjectId === prjct?.id_project?._id" (click)="$event.stopPropagation()"
|
|
82
|
+
[style.top.px]="statusDropdownPosition.top" [style.right.px]="statusDropdownPosition.right">
|
|
83
|
+
<div class="status-dropdown-option" *ngFor="let status of TEAMMATE_STATUS"
|
|
84
|
+
(click)="$event.stopPropagation(); onChangeProjectStatus(prjct, status.id)">
|
|
85
|
+
<img style="width: 15px; height: 15px; margin-right: 6px;" [src]="status.avatar" />
|
|
86
|
+
<span>{{ translationsMap?.get(status.label) || status.name }}</span>
|
|
87
|
+
</div>
|
|
88
|
+
</div>
|
|
89
|
+
</span>
|
|
77
90
|
</a>
|
|
78
91
|
</li>
|
|
79
92
|
|
|
@@ -85,8 +98,21 @@
|
|
|
85
98
|
|
|
86
99
|
<!-- *ngFor="let prjct of projects?.slice().reverse() | slice:5:10; let i=index" -->
|
|
87
100
|
<li *ngFor="let prjct of projects?.slice() | slice:5:10; let i=index" style="cursor: pointer">
|
|
88
|
-
<a (click)="goToHome(prjct?.id_project?._id, prjct?.id_project?.name)">
|
|
89
|
-
{{ prjct?.id_project?.name }}
|
|
101
|
+
<a (click)="goToHome(prjct?.id_project?._id, prjct?.id_project?.name)" class="project-item-row">
|
|
102
|
+
<span class="project-item-name">{{ prjct?.id_project?.name }}</span>
|
|
103
|
+
<span class="project-item-status project-item-status-wrapper"
|
|
104
|
+
[attr.title]="translationsMap?.get(prjct?.teammateStatus?.label) || prjct?.teammateStatus?.name"
|
|
105
|
+
(click)="toggleStatusDropdown($event, prjct)">
|
|
106
|
+
<img style="width: 15px; height: 15px; position: relative; top: 1px; cursor: pointer;" height="15" width="15" [src]="prjct?.teammateStatus?.avatar" />
|
|
107
|
+
<div class="status-dropdown status-dropdown-fixed" *ngIf="openStatusDropdownProjectId === prjct?.id_project?._id" (click)="$event.stopPropagation()"
|
|
108
|
+
[style.top.px]="statusDropdownPosition.top" [style.right.px]="statusDropdownPosition.right">
|
|
109
|
+
<div class="status-dropdown-option" *ngFor="let status of TEAMMATE_STATUS"
|
|
110
|
+
(click)="$event.stopPropagation(); onChangeProjectStatus(prjct, status.id)">
|
|
111
|
+
<img style="width: 15px; height: 15px; margin-right: 6px;" [src]="status.avatar" />
|
|
112
|
+
<span>{{ translationsMap?.get(status.label) || status.name }}</span>
|
|
113
|
+
</div>
|
|
114
|
+
</div>
|
|
115
|
+
</span>
|
|
90
116
|
</a>
|
|
91
117
|
</li>
|
|
92
118
|
</ng-container>
|
|
@@ -94,12 +94,18 @@ ion-navbar{
|
|
|
94
94
|
overflow: hidden;
|
|
95
95
|
text-overflow: ellipsis;
|
|
96
96
|
font-family: var(--header-font-family);
|
|
97
|
-
|
|
97
|
+
line-height: 1.4;
|
|
98
|
+
|
|
98
99
|
.material-icons{
|
|
99
100
|
font-size: 20px;
|
|
100
101
|
}
|
|
101
102
|
}
|
|
102
103
|
|
|
104
|
+
button.btn.project-dropdown {
|
|
105
|
+
padding-top: 4px;
|
|
106
|
+
padding-bottom: 4px;
|
|
107
|
+
}
|
|
108
|
+
|
|
103
109
|
li{
|
|
104
110
|
position: relative;
|
|
105
111
|
display: block
|
|
@@ -204,6 +210,70 @@ li{
|
|
|
204
210
|
color: var(--dropdown-menu-hover-color);
|
|
205
211
|
box-shadow: 0 12px 20px -10px rgba(var(--dropdown-menu-hover-color), 0.28), 0 4px 20px 0 rgba(0, 0, 0, 0.12), 0 7px 8px -5px rgba(var(--dropdown-menu-hover-color), 0.2);
|
|
206
212
|
}
|
|
213
|
+
|
|
214
|
+
&.project-item-row {
|
|
215
|
+
display: flex;
|
|
216
|
+
align-items: center;
|
|
217
|
+
justify-content: space-between;
|
|
218
|
+
gap: 8px;
|
|
219
|
+
|
|
220
|
+
.project-item-name {
|
|
221
|
+
flex: 1;
|
|
222
|
+
min-width: 0;
|
|
223
|
+
text-align: left;
|
|
224
|
+
overflow: hidden;
|
|
225
|
+
text-overflow: ellipsis;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
.project-item-status {
|
|
229
|
+
flex: 0 0 10%;
|
|
230
|
+
display: flex;
|
|
231
|
+
justify-content: flex-end;
|
|
232
|
+
align-items: center;
|
|
233
|
+
|
|
234
|
+
&.project-item-status-wrapper {
|
|
235
|
+
position: relative;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
.status-dropdown {
|
|
239
|
+
position: absolute;
|
|
240
|
+
right: 100%;
|
|
241
|
+
top: 50%;
|
|
242
|
+
transform: translateY(-50%);
|
|
243
|
+
margin-right: 4px;
|
|
244
|
+
min-width: 140px;
|
|
245
|
+
padding: 4px 0;
|
|
246
|
+
background-color: var(--dropdown-menu-background);
|
|
247
|
+
border-radius: 3px;
|
|
248
|
+
box-shadow: 0 2px 5px 0 rgb(0, 0, 0, 0.26);
|
|
249
|
+
z-index: 1001;
|
|
250
|
+
list-style: none;
|
|
251
|
+
|
|
252
|
+
&.status-dropdown-fixed {
|
|
253
|
+
position: fixed;
|
|
254
|
+
right: auto;
|
|
255
|
+
left: auto;
|
|
256
|
+
margin-right: 0;
|
|
257
|
+
transform: translateY(-50%);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
.status-dropdown-option {
|
|
261
|
+
display: flex;
|
|
262
|
+
align-items: center;
|
|
263
|
+
padding: 8px 16px;
|
|
264
|
+
font-size: 13px;
|
|
265
|
+
color: var(--dropdown-menu-color);
|
|
266
|
+
cursor: pointer;
|
|
267
|
+
white-space: nowrap;
|
|
268
|
+
|
|
269
|
+
&:hover {
|
|
270
|
+
background-color: var(--dropdown-menu-hover-background);
|
|
271
|
+
color: var(--dropdown-menu-hover-color);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
207
277
|
}
|
|
208
278
|
|
|
209
279
|
|