@escalated-dev/escalated 0.11.9 → 0.12.0
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/README.md +51 -0
- package/package.json +6 -1
- package/pages.json +7 -3
- package/src/components/ActiveChatsPanel.vue +4 -1
- package/src/components/ChatQueue.vue +4 -1
- package/src/components/GuestEmailCode.vue +58 -0
- package/src/components/PresenceIndicator.vue +25 -4
- package/src/components/QuickFilters.vue +6 -3
- package/src/components/TicketList.vue +8 -5
- package/src/composables/useChat.js +12 -30
- package/src/composables/useGuestVerification.js +48 -0
- package/src/composables/useRealtime.js +102 -146
- package/src/pages/Admin/Settings/DatabaseConnection.vue +3 -3
- package/src/pages/Admin/Settings.vue +240 -70
- package/src/pages/Agent/TicketIndex.vue +3 -1
- package/src/pages/Agent/TicketShow.vue +11 -3
- package/src/pages/Guest/Create.vue +137 -7
- package/src/pages/Guest/Show.vue +6 -0
- package/src/utils/guestRequests.js +27 -0
- package/src/widget/EscalatedWidget.vue +180 -17
|
@@ -2,13 +2,21 @@
|
|
|
2
2
|
import EscalatedLayout from '../../components/EscalatedLayout.vue';
|
|
3
3
|
import PluginSlot from '../../components/PluginSlot.vue';
|
|
4
4
|
import { useForm, usePage } from '@inertiajs/vue3';
|
|
5
|
-
import { computed } from 'vue';
|
|
5
|
+
import { computed, watch } from 'vue';
|
|
6
6
|
import { usePluginExtensions } from '../../composables/usePluginExtensions';
|
|
7
7
|
|
|
8
|
-
const props = defineProps({
|
|
8
|
+
const props = defineProps({
|
|
9
|
+
settings: { type: Object, default: () => ({}) },
|
|
10
|
+
departments: Array,
|
|
11
|
+
supported_settings: { type: Array, default: null },
|
|
12
|
+
update_url: { type: String, default: null },
|
|
13
|
+
});
|
|
14
|
+
const supported = computed(() => (props.supported_settings === null ? null : new Set(props.supported_settings)));
|
|
15
|
+
const supports = (key) => supported.value === null || supported.value.has(key);
|
|
16
|
+
const supportsAny = (keys) => keys.some(supports);
|
|
9
17
|
const page = usePage();
|
|
10
18
|
|
|
11
|
-
const
|
|
19
|
+
const settingsData = () => ({
|
|
12
20
|
guest_tickets_enabled: props.settings.guest_tickets_enabled,
|
|
13
21
|
allow_customer_close: props.settings.allow_customer_close,
|
|
14
22
|
auto_close_resolved_after_days: props.settings.auto_close_resolved_after_days,
|
|
@@ -65,9 +73,31 @@ const form = useForm({
|
|
|
65
73
|
widget_pre_chat_message: props.settings.widget_pre_chat_message ?? '',
|
|
66
74
|
widget_chat_header_text: props.settings.widget_chat_header_text ?? 'Support',
|
|
67
75
|
});
|
|
76
|
+
const form = useForm(settingsData());
|
|
77
|
+
watch(
|
|
78
|
+
[
|
|
79
|
+
() => (props.supported_settings === null ? null : [...props.supported_settings].sort().join(',')),
|
|
80
|
+
() => props.update_url,
|
|
81
|
+
() => page.props.escalated?.broadcasting?.channel_prefix,
|
|
82
|
+
() => page.props.auth?.user?.id,
|
|
83
|
+
],
|
|
84
|
+
() => {
|
|
85
|
+
// Inertia can reuse this page after an account/backend switch. Discard
|
|
86
|
+
// the previous account's pending request, fields and credentials.
|
|
87
|
+
form.cancel();
|
|
88
|
+
form.defaults(settingsData());
|
|
89
|
+
form.reset();
|
|
90
|
+
form.clearErrors();
|
|
91
|
+
form.wasSuccessful = false;
|
|
92
|
+
form.recentlySuccessful = false;
|
|
93
|
+
},
|
|
94
|
+
);
|
|
68
95
|
|
|
69
96
|
const webhookBaseUrl = computed(() => {
|
|
70
|
-
const prefix = page.props.escalated?.prefix || 'support'
|
|
97
|
+
const prefix = (page.props.escalated?.prefix || page.props.escalated?.route_prefix || 'support').replace(
|
|
98
|
+
/^\/+|\/+$/g,
|
|
99
|
+
'',
|
|
100
|
+
);
|
|
71
101
|
const origin = typeof window !== 'undefined' ? window.location.origin : '';
|
|
72
102
|
return `${origin}/${prefix}/inbound`;
|
|
73
103
|
});
|
|
@@ -75,18 +105,30 @@ const webhookBaseUrl = computed(() => {
|
|
|
75
105
|
const { getPageComponents } = usePluginExtensions();
|
|
76
106
|
|
|
77
107
|
function submit() {
|
|
78
|
-
form.
|
|
108
|
+
form.transform((data) => Object.fromEntries(Object.entries(data).filter(([key]) => supports(key)))).post(
|
|
109
|
+
props.update_url || route('escalated.admin.settings.update'),
|
|
110
|
+
);
|
|
79
111
|
}
|
|
80
112
|
</script>
|
|
81
113
|
|
|
82
114
|
<template>
|
|
83
115
|
<EscalatedLayout title="Settings">
|
|
84
116
|
<form class="mx-auto max-w-2xl space-y-6" @submit.prevent="submit">
|
|
117
|
+
<div
|
|
118
|
+
v-if="form.hasErrors"
|
|
119
|
+
role="alert"
|
|
120
|
+
class="rounded-xl border border-red-400/40 p-4 text-sm text-red-500"
|
|
121
|
+
>
|
|
122
|
+
<p v-for="(message, key) in form.errors" :key="key">{{ message }}</p>
|
|
123
|
+
</div>
|
|
85
124
|
<!-- General -->
|
|
86
|
-
<div
|
|
125
|
+
<div
|
|
126
|
+
v-if="supportsAny(['allow_customer_close', 'auto_close_resolved_after_days', 'guest_tickets_enabled'])"
|
|
127
|
+
class="rounded-xl border border-[var(--esc-panel-border)] bg-[var(--esc-panel-surface)] p-6"
|
|
128
|
+
>
|
|
87
129
|
<h3 class="mb-5 text-sm font-semibold text-[var(--esc-panel-text)]">General</h3>
|
|
88
130
|
<div class="space-y-5">
|
|
89
|
-
<label class="flex items-center justify-between">
|
|
131
|
+
<label v-if="supports('guest_tickets_enabled')" class="flex items-center justify-between">
|
|
90
132
|
<div>
|
|
91
133
|
<span class="text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
92
134
|
>Guest Tickets</span
|
|
@@ -112,7 +154,7 @@ function submit() {
|
|
|
112
154
|
</button>
|
|
113
155
|
</label>
|
|
114
156
|
|
|
115
|
-
<label class="flex items-center justify-between">
|
|
157
|
+
<label v-if="supports('allow_customer_close')" class="flex items-center justify-between">
|
|
116
158
|
<div>
|
|
117
159
|
<span class="text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
118
160
|
>Allow Customer Close</span
|
|
@@ -138,7 +180,7 @@ function submit() {
|
|
|
138
180
|
</button>
|
|
139
181
|
</label>
|
|
140
182
|
|
|
141
|
-
<div>
|
|
183
|
+
<div v-if="supports('auto_close_resolved_after_days')">
|
|
142
184
|
<label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
143
185
|
>Auto-close resolved tickets after</label
|
|
144
186
|
>
|
|
@@ -160,10 +202,13 @@ function submit() {
|
|
|
160
202
|
</div>
|
|
161
203
|
|
|
162
204
|
<!-- Limits -->
|
|
163
|
-
<div
|
|
205
|
+
<div
|
|
206
|
+
v-if="supportsAny(['max_attachment_size_kb', 'max_attachments_per_reply'])"
|
|
207
|
+
class="rounded-xl border border-[var(--esc-panel-border)] bg-[var(--esc-panel-surface)] p-6"
|
|
208
|
+
>
|
|
164
209
|
<h3 class="mb-5 text-sm font-semibold text-[var(--esc-panel-text)]">Limits</h3>
|
|
165
210
|
<div class="space-y-5">
|
|
166
|
-
<div>
|
|
211
|
+
<div v-if="supports('max_attachments_per_reply')">
|
|
167
212
|
<label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
168
213
|
>Max attachments per reply</label
|
|
169
214
|
>
|
|
@@ -175,7 +220,7 @@ function submit() {
|
|
|
175
220
|
class="mt-2 w-24 rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface-alt)] px-3 py-2 text-sm text-[var(--esc-panel-text-secondary)] focus:border-[var(--esc-panel-border-input)] focus:outline-none focus:ring-1 focus:ring-[var(--esc-panel-border-input)]"
|
|
176
221
|
/>
|
|
177
222
|
</div>
|
|
178
|
-
<div>
|
|
223
|
+
<div v-if="supports('max_attachment_size_kb')">
|
|
179
224
|
<label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
180
225
|
>Max attachment size</label
|
|
181
226
|
>
|
|
@@ -197,7 +242,10 @@ function submit() {
|
|
|
197
242
|
</div>
|
|
198
243
|
|
|
199
244
|
<!-- Tickets -->
|
|
200
|
-
<div
|
|
245
|
+
<div
|
|
246
|
+
v-if="supports('ticket_reference_prefix')"
|
|
247
|
+
class="rounded-xl border border-[var(--esc-panel-border)] bg-[var(--esc-panel-surface)] p-6"
|
|
248
|
+
>
|
|
201
249
|
<h3 class="mb-5 text-sm font-semibold text-[var(--esc-panel-text)]">Tickets</h3>
|
|
202
250
|
<div class="space-y-5">
|
|
203
251
|
<div>
|
|
@@ -218,10 +266,29 @@ function submit() {
|
|
|
218
266
|
</div>
|
|
219
267
|
|
|
220
268
|
<!-- Inbound Email -->
|
|
221
|
-
<div
|
|
269
|
+
<div
|
|
270
|
+
v-if="
|
|
271
|
+
supportsAny([
|
|
272
|
+
'imap_encryption',
|
|
273
|
+
'imap_host',
|
|
274
|
+
'imap_mailbox',
|
|
275
|
+
'imap_password',
|
|
276
|
+
'imap_port',
|
|
277
|
+
'imap_username',
|
|
278
|
+
'inbound_email_adapter',
|
|
279
|
+
'inbound_email_address',
|
|
280
|
+
'inbound_email_enabled',
|
|
281
|
+
'mailgun_signing_key',
|
|
282
|
+
'postmark_inbound_token',
|
|
283
|
+
'ses_region',
|
|
284
|
+
'ses_topic_arn',
|
|
285
|
+
])
|
|
286
|
+
"
|
|
287
|
+
class="rounded-xl border border-[var(--esc-panel-border)] bg-[var(--esc-panel-surface)] p-6"
|
|
288
|
+
>
|
|
222
289
|
<h3 class="mb-5 text-sm font-semibold text-[var(--esc-panel-text)]">Inbound Email</h3>
|
|
223
290
|
<div class="space-y-5">
|
|
224
|
-
<label class="flex items-center justify-between">
|
|
291
|
+
<label v-if="supports('inbound_email_enabled')" class="flex items-center justify-between">
|
|
225
292
|
<div>
|
|
226
293
|
<span class="text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
227
294
|
>Inbound Email</span
|
|
@@ -247,8 +314,26 @@ function submit() {
|
|
|
247
314
|
</button>
|
|
248
315
|
</label>
|
|
249
316
|
|
|
250
|
-
<template
|
|
251
|
-
|
|
317
|
+
<template
|
|
318
|
+
v-if="
|
|
319
|
+
form.inbound_email_enabled &&
|
|
320
|
+
supportsAny([
|
|
321
|
+
'imap_encryption',
|
|
322
|
+
'imap_host',
|
|
323
|
+
'imap_mailbox',
|
|
324
|
+
'imap_password',
|
|
325
|
+
'imap_port',
|
|
326
|
+
'imap_username',
|
|
327
|
+
'inbound_email_adapter',
|
|
328
|
+
'inbound_email_address',
|
|
329
|
+
'mailgun_signing_key',
|
|
330
|
+
'postmark_inbound_token',
|
|
331
|
+
'ses_region',
|
|
332
|
+
'ses_topic_arn',
|
|
333
|
+
])
|
|
334
|
+
"
|
|
335
|
+
>
|
|
336
|
+
<div v-if="supports('inbound_email_adapter')">
|
|
252
337
|
<label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
253
338
|
>Email Provider</label
|
|
254
339
|
>
|
|
@@ -266,7 +351,7 @@ function submit() {
|
|
|
266
351
|
</select>
|
|
267
352
|
</div>
|
|
268
353
|
|
|
269
|
-
<div>
|
|
354
|
+
<div v-if="supports('inbound_email_address')">
|
|
270
355
|
<label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
271
356
|
>Support Email Address</label
|
|
272
357
|
>
|
|
@@ -282,7 +367,7 @@ function submit() {
|
|
|
282
367
|
</div>
|
|
283
368
|
|
|
284
369
|
<!-- Mailgun -->
|
|
285
|
-
<template v-if="form.inbound_email_adapter === 'mailgun'">
|
|
370
|
+
<template v-if="form.inbound_email_adapter === 'mailgun' && supports('mailgun_signing_key')">
|
|
286
371
|
<div>
|
|
287
372
|
<label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
288
373
|
>Signing Key</label
|
|
@@ -310,7 +395,9 @@ function submit() {
|
|
|
310
395
|
</template>
|
|
311
396
|
|
|
312
397
|
<!-- Postmark -->
|
|
313
|
-
<template
|
|
398
|
+
<template
|
|
399
|
+
v-if="form.inbound_email_adapter === 'postmark' && supports('postmark_inbound_token')"
|
|
400
|
+
>
|
|
314
401
|
<div>
|
|
315
402
|
<label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
316
403
|
>Inbound Token</label
|
|
@@ -338,8 +425,10 @@ function submit() {
|
|
|
338
425
|
</template>
|
|
339
426
|
|
|
340
427
|
<!-- AWS SES -->
|
|
341
|
-
<template
|
|
342
|
-
|
|
428
|
+
<template
|
|
429
|
+
v-if="form.inbound_email_adapter === 'ses' && supportsAny(['ses_region', 'ses_topic_arn'])"
|
|
430
|
+
>
|
|
431
|
+
<div v-if="supports('ses_region')">
|
|
343
432
|
<label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
344
433
|
>Region</label
|
|
345
434
|
>
|
|
@@ -350,7 +439,7 @@ function submit() {
|
|
|
350
439
|
class="mt-2 w-48 rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface-alt)] px-3 py-2 text-sm text-[var(--esc-panel-text-secondary)] focus:border-[var(--esc-panel-border-input)] focus:outline-none focus:ring-1 focus:ring-[var(--esc-panel-border-input)]"
|
|
351
440
|
/>
|
|
352
441
|
</div>
|
|
353
|
-
<div>
|
|
442
|
+
<div v-if="supports('ses_topic_arn')">
|
|
354
443
|
<label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
355
444
|
>Topic ARN</label
|
|
356
445
|
>
|
|
@@ -378,8 +467,20 @@ function submit() {
|
|
|
378
467
|
</template>
|
|
379
468
|
|
|
380
469
|
<!-- IMAP -->
|
|
381
|
-
<template
|
|
382
|
-
|
|
470
|
+
<template
|
|
471
|
+
v-if="
|
|
472
|
+
form.inbound_email_adapter === 'imap' &&
|
|
473
|
+
supportsAny([
|
|
474
|
+
'imap_encryption',
|
|
475
|
+
'imap_host',
|
|
476
|
+
'imap_mailbox',
|
|
477
|
+
'imap_password',
|
|
478
|
+
'imap_port',
|
|
479
|
+
'imap_username',
|
|
480
|
+
])
|
|
481
|
+
"
|
|
482
|
+
>
|
|
483
|
+
<div v-if="supports('imap_host')">
|
|
383
484
|
<label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
384
485
|
>Host</label
|
|
385
486
|
>
|
|
@@ -390,8 +491,8 @@ function submit() {
|
|
|
390
491
|
class="mt-2 w-full max-w-sm rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface-alt)] px-3 py-2 text-sm text-[var(--esc-panel-text-secondary)] focus:border-[var(--esc-panel-border-input)] focus:outline-none focus:ring-1 focus:ring-[var(--esc-panel-border-input)]"
|
|
391
492
|
/>
|
|
392
493
|
</div>
|
|
393
|
-
<div class="flex items-end gap-4">
|
|
394
|
-
<div>
|
|
494
|
+
<div v-if="supportsAny(['imap_encryption', 'imap_port'])" class="flex items-end gap-4">
|
|
495
|
+
<div v-if="supports('imap_port')">
|
|
395
496
|
<label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
396
497
|
>Port</label
|
|
397
498
|
>
|
|
@@ -403,7 +504,7 @@ function submit() {
|
|
|
403
504
|
class="mt-2 w-24 rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface-alt)] px-3 py-2 text-sm text-[var(--esc-panel-text-secondary)] focus:border-[var(--esc-panel-border-input)] focus:outline-none focus:ring-1 focus:ring-[var(--esc-panel-border-input)]"
|
|
404
505
|
/>
|
|
405
506
|
</div>
|
|
406
|
-
<div>
|
|
507
|
+
<div v-if="supports('imap_encryption')">
|
|
407
508
|
<label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
408
509
|
>Encryption</label
|
|
409
510
|
>
|
|
@@ -417,7 +518,7 @@ function submit() {
|
|
|
417
518
|
</select>
|
|
418
519
|
</div>
|
|
419
520
|
</div>
|
|
420
|
-
<div>
|
|
521
|
+
<div v-if="supports('imap_username')">
|
|
421
522
|
<label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
422
523
|
>Username</label
|
|
423
524
|
>
|
|
@@ -427,7 +528,7 @@ function submit() {
|
|
|
427
528
|
class="mt-2 w-full max-w-sm rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface-alt)] px-3 py-2 text-sm text-[var(--esc-panel-text-secondary)] focus:border-[var(--esc-panel-border-input)] focus:outline-none focus:ring-1 focus:ring-[var(--esc-panel-border-input)]"
|
|
428
529
|
/>
|
|
429
530
|
</div>
|
|
430
|
-
<div>
|
|
531
|
+
<div v-if="supports('imap_password')">
|
|
431
532
|
<label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
432
533
|
>Password</label
|
|
433
534
|
>
|
|
@@ -437,7 +538,7 @@ function submit() {
|
|
|
437
538
|
class="mt-2 w-full max-w-sm rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface-alt)] px-3 py-2 text-sm text-[var(--esc-panel-text-secondary)] focus:border-[var(--esc-panel-border-input)] focus:outline-none focus:ring-1 focus:ring-[var(--esc-panel-border-input)]"
|
|
438
539
|
/>
|
|
439
540
|
</div>
|
|
440
|
-
<div>
|
|
541
|
+
<div v-if="supports('imap_mailbox')">
|
|
441
542
|
<label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
442
543
|
>Mailbox</label
|
|
443
544
|
>
|
|
@@ -454,10 +555,15 @@ function submit() {
|
|
|
454
555
|
</div>
|
|
455
556
|
|
|
456
557
|
<!-- Knowledge Base -->
|
|
457
|
-
<div
|
|
558
|
+
<div
|
|
559
|
+
v-if="
|
|
560
|
+
supportsAny(['knowledge_base_enabled', 'knowledge_base_feedback_enabled', 'knowledge_base_public'])
|
|
561
|
+
"
|
|
562
|
+
class="rounded-xl border border-[var(--esc-panel-border)] bg-[var(--esc-panel-surface)] p-6"
|
|
563
|
+
>
|
|
458
564
|
<h3 class="mb-5 text-sm font-semibold text-[var(--esc-panel-text)]">Knowledge Base</h3>
|
|
459
565
|
<div class="space-y-5">
|
|
460
|
-
<label class="flex items-center justify-between">
|
|
566
|
+
<label v-if="supports('knowledge_base_enabled')" class="flex items-center justify-between">
|
|
461
567
|
<div>
|
|
462
568
|
<span class="text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
463
569
|
>Enable Knowledge Base</span
|
|
@@ -482,7 +588,7 @@ function submit() {
|
|
|
482
588
|
/>
|
|
483
589
|
</button>
|
|
484
590
|
</label>
|
|
485
|
-
<label class="flex items-center justify-between">
|
|
591
|
+
<label v-if="supports('knowledge_base_public')" class="flex items-center justify-between">
|
|
486
592
|
<div>
|
|
487
593
|
<span class="text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
488
594
|
>Public Access</span
|
|
@@ -507,7 +613,7 @@ function submit() {
|
|
|
507
613
|
/>
|
|
508
614
|
</button>
|
|
509
615
|
</label>
|
|
510
|
-
<label class="flex items-center justify-between">
|
|
616
|
+
<label v-if="supports('knowledge_base_feedback_enabled')" class="flex items-center justify-between">
|
|
511
617
|
<div>
|
|
512
618
|
<span class="text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
513
619
|
>Article Feedback</span
|
|
@@ -536,7 +642,10 @@ function submit() {
|
|
|
536
642
|
</div>
|
|
537
643
|
|
|
538
644
|
<!-- Branding -->
|
|
539
|
-
<div
|
|
645
|
+
<div
|
|
646
|
+
v-if="supports('show_powered_by')"
|
|
647
|
+
class="rounded-xl border border-[var(--esc-panel-border)] bg-[var(--esc-panel-surface)] p-6"
|
|
648
|
+
>
|
|
540
649
|
<h3 class="mb-5 text-sm font-semibold text-[var(--esc-panel-text)]">Branding</h3>
|
|
541
650
|
<div class="space-y-5">
|
|
542
651
|
<label class="flex items-center justify-between">
|
|
@@ -568,10 +677,21 @@ function submit() {
|
|
|
568
677
|
</div>
|
|
569
678
|
|
|
570
679
|
<!-- Support Widget -->
|
|
571
|
-
<div
|
|
680
|
+
<div
|
|
681
|
+
v-if="
|
|
682
|
+
supportsAny([
|
|
683
|
+
'widget_color',
|
|
684
|
+
'widget_enabled',
|
|
685
|
+
'widget_greeting',
|
|
686
|
+
'widget_position',
|
|
687
|
+
'widget_departments',
|
|
688
|
+
])
|
|
689
|
+
"
|
|
690
|
+
class="rounded-xl border border-[var(--esc-panel-border)] bg-[var(--esc-panel-surface)] p-6"
|
|
691
|
+
>
|
|
572
692
|
<h3 class="mb-5 text-sm font-semibold text-[var(--esc-panel-text)]">Support Widget</h3>
|
|
573
693
|
<div class="space-y-5">
|
|
574
|
-
<label class="flex items-center justify-between">
|
|
694
|
+
<label v-if="supports('widget_enabled')" class="flex items-center justify-between">
|
|
575
695
|
<div>
|
|
576
696
|
<span class="text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
577
697
|
>Enable Widget</span
|
|
@@ -596,8 +716,13 @@ function submit() {
|
|
|
596
716
|
/>
|
|
597
717
|
</button>
|
|
598
718
|
</label>
|
|
599
|
-
<template
|
|
600
|
-
|
|
719
|
+
<template
|
|
720
|
+
v-if="
|
|
721
|
+
form.widget_enabled &&
|
|
722
|
+
supportsAny(['widget_color', 'widget_greeting', 'widget_position', 'widget_departments'])
|
|
723
|
+
"
|
|
724
|
+
>
|
|
725
|
+
<div v-if="supports('widget_color')">
|
|
601
726
|
<label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
602
727
|
>Widget Color</label
|
|
603
728
|
>
|
|
@@ -618,7 +743,7 @@ function submit() {
|
|
|
618
743
|
/>
|
|
619
744
|
</div>
|
|
620
745
|
</div>
|
|
621
|
-
<div>
|
|
746
|
+
<div v-if="supports('widget_position')">
|
|
622
747
|
<label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
623
748
|
>Position</label
|
|
624
749
|
>
|
|
@@ -630,7 +755,7 @@ function submit() {
|
|
|
630
755
|
<option value="bottom-left">Bottom Left</option>
|
|
631
756
|
</select>
|
|
632
757
|
</div>
|
|
633
|
-
<div>
|
|
758
|
+
<div v-if="supports('widget_greeting')">
|
|
634
759
|
<label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
635
760
|
>Greeting Message</label
|
|
636
761
|
>
|
|
@@ -641,7 +766,7 @@ function submit() {
|
|
|
641
766
|
class="mt-2 w-full max-w-sm rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface-alt)] px-3 py-2 text-sm text-[var(--esc-panel-text-secondary)] focus:border-[var(--esc-panel-border-input)] focus:outline-none focus:ring-1 focus:ring-[var(--esc-panel-border-input)]"
|
|
642
767
|
/>
|
|
643
768
|
</div>
|
|
644
|
-
<div v-if="departments?.length">
|
|
769
|
+
<div v-if="supports('widget_departments') && departments?.length">
|
|
645
770
|
<label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
646
771
|
>Departments</label
|
|
647
772
|
>
|
|
@@ -696,10 +821,13 @@ function submit() {
|
|
|
696
821
|
</div>
|
|
697
822
|
|
|
698
823
|
<!-- Live Chat -->
|
|
699
|
-
<div
|
|
824
|
+
<div
|
|
825
|
+
v-if="supportsAny(['chat_enabled', 'chat_sound_notifications'])"
|
|
826
|
+
class="rounded-xl border border-[var(--esc-panel-border)] bg-[var(--esc-panel-surface)] p-6"
|
|
827
|
+
>
|
|
700
828
|
<h3 class="mb-5 text-sm font-semibold text-[var(--esc-panel-text)]">Live Chat</h3>
|
|
701
829
|
<div class="space-y-5">
|
|
702
|
-
<label class="flex items-center justify-between">
|
|
830
|
+
<label v-if="supports('chat_enabled')" class="flex items-center justify-between">
|
|
703
831
|
<div>
|
|
704
832
|
<span class="text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
705
833
|
>Enable Live Chat</span
|
|
@@ -716,7 +844,7 @@ function submit() {
|
|
|
716
844
|
class="h-4 w-4 rounded border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface-alt)] text-[var(--esc-panel-accent)] focus:ring-[var(--esc-panel-accent)]/20"
|
|
717
845
|
/>
|
|
718
846
|
</label>
|
|
719
|
-
<label class="flex items-center justify-between">
|
|
847
|
+
<label v-if="supports('chat_sound_notifications')" class="flex items-center justify-between">
|
|
720
848
|
<div>
|
|
721
849
|
<span class="text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
722
850
|
>Sound Notifications</span
|
|
@@ -738,12 +866,23 @@ function submit() {
|
|
|
738
866
|
|
|
739
867
|
<!-- Chat Routing -->
|
|
740
868
|
<div
|
|
741
|
-
v-if="
|
|
869
|
+
v-if="
|
|
870
|
+
form.chat_enabled &&
|
|
871
|
+
supportsAny([
|
|
872
|
+
'chat_auto_close_minutes',
|
|
873
|
+
'chat_concurrent_limit',
|
|
874
|
+
'chat_max_queue',
|
|
875
|
+
'chat_offline_behavior',
|
|
876
|
+
'chat_offline_message',
|
|
877
|
+
'chat_queue_message',
|
|
878
|
+
'chat_routing_strategy',
|
|
879
|
+
])
|
|
880
|
+
"
|
|
742
881
|
class="rounded-xl border border-[var(--esc-panel-border)] bg-[var(--esc-panel-surface)] p-6"
|
|
743
882
|
>
|
|
744
883
|
<h3 class="mb-5 text-sm font-semibold text-[var(--esc-panel-text)]">Chat Routing</h3>
|
|
745
884
|
<div class="space-y-5">
|
|
746
|
-
<div>
|
|
885
|
+
<div v-if="supports('chat_routing_strategy')">
|
|
747
886
|
<label class="mb-1 block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
748
887
|
>Routing Strategy</label
|
|
749
888
|
>
|
|
@@ -756,7 +895,7 @@ function submit() {
|
|
|
756
895
|
<option value="manual">Manual (Queue)</option>
|
|
757
896
|
</select>
|
|
758
897
|
</div>
|
|
759
|
-
<div>
|
|
898
|
+
<div v-if="supports('chat_offline_behavior')">
|
|
760
899
|
<label class="mb-1 block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
761
900
|
>Offline Behavior</label
|
|
762
901
|
>
|
|
@@ -769,8 +908,8 @@ function submit() {
|
|
|
769
908
|
<option value="hide">Hide Chat</option>
|
|
770
909
|
</select>
|
|
771
910
|
</div>
|
|
772
|
-
<div class="grid grid-cols-2 gap-4">
|
|
773
|
-
<div>
|
|
911
|
+
<div v-if="supportsAny(['chat_concurrent_limit', 'chat_max_queue'])" class="grid grid-cols-2 gap-4">
|
|
912
|
+
<div v-if="supports('chat_max_queue')">
|
|
774
913
|
<label class="mb-1 block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
775
914
|
>Max Queue Size</label
|
|
776
915
|
>
|
|
@@ -781,7 +920,7 @@ function submit() {
|
|
|
781
920
|
class="w-full rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface)] px-3 py-2 text-sm text-[var(--esc-panel-text-secondary)]"
|
|
782
921
|
/>
|
|
783
922
|
</div>
|
|
784
|
-
<div>
|
|
923
|
+
<div v-if="supports('chat_concurrent_limit')">
|
|
785
924
|
<label class="mb-1 block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
786
925
|
>Concurrent Limit</label
|
|
787
926
|
>
|
|
@@ -793,7 +932,7 @@ function submit() {
|
|
|
793
932
|
/>
|
|
794
933
|
</div>
|
|
795
934
|
</div>
|
|
796
|
-
<div>
|
|
935
|
+
<div v-if="supports('chat_auto_close_minutes')">
|
|
797
936
|
<label class="mb-1 block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
798
937
|
>Auto-close after (minutes)</label
|
|
799
938
|
>
|
|
@@ -804,7 +943,7 @@ function submit() {
|
|
|
804
943
|
class="w-full rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface)] px-3 py-2 text-sm text-[var(--esc-panel-text-secondary)]"
|
|
805
944
|
/>
|
|
806
945
|
</div>
|
|
807
|
-
<div>
|
|
946
|
+
<div v-if="supports('chat_queue_message')">
|
|
808
947
|
<label class="mb-1 block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
809
948
|
>Queue Message</label
|
|
810
949
|
>
|
|
@@ -815,7 +954,7 @@ function submit() {
|
|
|
815
954
|
class="w-full rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface)] px-3 py-2 text-sm text-[var(--esc-panel-text-secondary)] placeholder-[var(--esc-panel-text-muted)]"
|
|
816
955
|
/>
|
|
817
956
|
</div>
|
|
818
|
-
<div>
|
|
957
|
+
<div v-if="supports('chat_offline_message')">
|
|
819
958
|
<label class="mb-1 block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
820
959
|
>Offline Message</label
|
|
821
960
|
>
|
|
@@ -830,11 +969,42 @@ function submit() {
|
|
|
830
969
|
</div>
|
|
831
970
|
|
|
832
971
|
<!-- Widget Theme -->
|
|
833
|
-
<div
|
|
972
|
+
<div
|
|
973
|
+
v-if="
|
|
974
|
+
supportsAny([
|
|
975
|
+
'widget_agent_bubble_color',
|
|
976
|
+
'widget_background_color',
|
|
977
|
+
'widget_border_radius',
|
|
978
|
+
'widget_chat_header_text',
|
|
979
|
+
'widget_custom_css',
|
|
980
|
+
'widget_customer_bubble_color',
|
|
981
|
+
'widget_font_family',
|
|
982
|
+
'widget_header_background',
|
|
983
|
+
'widget_launcher_size',
|
|
984
|
+
'widget_pre_chat_message',
|
|
985
|
+
'widget_primary_color',
|
|
986
|
+
'widget_show_branding',
|
|
987
|
+
'widget_text_color',
|
|
988
|
+
])
|
|
989
|
+
"
|
|
990
|
+
class="rounded-xl border border-[var(--esc-panel-border)] bg-[var(--esc-panel-surface)] p-6"
|
|
991
|
+
>
|
|
834
992
|
<h3 class="mb-5 text-sm font-semibold text-[var(--esc-panel-text)]">Widget Theme</h3>
|
|
835
993
|
<div class="space-y-5">
|
|
836
|
-
<div
|
|
837
|
-
|
|
994
|
+
<div
|
|
995
|
+
v-if="
|
|
996
|
+
supportsAny([
|
|
997
|
+
'widget_agent_bubble_color',
|
|
998
|
+
'widget_background_color',
|
|
999
|
+
'widget_customer_bubble_color',
|
|
1000
|
+
'widget_header_background',
|
|
1001
|
+
'widget_primary_color',
|
|
1002
|
+
'widget_text_color',
|
|
1003
|
+
])
|
|
1004
|
+
"
|
|
1005
|
+
class="grid grid-cols-2 gap-4"
|
|
1006
|
+
>
|
|
1007
|
+
<div v-if="supports('widget_primary_color')">
|
|
838
1008
|
<label class="mb-1 block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
839
1009
|
>Primary Color</label
|
|
840
1010
|
>
|
|
@@ -844,7 +1014,7 @@ function submit() {
|
|
|
844
1014
|
class="h-10 w-full cursor-pointer rounded-lg border border-[var(--esc-panel-border-input)]"
|
|
845
1015
|
/>
|
|
846
1016
|
</div>
|
|
847
|
-
<div>
|
|
1017
|
+
<div v-if="supports('widget_header_background')">
|
|
848
1018
|
<label class="mb-1 block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
849
1019
|
>Header Background</label
|
|
850
1020
|
>
|
|
@@ -854,7 +1024,7 @@ function submit() {
|
|
|
854
1024
|
class="h-10 w-full cursor-pointer rounded-lg border border-[var(--esc-panel-border-input)]"
|
|
855
1025
|
/>
|
|
856
1026
|
</div>
|
|
857
|
-
<div>
|
|
1027
|
+
<div v-if="supports('widget_agent_bubble_color')">
|
|
858
1028
|
<label class="mb-1 block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
859
1029
|
>Agent Bubble Color</label
|
|
860
1030
|
>
|
|
@@ -864,7 +1034,7 @@ function submit() {
|
|
|
864
1034
|
class="h-10 w-full cursor-pointer rounded-lg border border-[var(--esc-panel-border-input)]"
|
|
865
1035
|
/>
|
|
866
1036
|
</div>
|
|
867
|
-
<div>
|
|
1037
|
+
<div v-if="supports('widget_customer_bubble_color')">
|
|
868
1038
|
<label class="mb-1 block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
869
1039
|
>Customer Bubble Color</label
|
|
870
1040
|
>
|
|
@@ -874,7 +1044,7 @@ function submit() {
|
|
|
874
1044
|
class="h-10 w-full cursor-pointer rounded-lg border border-[var(--esc-panel-border-input)]"
|
|
875
1045
|
/>
|
|
876
1046
|
</div>
|
|
877
|
-
<div>
|
|
1047
|
+
<div v-if="supports('widget_background_color')">
|
|
878
1048
|
<label class="mb-1 block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
879
1049
|
>Background Color</label
|
|
880
1050
|
>
|
|
@@ -884,7 +1054,7 @@ function submit() {
|
|
|
884
1054
|
class="h-10 w-full cursor-pointer rounded-lg border border-[var(--esc-panel-border-input)]"
|
|
885
1055
|
/>
|
|
886
1056
|
</div>
|
|
887
|
-
<div>
|
|
1057
|
+
<div v-if="supports('widget_text_color')">
|
|
888
1058
|
<label class="mb-1 block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
889
1059
|
>Text Color</label
|
|
890
1060
|
>
|
|
@@ -895,7 +1065,7 @@ function submit() {
|
|
|
895
1065
|
/>
|
|
896
1066
|
</div>
|
|
897
1067
|
</div>
|
|
898
|
-
<div>
|
|
1068
|
+
<div v-if="supports('widget_font_family')">
|
|
899
1069
|
<label class="mb-1 block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
900
1070
|
>Font Family</label
|
|
901
1071
|
>
|
|
@@ -912,7 +1082,7 @@ function submit() {
|
|
|
912
1082
|
<option value="Nunito">Nunito</option>
|
|
913
1083
|
</select>
|
|
914
1084
|
</div>
|
|
915
|
-
<div>
|
|
1085
|
+
<div v-if="supports('widget_border_radius')">
|
|
916
1086
|
<label class="mb-1 block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
917
1087
|
>Border Radius ({{ form.widget_border_radius }}px)</label
|
|
918
1088
|
>
|
|
@@ -924,7 +1094,7 @@ function submit() {
|
|
|
924
1094
|
class="w-full"
|
|
925
1095
|
/>
|
|
926
1096
|
</div>
|
|
927
|
-
<div>
|
|
1097
|
+
<div v-if="supports('widget_launcher_size')">
|
|
928
1098
|
<label class="mb-1 block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
929
1099
|
>Launcher Size</label
|
|
930
1100
|
>
|
|
@@ -946,7 +1116,7 @@ function submit() {
|
|
|
946
1116
|
</label>
|
|
947
1117
|
</div>
|
|
948
1118
|
</div>
|
|
949
|
-
<label class="flex items-center justify-between">
|
|
1119
|
+
<label v-if="supports('widget_show_branding')" class="flex items-center justify-between">
|
|
950
1120
|
<span class="text-sm font-medium text-[var(--esc-panel-text-secondary)]">Show Branding</span>
|
|
951
1121
|
<input
|
|
952
1122
|
v-model="form.widget_show_branding"
|
|
@@ -956,7 +1126,7 @@ function submit() {
|
|
|
956
1126
|
class="h-4 w-4 rounded border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface-alt)] text-[var(--esc-panel-accent)] focus:ring-[var(--esc-panel-accent)]/20"
|
|
957
1127
|
/>
|
|
958
1128
|
</label>
|
|
959
|
-
<div>
|
|
1129
|
+
<div v-if="supports('widget_pre_chat_message')">
|
|
960
1130
|
<label class="mb-1 block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
961
1131
|
>Pre-chat Message</label
|
|
962
1132
|
>
|
|
@@ -966,7 +1136,7 @@ function submit() {
|
|
|
966
1136
|
class="w-full rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface)] px-3 py-2 text-sm text-[var(--esc-panel-text-secondary)] placeholder-[var(--esc-panel-text-muted)]"
|
|
967
1137
|
/>
|
|
968
1138
|
</div>
|
|
969
|
-
<div>
|
|
1139
|
+
<div v-if="supports('widget_chat_header_text')">
|
|
970
1140
|
<label class="mb-1 block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
971
1141
|
>Chat Header Text</label
|
|
972
1142
|
>
|
|
@@ -976,7 +1146,7 @@ function submit() {
|
|
|
976
1146
|
class="w-full rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface)] px-3 py-2 text-sm text-[var(--esc-panel-text-secondary)] placeholder-[var(--esc-panel-text-muted)]"
|
|
977
1147
|
/>
|
|
978
1148
|
</div>
|
|
979
|
-
<div>
|
|
1149
|
+
<div v-if="supports('widget_custom_css')">
|
|
980
1150
|
<label class="mb-1 block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
981
1151
|
>Custom CSS</label
|
|
982
1152
|
>
|