@chat21/chat21-ionic 3.4.29 → 3.4.30-rc2
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 +120 -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 +71 -12
- package/src/app/chatlib/conversation-detail/message/image/image.component.html +1 -0
- package/src/app/chatlib/conversation-detail/message/image/image.component.ts +19 -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 +39 -9
- 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 +3 -3
- package/src/app/components/navbar/navbar.component.ts +29 -38
- package/src/app/components/project-item/project-item.component.ts +11 -11
- 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 +2 -2
- package/src/app/components/sidebar-user-details/sidebar-user-details.component.ts +10 -7
- 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 +95 -7
- package/src/app/pages/conversations-list/conversations-list.page.html +2 -0
- package/src/app/pages/conversations-list/conversations-list.page.ts +40 -2
- 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/tiledesk/tiledesk.service.ts +0 -16
- package/src/app/services/triggerEvents/triggerEvents.ts +28 -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 +9 -10
- package/src/app/services/websocket/websocket.worker.ts +242 -0
- package/src/app/shared/shared.module.ts +11 -2
- 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/img/no_data_found.png +0 -0
- 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/providers/abstract/upload.service.ts +5 -1
- package/src/chat21-core/providers/firebase/firebase-conversation-handler.ts +1 -1
- package/src/chat21-core/providers/firebase/firebase-upload.service.ts +136 -9
- package/src/chat21-core/providers/mqtt/mqtt-conversation-handler.ts +1 -1
- package/src/chat21-core/providers/native/native-image-repo.ts +1 -1
- package/src/chat21-core/providers/native/native-upload-service.ts +143 -45
- package/src/chat21-core/providers/tiledesk/tiledesk-auth.service.ts +3 -0
- package/src/chat21-core/utils/utils.ts +16 -2
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
/// websocket.worker.ts
|
|
2
|
+
|
|
3
|
+
interface WSMessage {
|
|
4
|
+
action?: string;
|
|
5
|
+
event?: { topic: string; method: string };
|
|
6
|
+
payload?: any;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
interface Subscription {
|
|
10
|
+
topic: string;
|
|
11
|
+
label?: string;
|
|
12
|
+
onCreate?: (msg: any) => void;
|
|
13
|
+
onUpdate?: (msg: any) => void;
|
|
14
|
+
onData?: (msg: any) => void;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
let ws: WebSocket | null = null;
|
|
18
|
+
let url = '';
|
|
19
|
+
let reconnectInterval = 5000;
|
|
20
|
+
let subscriptions: Subscription[] = [];
|
|
21
|
+
let pendingMessages: any[] = [];
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
let pingMsg = { action: "heartbeat", payload: { message: { text: "ping" } } }
|
|
25
|
+
let pongMsg = { action: "heartbeat", payload: { message: { text: "pong" } } }
|
|
26
|
+
const pongTimeout = 10000;
|
|
27
|
+
const pingTimeout = 15000;
|
|
28
|
+
let pingTimeoutId;
|
|
29
|
+
let pongTimeoutId;
|
|
30
|
+
|
|
31
|
+
let reconnectAttempts = 0;
|
|
32
|
+
const maxReconnectDelay = 30000;
|
|
33
|
+
let manuallyClosed = false;
|
|
34
|
+
let pageHidden = false;
|
|
35
|
+
|
|
36
|
+
onmessage = (e: MessageEvent) => {
|
|
37
|
+
const { action, data } = e.data;
|
|
38
|
+
|
|
39
|
+
switch (action) {
|
|
40
|
+
case 'init':
|
|
41
|
+
url = data.url;
|
|
42
|
+
connect();
|
|
43
|
+
break;
|
|
44
|
+
case 'subscribe':
|
|
45
|
+
const topic = data.topic || data.label;
|
|
46
|
+
subscriptions.push({ topic });
|
|
47
|
+
if (ws && ws.readyState === WebSocket.OPEN) {
|
|
48
|
+
ws.send(JSON.stringify({
|
|
49
|
+
action: 'subscribe',
|
|
50
|
+
payload: {
|
|
51
|
+
topic: topic,
|
|
52
|
+
message: undefined,
|
|
53
|
+
method: undefined
|
|
54
|
+
}
|
|
55
|
+
}));
|
|
56
|
+
}
|
|
57
|
+
break;
|
|
58
|
+
case 'unsubscribe':
|
|
59
|
+
subscriptions = subscriptions.filter(s => s.topic !== data.topic);
|
|
60
|
+
if (ws && ws.readyState === WebSocket.OPEN) {
|
|
61
|
+
// Unsubscribe
|
|
62
|
+
ws.send(JSON.stringify({
|
|
63
|
+
action: 'unsubscribe',
|
|
64
|
+
payload: {
|
|
65
|
+
topic: data.topic,
|
|
66
|
+
message: undefined,
|
|
67
|
+
method: undefined
|
|
68
|
+
}
|
|
69
|
+
}));
|
|
70
|
+
}
|
|
71
|
+
break;
|
|
72
|
+
case 'visibility': // ✅ Nuovo
|
|
73
|
+
pageHidden = data.hidden;
|
|
74
|
+
break;
|
|
75
|
+
case 'send':
|
|
76
|
+
sendMessage(data.message);
|
|
77
|
+
break;
|
|
78
|
+
case 'close': // ✅ Nuovo
|
|
79
|
+
closeConnection();
|
|
80
|
+
break;
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
function connect() {
|
|
85
|
+
ws = new WebSocket(url);
|
|
86
|
+
ws.onopen = () => {
|
|
87
|
+
console.log('[Worker] WebSocket connected',subscriptions);
|
|
88
|
+
// Risottiamo pending subscriptions
|
|
89
|
+
subscriptions.forEach(s => {
|
|
90
|
+
ws!.send(JSON.stringify({
|
|
91
|
+
action: 'subscribe',
|
|
92
|
+
payload: {
|
|
93
|
+
topic: s.topic,
|
|
94
|
+
message: undefined,
|
|
95
|
+
method: undefined
|
|
96
|
+
}
|
|
97
|
+
}));
|
|
98
|
+
}
|
|
99
|
+
);
|
|
100
|
+
// Invia messaggi in coda
|
|
101
|
+
pendingMessages.forEach(msg => ws!.send(JSON.stringify(msg)));
|
|
102
|
+
pendingMessages = [];
|
|
103
|
+
|
|
104
|
+
// Inizializza heartbeat
|
|
105
|
+
heartCheck();
|
|
106
|
+
reconnectAttempts = 0;
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
ws.onmessage = (event) => {
|
|
110
|
+
try {
|
|
111
|
+
const msg: WSMessage = JSON.parse(event.data);
|
|
112
|
+
handleMessage(msg);
|
|
113
|
+
} catch (err) {
|
|
114
|
+
console.error('[Worker] Invalid message', err);
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
ws.onclose = () => {
|
|
119
|
+
heartReset();
|
|
120
|
+
if(!manuallyClosed){
|
|
121
|
+
reconnectAttempts++;
|
|
122
|
+
const delay = Math.min(reconnectAttempts * 1000, maxReconnectDelay);
|
|
123
|
+
console.log('[Worker] WebSocket disconnected, retry in', delay, 'ms');
|
|
124
|
+
setTimeout(connect, delay);
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
ws.onerror = (err) => {
|
|
129
|
+
console.error('[Worker] WebSocket error', err);
|
|
130
|
+
ws?.close();
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function handleMessage(msg: WSMessage) {
|
|
135
|
+
console.log('[Worker] Received message:', msg);
|
|
136
|
+
// --- GESTIONE PING/PONG ---
|
|
137
|
+
if (msg.action === 'heartbeat' && msg.payload?.message?.text === 'ping') {
|
|
138
|
+
console.log('[Worker] Received ping, sending pong');
|
|
139
|
+
if (ws && ws.readyState === WebSocket.OPEN) {
|
|
140
|
+
ws.send(JSON.stringify(pongMsg));
|
|
141
|
+
}
|
|
142
|
+
return; // Non processare ulteriormente il ping
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Solo formato "publish"
|
|
146
|
+
if (msg.action !== "publish") return;
|
|
147
|
+
|
|
148
|
+
const topic = msg.payload?.topic;
|
|
149
|
+
const method = msg.payload?.method;
|
|
150
|
+
const payload = msg.payload?.message;
|
|
151
|
+
|
|
152
|
+
if (!topic) return;
|
|
153
|
+
|
|
154
|
+
// --- GESTIONE ARRAY DI MESSAGGI ---
|
|
155
|
+
const messages = Array.isArray(msg.payload.message) ? msg.payload.message : [msg.payload.message];
|
|
156
|
+
// Notifica solo le subscription che matchano
|
|
157
|
+
subscriptions.forEach(sub => {
|
|
158
|
+
if (sub.topic === topic) {
|
|
159
|
+
messages.forEach(element => {
|
|
160
|
+
postMessage({
|
|
161
|
+
topic,
|
|
162
|
+
method,
|
|
163
|
+
payload: element, // singolo elemento
|
|
164
|
+
data: msg // payload completo per eventuali onData globali
|
|
165
|
+
}, undefined);
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
function sendMessage(message: any) {
|
|
173
|
+
if (ws && ws.readyState === WebSocket.OPEN) {
|
|
174
|
+
ws.send(JSON.stringify(message));
|
|
175
|
+
} else {
|
|
176
|
+
pendingMessages.push(message);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
// -----------------------------------------------------------------------------------------------------
|
|
182
|
+
// @ HeartCheck
|
|
183
|
+
// -----------------------------------------------------------------------------------------------------
|
|
184
|
+
function heartCheck() {
|
|
185
|
+
heartReset();
|
|
186
|
+
heartStart();
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// -----------------------------------------------------------------------------------------------------
|
|
190
|
+
// @ HeartStart
|
|
191
|
+
// -----------------------------------------------------------------------------------------------------
|
|
192
|
+
function heartStart() {
|
|
193
|
+
// this.getRemainingTime();
|
|
194
|
+
|
|
195
|
+
// usa intervallo adattivo se tab è in background (Chrome throtla i timer)
|
|
196
|
+
const adaptivePing = pageHidden ? pingTimeout * 3 : pingTimeout;
|
|
197
|
+
|
|
198
|
+
// // pianifica invio ping
|
|
199
|
+
pingTimeoutId = setTimeout(() => {
|
|
200
|
+
if (!ws || ws.readyState !== WebSocket.OPEN) return;
|
|
201
|
+
console.log("[WEBSOCKET-JS] - HEART-START - SENDING PING ");
|
|
202
|
+
|
|
203
|
+
// Qui viene inviato un battito cardiaco. Dopo averlo ricevuto, viene restituito un messaggio di battito cardiaco.
|
|
204
|
+
// onmessage Ottieni il battito cardiaco restituito per indicare che la connessione è normale
|
|
205
|
+
ws.send(JSON.stringify(pingMsg));
|
|
206
|
+
|
|
207
|
+
// Se non viene ripristinato dopo un determinato periodo di tempo, il backend viene attivamente disconnesso
|
|
208
|
+
pongTimeoutId = setTimeout(() => {
|
|
209
|
+
console.log("[WEBSOCKET-JS] - HEART-START - PONG-TIMEOUT-ID - CLOSE WS ");
|
|
210
|
+
// se onclose Si esibirà reconnect,Eseguiamo ws.close() Bene, se lo esegui direttamente reconnect Si innescherà onclose Causa riconnessione due volte
|
|
211
|
+
ws.close();
|
|
212
|
+
}, pongTimeout) as unknown as number;
|
|
213
|
+
}, adaptivePing);
|
|
214
|
+
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// -----------------------------------------------------------------------------------------------------
|
|
218
|
+
// @ heartReset
|
|
219
|
+
// -----------------------------------------------------------------------------------------------------
|
|
220
|
+
function heartReset() {
|
|
221
|
+
if (pongTimeoutId !== undefined) {
|
|
222
|
+
clearTimeout(pongTimeoutId);
|
|
223
|
+
pongTimeoutId = undefined;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
if (pingTimeoutId !== undefined) {
|
|
227
|
+
clearTimeout(pingTimeoutId);
|
|
228
|
+
pingTimeoutId = undefined;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
function closeConnection() {
|
|
233
|
+
if (ws) {
|
|
234
|
+
ws.close();
|
|
235
|
+
ws = null;
|
|
236
|
+
}
|
|
237
|
+
heartReset();
|
|
238
|
+
pendingMessages = [];
|
|
239
|
+
subscriptions = [];
|
|
240
|
+
manuallyClosed = true;
|
|
241
|
+
console.log('[Worker] WebSocket closed manually');
|
|
242
|
+
}
|
|
@@ -22,8 +22,9 @@ import { MatTooltipModule } from '@angular/material/tooltip';
|
|
|
22
22
|
import { MatSnackBarModule } from '@angular/material/snack-bar';
|
|
23
23
|
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
|
|
24
24
|
import { SafeHtmlPipe } from '../directives/safe-html.pipe';
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
|
|
26
|
+
import { createTranslateLoader } from 'src/chat21-core/utils/utils';
|
|
27
|
+
import { HttpClient } from '@angular/common/http';
|
|
27
28
|
|
|
28
29
|
@NgModule({
|
|
29
30
|
declarations: [
|
|
@@ -140,6 +141,14 @@ import { SafeHtmlPipe } from '../directives/safe-html.pipe';
|
|
|
140
141
|
NgSelectModule,
|
|
141
142
|
FormsModule,
|
|
142
143
|
|
|
144
|
+
TranslateModule.forChild({
|
|
145
|
+
loader: {
|
|
146
|
+
provide: TranslateLoader,
|
|
147
|
+
useFactory: (createTranslateLoader),
|
|
148
|
+
deps: [HttpClient]
|
|
149
|
+
}
|
|
150
|
+
})
|
|
151
|
+
|
|
143
152
|
],
|
|
144
153
|
schemas: [
|
|
145
154
|
CUSTOM_ELEMENTS_SCHEMA,
|
package/src/app/utils/globals.ts
CHANGED
|
@@ -15,6 +15,7 @@ export class Globals {
|
|
|
15
15
|
jwt: string;
|
|
16
16
|
fileUploadAccept: string;
|
|
17
17
|
projectID: string;
|
|
18
|
+
logOut: boolean
|
|
18
19
|
|
|
19
20
|
constructor(
|
|
20
21
|
) { }
|
|
@@ -36,6 +37,7 @@ export class Globals {
|
|
|
36
37
|
this.lang = 'en'
|
|
37
38
|
this.fileUploadAccept = 'image/*,.pdf,.txt'
|
|
38
39
|
this.projectID = null;
|
|
40
|
+
this.logOut = true;
|
|
39
41
|
|
|
40
42
|
}
|
|
41
43
|
|
|
@@ -0,0 +1,138 @@
|
|
|
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
|
+
HOME_READ: 'home_read',
|
|
8
|
+
|
|
9
|
+
INBOX_READ: 'inbox_read',
|
|
10
|
+
REQUEST_UPDATE: 'request_update',
|
|
11
|
+
REQUEST_SEND: 'request_send',
|
|
12
|
+
REQUEST_CREATE_TICKET: 'request_create_ticket',
|
|
13
|
+
REQUEST_CLOSE: 'request_close',
|
|
14
|
+
REQUEST_JOIN: 'request_join',
|
|
15
|
+
REQUEST_REOPEN: 'request_reopen',
|
|
16
|
+
REQUEST_DELETE: 'request_delete',
|
|
17
|
+
REQUEST_UPDATE_STATUS: 'request_update_status',
|
|
18
|
+
REQUEST_UPDATE_PRIORITY: 'request_update_priority',
|
|
19
|
+
REQUEST_UPDATE_FOLLOWERS: 'request_update_followers',
|
|
20
|
+
REQUEST_UPDATE_SMART_ASSIGNMENT: 'request_update_smart_assignment',
|
|
21
|
+
REQUEST_UPDATE_TAGS: 'request_update_tags',
|
|
22
|
+
REQUEST_UPDATE_NOTES: 'request_update_notes',
|
|
23
|
+
REQUEST_REASSIGN:'request_reassign',
|
|
24
|
+
REQUEST_ADD:'request_add',
|
|
25
|
+
REQUEST_LEFT: 'request_left',
|
|
26
|
+
REQUEST_TRANSCRIPT_SEND: 'request_transcript_send',
|
|
27
|
+
|
|
28
|
+
HISTORY_READ: 'history_read',
|
|
29
|
+
|
|
30
|
+
RATING_READ:'rating_read',
|
|
31
|
+
|
|
32
|
+
AUTOMATIONSLOG_READ: "automationslog_read",
|
|
33
|
+
AUTOMATIONSLOG_CREATE: "automationslog_create",
|
|
34
|
+
|
|
35
|
+
KB_READ: 'kb_read',
|
|
36
|
+
KB_CONTENTS_ADD:'kb_contents_add',
|
|
37
|
+
KB_CONTENT_UPDATE: 'kb_content_update',
|
|
38
|
+
KB_CONTENT_REINDEX: 'kb_content_reindex',
|
|
39
|
+
KB_CONTENT_CHECK_STATUS: 'kb_content_check_status',
|
|
40
|
+
KB_NAMESPACE_ADD:'kb_namespace_add',
|
|
41
|
+
KB_SETTINGS_EDIT:'kb_settings_edit',
|
|
42
|
+
KB_DELETE: 'kb_delete',
|
|
43
|
+
KB_CONTENTS_EXPORT: 'kb_contents_export',
|
|
44
|
+
// KB_NAMESPACE_DELETE:'kb_namespace_delete',
|
|
45
|
+
// KB_CONTENTS_DELETE:'kb_contents_delete',
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
FLOWS_READ: 'flows_read',
|
|
50
|
+
FLOW_ADD: 'flow_add',
|
|
51
|
+
FLOW_EDIT: 'flow_edit',
|
|
52
|
+
FLOW_TEST: 'flow_test',
|
|
53
|
+
FLOW_DUPLICATE: 'flow_duplicate',
|
|
54
|
+
FLOW_DELETE: 'flow_delete',
|
|
55
|
+
FLOW_SHARE: 'flow_share',
|
|
56
|
+
FLOW_EXPORT: 'flow_export',
|
|
57
|
+
FLOW_WEBHOOK_COPY:"flow_webhook_copy",
|
|
58
|
+
FLOW_WEBHOOK_EDIT:"flow_webhook_edit",
|
|
59
|
+
FLOW_WEBHOOK_DELETE:"flow_webhook_delete",
|
|
60
|
+
// FLOW_VIEW_MESSAGE_GRAPH: 'flow_view_message_graph',
|
|
61
|
+
|
|
62
|
+
LEADS_READ: 'leads_read',
|
|
63
|
+
LEAD_UPDATE: 'lead_update',
|
|
64
|
+
LEAD_RESTORE: 'lead_restore',
|
|
65
|
+
LEAD_TRASH: 'lead_trash',
|
|
66
|
+
LEAD_DELETE: 'lead_delete',
|
|
67
|
+
LEADS_EXPORT: 'leads_export',
|
|
68
|
+
LEAD_BAN: 'lead_ban',
|
|
69
|
+
LEAD_UNBAN: 'lead_unban',
|
|
70
|
+
|
|
71
|
+
ANALYTICS_READ: 'analytics_read',
|
|
72
|
+
ACTIVITIES_READ: 'activities_read',
|
|
73
|
+
|
|
74
|
+
WIDGETSETUP_READ: 'widgetsetup_read',
|
|
75
|
+
INSTALLATION_READ: 'installation_read',
|
|
76
|
+
TRANSLATIONS_READ: 'translations_read',
|
|
77
|
+
WIDGETSETUP_UPDATE: 'widgetsetup_update',
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
DEPARTMENTS_LIST_READ: 'department_list_read',
|
|
82
|
+
DEPARTMENT_DETAIL_READ: 'department_detail_read',
|
|
83
|
+
DEPARTMENT_CREATE_READ: 'department_create_read',
|
|
84
|
+
|
|
85
|
+
TEAMMATES_READ: 'teammates_read',
|
|
86
|
+
TEAMMATE_UPDATE: 'teammate_update',
|
|
87
|
+
TEAMMATES_CREATE: 'teammates_create',
|
|
88
|
+
ROLES_READ: 'roles_read',
|
|
89
|
+
GROUPS_READ: 'groups_read',
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
EMAIL_TICKETING_READ:'email_ticketing_read',
|
|
94
|
+
EMAIL_TICKETING_UPDATE:'email_ticketing_update',
|
|
95
|
+
|
|
96
|
+
CANNED_RESPONSES_READ:'canned_responses_read',
|
|
97
|
+
CANNED_RESPONSES_UPDATE:'canned_responses_update',
|
|
98
|
+
CANNED_RESPONSES_CREATE:'canned_responses_create',
|
|
99
|
+
CANNED_RESPONSES_DELETE:'canned_responses_delete',
|
|
100
|
+
|
|
101
|
+
TAGS_READ:'tags_read',
|
|
102
|
+
TAG_CREATE:'tag_create',
|
|
103
|
+
TAG_DELETE:'tag_delete',
|
|
104
|
+
TAG_UPDATE:'tag_update',
|
|
105
|
+
|
|
106
|
+
HOURS_READ: 'hours_read',
|
|
107
|
+
HOURS_UPDATE: 'hours_update',
|
|
108
|
+
HOURS_DELETE: 'hours_delete',
|
|
109
|
+
HOURS_CREATE: 'hours_create',
|
|
110
|
+
|
|
111
|
+
INTEGRATIONS_READ: 'integrations_read',
|
|
112
|
+
INTEGRATIONS_UPDATE: 'integrations_update',
|
|
113
|
+
|
|
114
|
+
APPS_READ:'apps_read',
|
|
115
|
+
APPS_UPDATE:'apps_update',
|
|
116
|
+
|
|
117
|
+
SETTINGS_READ: 'settings_read',
|
|
118
|
+
PROJECTSETTINGS_GENERAL_READ: 'projectsettings_general_read',
|
|
119
|
+
PROJECTSETTINGS_GENERAL_UPDATE: 'projectsettings_general_update',
|
|
120
|
+
PROJECTSETTINGS_SUBSCRIPTION_READ: 'projectsettings_subscription_read',
|
|
121
|
+
PROJECTSETTINGS_DEVELOPER_READ: 'projectsettings_developer_read',
|
|
122
|
+
PROJECTSETTINGS_DEVELOPER_UPDATE: 'projectsettings_developer_update',
|
|
123
|
+
PROJECTSETTINGS_SMARTASSIGNMENT_READ: 'projectsettings_smartassignment_read',
|
|
124
|
+
PROJECTSETTINGS_SMARTASSIGNMENT_UPDATE: 'projectsettings_smartassignment_update',
|
|
125
|
+
PROJECTSETTINGS_NOTIFICATION_READ: 'projectsettings_notification_read',
|
|
126
|
+
PROJECTSETTINGS_SECURITY_READ: 'projectsettings_security_read',
|
|
127
|
+
PROJECTSETTINGS_BANNED_READ: 'projectsettings_banned_read',
|
|
128
|
+
PROJECTSETTINGS_ADVANCED_READ: 'projectsettings_advanced_read',
|
|
129
|
+
|
|
130
|
+
ACCESS_LISTS: 'accessLists',
|
|
131
|
+
PROFILE_PAGES: 'profilePages',
|
|
132
|
+
LEAD_DATA: 'leadData',
|
|
133
|
+
IMPORT_DATA: 'importData',
|
|
134
|
+
MANAGE_TAGS: 'manageTags',
|
|
135
|
+
|
|
136
|
+
CHANGE_PROJECT:'change_project',
|
|
137
|
+
SIMULATE_CONV:'simulate_conv',
|
|
138
|
+
};
|
|
@@ -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
|
}
|
package/src/assets/i18n/ar.json
CHANGED
|
@@ -225,6 +225,10 @@
|
|
|
225
225
|
"admin": "مدير",
|
|
226
226
|
"agent": "وكيل",
|
|
227
227
|
"Conversations": "المحادثات",
|
|
228
|
+
"Monitor": "شاشة",
|
|
229
|
+
"Flows": "التدفّقات",
|
|
230
|
+
"Knowledgebases": "قواعد المعرفة",
|
|
231
|
+
"Whatsappbroadcasts": "نشرات WhatsApp",
|
|
228
232
|
"Apps": "تطبيقات",
|
|
229
233
|
"Analytics": "تحليلات",
|
|
230
234
|
"Activities": "أنشطة",
|
|
@@ -306,5 +310,11 @@
|
|
|
306
310
|
"SEND_EMAIL_SUCCESS_OFFLINE_MESSAGE":"تم إرسال الرسالة أيضًا عبر البريد الإلكتروني 📩"
|
|
307
311
|
},
|
|
308
312
|
"EMOJI_NOT_ELLOWED": "الرموز التعبيرية غير مسموح بها",
|
|
309
|
-
"DOMAIN_NOT_ALLOWED": "يحتوي الرابط على نطاق غير مسموح"
|
|
313
|
+
"DOMAIN_NOT_ALLOWED": "يحتوي الرابط على نطاق غير مسموح",
|
|
314
|
+
"TICKET": {
|
|
315
|
+
"OPEN_TICKET": "افتح تذكرة",
|
|
316
|
+
"DESCRIPTION": "هل تؤكد أنك تريد فتح تذكرة لهذه المحادثة؟",
|
|
317
|
+
"CONFIRM": "تأكيد",
|
|
318
|
+
"CLOSE": "إغلاق"
|
|
319
|
+
}
|
|
310
320
|
}
|
package/src/assets/i18n/az.json
CHANGED
|
@@ -225,6 +225,10 @@
|
|
|
225
225
|
"admin": "Administrator",
|
|
226
226
|
"agent": "Agent",
|
|
227
227
|
"Conversations": "Söhbətlər",
|
|
228
|
+
"Monitor": "Monitor",
|
|
229
|
+
"Flows": "Axınlar",
|
|
230
|
+
"Knowledgebases": "Bilik bazaları",
|
|
231
|
+
"Whatsappbroadcasts": "WhatsApp Yayınları",
|
|
228
232
|
"Apps": "Proqramlar",
|
|
229
233
|
"Analytics": "Analitika",
|
|
230
234
|
"Activities": "Fəaliyyətlər",
|
|
@@ -306,5 +310,11 @@
|
|
|
306
310
|
"SEND_EMAIL_SUCCESS_OFFLINE_MESSAGE":"Mesaj e-poçt vasitəsilə də göndərilib 📩"
|
|
307
311
|
},
|
|
308
312
|
"EMOJI_NOT_ELLOWED": "Emoji icazə verilmir",
|
|
309
|
-
"DOMAIN_NOT_ALLOWED": "URL icazə verilməyən domeni ehtiva edir"
|
|
313
|
+
"DOMAIN_NOT_ALLOWED": "URL icazə verilməyən domeni ehtiva edir",
|
|
314
|
+
"TICKET": {
|
|
315
|
+
"OPEN_TICKET": "Bilet aç",
|
|
316
|
+
"DESCRIPTION": "Bu söhbət üçün bilet açmaq istədiyinizi təsdiqləyirsinizmi?",
|
|
317
|
+
"CONFIRM": "Təsdiqlə",
|
|
318
|
+
"CLOSE": "Bağla"
|
|
319
|
+
}
|
|
310
320
|
}
|
package/src/assets/i18n/de.json
CHANGED
|
@@ -225,6 +225,10 @@
|
|
|
225
225
|
"admin": "Administrator",
|
|
226
226
|
"agent": "Agent",
|
|
227
227
|
"Conversations": "Gespräche",
|
|
228
|
+
"Monitor": "Monitor",
|
|
229
|
+
"Flows": "Flows",
|
|
230
|
+
"Knowledgebases": "Wissensdatenbanken",
|
|
231
|
+
"Whatsappbroadcasts": "WhatsApp-Broadcasts",
|
|
228
232
|
"Apps": "Anwendungen",
|
|
229
233
|
"Analytics": "Analytik",
|
|
230
234
|
"Activities": "Aktivitäten",
|
|
@@ -306,5 +310,11 @@
|
|
|
306
310
|
"SEND_EMAIL_SUCCESS_OFFLINE_MESSAGE":"Nachricht auch per E-Mail gesendet 📩"
|
|
307
311
|
},
|
|
308
312
|
"EMOJI_NOT_ELLOWED": "Emoji nicht erlaubt",
|
|
309
|
-
"DOMAIN_NOT_ALLOWED": "Die URL enthält eine nicht erlaubte Domain"
|
|
313
|
+
"DOMAIN_NOT_ALLOWED": "Die URL enthält eine nicht erlaubte Domain",
|
|
314
|
+
"TICKET": {
|
|
315
|
+
"OPEN_TICKET": "Ticket öffnen",
|
|
316
|
+
"DESCRIPTION": "Bestätigen Sie, dass Sie ein Ticket für dieses Gespräch eröffnen möchten?",
|
|
317
|
+
"CONFIRM": "Bestätigen",
|
|
318
|
+
"CLOSE": "Schließen"
|
|
319
|
+
}
|
|
310
320
|
}
|
package/src/assets/i18n/en.json
CHANGED
|
@@ -225,6 +225,10 @@
|
|
|
225
225
|
"admin": "Administrator",
|
|
226
226
|
"agent": "Agent",
|
|
227
227
|
"Conversations": "Conversations",
|
|
228
|
+
"Monitor":"Monitor",
|
|
229
|
+
"Flows": "Flows",
|
|
230
|
+
"Knowledgebases": "Knowledge Bases",
|
|
231
|
+
"Whatsappbroadcasts": "WhatsApp Broadcasts",
|
|
228
232
|
"Apps": "Apps",
|
|
229
233
|
"Analytics": "Analytics",
|
|
230
234
|
"Activities": "Activities",
|
|
@@ -314,5 +318,11 @@
|
|
|
314
318
|
"HOW_CAN_I_HELP_YOU":"How can i help you?"
|
|
315
319
|
},
|
|
316
320
|
"EMOJI_NOT_ELLOWED":"Emoji not allowed",
|
|
317
|
-
"DOMAIN_NOT_ALLOWED":"URL contains a non-allowed domain"
|
|
321
|
+
"DOMAIN_NOT_ALLOWED":"URL contains a non-allowed domain",
|
|
322
|
+
"TICKET": {
|
|
323
|
+
"OPEN_TICKET": "Open Ticket",
|
|
324
|
+
"DESCRIPTION": "Do you confirm you want to open a ticket for this conversation?",
|
|
325
|
+
"CONFIRM": "Confirm",
|
|
326
|
+
"CLOSE": "Close"
|
|
327
|
+
}
|
|
318
328
|
}
|
package/src/assets/i18n/es.json
CHANGED
|
@@ -225,6 +225,10 @@
|
|
|
225
225
|
"admin": "Administrador",
|
|
226
226
|
"agent": "Agente",
|
|
227
227
|
"Conversations": "Conversaciones",
|
|
228
|
+
"Monitor": "Monitor",
|
|
229
|
+
"Flows": "Flujos",
|
|
230
|
+
"Knowledgebases": "Bases de Conocimiento",
|
|
231
|
+
"Whatsappbroadcasts": "Difusiones de WhatsApp",
|
|
228
232
|
"Apps":"Aplicaciones",
|
|
229
233
|
"Analytics":"Analíticas",
|
|
230
234
|
"Activities": "Actividades",
|
|
@@ -306,5 +310,11 @@
|
|
|
306
310
|
"SEND_EMAIL_SUCCESS_OFFLINE_MESSAGE":"Mensaje también enviado por correo electrónico 📩"
|
|
307
311
|
},
|
|
308
312
|
"EMOJI_NOT_ELLOWED": "Emoji no permitido",
|
|
309
|
-
"DOMAIN_NOT_ALLOWED": "La URL contiene un dominio no permitido"
|
|
313
|
+
"DOMAIN_NOT_ALLOWED": "La URL contiene un dominio no permitido",
|
|
314
|
+
"TICKET": {
|
|
315
|
+
"OPEN_TICKET": "Abrir Ticket",
|
|
316
|
+
"DESCRIPTION": "¿Confirmas que deseas abrir un ticket para esta conversación?",
|
|
317
|
+
"CONFIRM": "Confirmar",
|
|
318
|
+
"CLOSE": "Cerrar"
|
|
319
|
+
}
|
|
310
320
|
}
|
package/src/assets/i18n/fr.json
CHANGED
|
@@ -225,6 +225,10 @@
|
|
|
225
225
|
"admin": "Administrateur",
|
|
226
226
|
"agent": "Agent",
|
|
227
227
|
"Conversations": "Conversations",
|
|
228
|
+
"Monitor": "Moniteur",
|
|
229
|
+
"Flows": "Flux",
|
|
230
|
+
"Knowledgebases": "Bases de Connaissances",
|
|
231
|
+
"Whatsappbroadcasts": "Diffusions WhatsApp",
|
|
228
232
|
"Apps":"Applications",
|
|
229
233
|
"Analytics":"Analytique",
|
|
230
234
|
"Activities": "Activités",
|
|
@@ -306,5 +310,11 @@
|
|
|
306
310
|
"SEND_EMAIL_SUCCESS_OFFLINE_MESSAGE":"Message également envoyé par mail 📩"
|
|
307
311
|
},
|
|
308
312
|
"EMOJI_NOT_ELLOWED": "Emoji non autorisé",
|
|
309
|
-
"DOMAIN_NOT_ALLOWED": "L'URL contient un domaine non autorisé"
|
|
313
|
+
"DOMAIN_NOT_ALLOWED": "L'URL contient un domaine non autorisé",
|
|
314
|
+
"TICKET": {
|
|
315
|
+
"OPEN_TICKET": "Ouvrir un Ticket",
|
|
316
|
+
"DESCRIPTION": "Confirmez-vous vouloir ouvrir un ticket pour cette conversation ?",
|
|
317
|
+
"CONFIRM": "Confirmer",
|
|
318
|
+
"CLOSE": "Fermer"
|
|
319
|
+
}
|
|
310
320
|
}
|
package/src/assets/i18n/it.json
CHANGED
|
@@ -225,6 +225,10 @@
|
|
|
225
225
|
"admin": "Amministratore",
|
|
226
226
|
"agent": "Agente",
|
|
227
227
|
"Conversations": "Conversazioni",
|
|
228
|
+
"Monitor": "Monitor",
|
|
229
|
+
"Flows": "Flussi",
|
|
230
|
+
"Knowledgebases": "Basi di Conoscenza",
|
|
231
|
+
"Whatsappbroadcasts": "Trasmissioni WhatsApp",
|
|
228
232
|
"Apps":"App",
|
|
229
233
|
"Analytics":"Analitica",
|
|
230
234
|
"Activities": "Attività",
|
|
@@ -312,7 +316,13 @@
|
|
|
312
316
|
"NO_SUGGESTIONS_PRESENT":"Nessun suggerimento trovato",
|
|
313
317
|
"INSERT_PROMPT_HERE":"Inserisci un prompt qui",
|
|
314
318
|
"HOW_CAN_I_HELP_YOU":"Come posso aiutarti?"
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
319
|
+
},
|
|
320
|
+
"EMOJI_NOT_ELLOWED": "Emoji non consentite",
|
|
321
|
+
"DOMAIN_NOT_ALLOWED": "L'URL contiene un dominio non consentito",
|
|
322
|
+
"TICKET": {
|
|
323
|
+
"OPEN_TICKET": "Apri Ticket",
|
|
324
|
+
"DESCRIPTION": "Confermi di voler aprire un ticket per questa conversazione?",
|
|
325
|
+
"CONFIRM": "Conferma",
|
|
326
|
+
"CLOSE": "Chiudi"
|
|
327
|
+
}
|
|
318
328
|
}
|
package/src/assets/i18n/kk.json
CHANGED
|
@@ -225,6 +225,10 @@
|
|
|
225
225
|
"admin": "Әкімші",
|
|
226
226
|
"agent": "Агент",
|
|
227
227
|
"Conversations": "Әңгімелер",
|
|
228
|
+
"Monitor": "Монитор",
|
|
229
|
+
"Flows": "Ағындар",
|
|
230
|
+
"Knowledgebases": "Білім базалары",
|
|
231
|
+
"Whatsappbroadcasts": "WhatsApp хабарламалары",
|
|
228
232
|
"Apps": "Қолданбалар",
|
|
229
233
|
"Analytics": "Аналитика",
|
|
230
234
|
"Activities": "Іс-шаралар",
|
|
@@ -306,5 +310,11 @@
|
|
|
306
310
|
"SEND_EMAIL_SUCCESS_OFFLINE_MESSAGE":"Хабарлама электрондық пошта арқылы да жіберілді 📩"
|
|
307
311
|
},
|
|
308
312
|
"EMOJI_NOT_ELLOWED": "Эмодзи рұқсат етілмеген",
|
|
309
|
-
"DOMAIN_NOT_ALLOWED": "URL рұқсат етілмеген доменді қамтиды"
|
|
313
|
+
"DOMAIN_NOT_ALLOWED": "URL рұқсат етілмеген доменді қамтиды",
|
|
314
|
+
"TICKET": {
|
|
315
|
+
"OPEN_TICKET": "Тапсырма ашу",
|
|
316
|
+
"DESCRIPTION": "Осы әңгіме үшін тапсырма ашқыңыз келетінін растайсыз ба?",
|
|
317
|
+
"CONFIRM": "Растау",
|
|
318
|
+
"CLOSE": "Жабу"
|
|
319
|
+
}
|
|
310
320
|
}
|