@escalated-dev/escalated 0.11.10 → 0.12.1

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.
@@ -2,13 +2,23 @@
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({ settings: Object, departments: Array });
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();
18
+ // Absolute, so the snippet also works when pasted into another site.
19
+ const siteOrigin = typeof window === 'undefined' ? '' : window.location.origin;
10
20
 
11
- const form = useForm({
21
+ const settingsData = () => ({
12
22
  guest_tickets_enabled: props.settings.guest_tickets_enabled,
13
23
  allow_customer_close: props.settings.allow_customer_close,
14
24
  auto_close_resolved_after_days: props.settings.auto_close_resolved_after_days,
@@ -34,6 +44,7 @@ const form = useForm({
34
44
  widget_position: props.settings.widget_position ?? 'bottom-right',
35
45
  widget_greeting: props.settings.widget_greeting ?? 'Hi there! How can we help?',
36
46
  widget_departments: props.settings.widget_departments ?? '',
47
+ widget_allowed_origins: props.settings.widget_allowed_origins ?? '',
37
48
  knowledge_base_enabled: props.settings.knowledge_base_enabled ?? true,
38
49
  knowledge_base_public: props.settings.knowledge_base_public ?? true,
39
50
  knowledge_base_feedback_enabled: props.settings.knowledge_base_feedback_enabled ?? true,
@@ -65,9 +76,31 @@ const form = useForm({
65
76
  widget_pre_chat_message: props.settings.widget_pre_chat_message ?? '',
66
77
  widget_chat_header_text: props.settings.widget_chat_header_text ?? 'Support',
67
78
  });
79
+ const form = useForm(settingsData());
80
+ watch(
81
+ [
82
+ () => (props.supported_settings === null ? null : [...props.supported_settings].sort().join(',')),
83
+ () => props.update_url,
84
+ () => page.props.escalated?.broadcasting?.channel_prefix,
85
+ () => page.props.auth?.user?.id,
86
+ ],
87
+ () => {
88
+ // Inertia can reuse this page after an account/backend switch. Discard
89
+ // the previous account's pending request, fields and credentials.
90
+ form.cancel();
91
+ form.defaults(settingsData());
92
+ form.reset();
93
+ form.clearErrors();
94
+ form.wasSuccessful = false;
95
+ form.recentlySuccessful = false;
96
+ },
97
+ );
68
98
 
69
99
  const webhookBaseUrl = computed(() => {
70
- const prefix = page.props.escalated?.prefix || 'support';
100
+ const prefix = (page.props.escalated?.prefix || page.props.escalated?.route_prefix || 'support').replace(
101
+ /^\/+|\/+$/g,
102
+ '',
103
+ );
71
104
  const origin = typeof window !== 'undefined' ? window.location.origin : '';
72
105
  return `${origin}/${prefix}/inbound`;
73
106
  });
@@ -75,18 +108,30 @@ const webhookBaseUrl = computed(() => {
75
108
  const { getPageComponents } = usePluginExtensions();
76
109
 
77
110
  function submit() {
78
- form.post(route('escalated.admin.settings.update'));
111
+ form.transform((data) => Object.fromEntries(Object.entries(data).filter(([key]) => supports(key)))).post(
112
+ props.update_url || route('escalated.admin.settings.update'),
113
+ );
79
114
  }
80
115
  </script>
81
116
 
82
117
  <template>
83
118
  <EscalatedLayout title="Settings">
84
119
  <form class="mx-auto max-w-2xl space-y-6" @submit.prevent="submit">
120
+ <div
121
+ v-if="form.hasErrors"
122
+ role="alert"
123
+ class="rounded-xl border border-red-400/40 p-4 text-sm text-red-500"
124
+ >
125
+ <p v-for="(message, key) in form.errors" :key="key">{{ message }}</p>
126
+ </div>
85
127
  <!-- General -->
86
- <div class="rounded-xl border border-[var(--esc-panel-border)] bg-[var(--esc-panel-surface)] p-6">
128
+ <div
129
+ v-if="supportsAny(['allow_customer_close', 'auto_close_resolved_after_days', 'guest_tickets_enabled'])"
130
+ class="rounded-xl border border-[var(--esc-panel-border)] bg-[var(--esc-panel-surface)] p-6"
131
+ >
87
132
  <h3 class="mb-5 text-sm font-semibold text-[var(--esc-panel-text)]">General</h3>
88
133
  <div class="space-y-5">
89
- <label class="flex items-center justify-between">
134
+ <label v-if="supports('guest_tickets_enabled')" class="flex items-center justify-between">
90
135
  <div>
91
136
  <span class="text-sm font-medium text-[var(--esc-panel-text-secondary)]"
92
137
  >Guest Tickets</span
@@ -112,7 +157,7 @@ function submit() {
112
157
  </button>
113
158
  </label>
114
159
 
115
- <label class="flex items-center justify-between">
160
+ <label v-if="supports('allow_customer_close')" class="flex items-center justify-between">
116
161
  <div>
117
162
  <span class="text-sm font-medium text-[var(--esc-panel-text-secondary)]"
118
163
  >Allow Customer Close</span
@@ -138,7 +183,7 @@ function submit() {
138
183
  </button>
139
184
  </label>
140
185
 
141
- <div>
186
+ <div v-if="supports('auto_close_resolved_after_days')">
142
187
  <label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
143
188
  >Auto-close resolved tickets after</label
144
189
  >
@@ -160,10 +205,13 @@ function submit() {
160
205
  </div>
161
206
 
162
207
  <!-- Limits -->
163
- <div class="rounded-xl border border-[var(--esc-panel-border)] bg-[var(--esc-panel-surface)] p-6">
208
+ <div
209
+ v-if="supportsAny(['max_attachment_size_kb', 'max_attachments_per_reply'])"
210
+ class="rounded-xl border border-[var(--esc-panel-border)] bg-[var(--esc-panel-surface)] p-6"
211
+ >
164
212
  <h3 class="mb-5 text-sm font-semibold text-[var(--esc-panel-text)]">Limits</h3>
165
213
  <div class="space-y-5">
166
- <div>
214
+ <div v-if="supports('max_attachments_per_reply')">
167
215
  <label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
168
216
  >Max attachments per reply</label
169
217
  >
@@ -175,7 +223,7 @@ function submit() {
175
223
  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
224
  />
177
225
  </div>
178
- <div>
226
+ <div v-if="supports('max_attachment_size_kb')">
179
227
  <label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
180
228
  >Max attachment size</label
181
229
  >
@@ -197,7 +245,10 @@ function submit() {
197
245
  </div>
198
246
 
199
247
  <!-- Tickets -->
200
- <div class="rounded-xl border border-[var(--esc-panel-border)] bg-[var(--esc-panel-surface)] p-6">
248
+ <div
249
+ v-if="supports('ticket_reference_prefix')"
250
+ class="rounded-xl border border-[var(--esc-panel-border)] bg-[var(--esc-panel-surface)] p-6"
251
+ >
201
252
  <h3 class="mb-5 text-sm font-semibold text-[var(--esc-panel-text)]">Tickets</h3>
202
253
  <div class="space-y-5">
203
254
  <div>
@@ -218,10 +269,29 @@ function submit() {
218
269
  </div>
219
270
 
220
271
  <!-- Inbound Email -->
221
- <div class="rounded-xl border border-[var(--esc-panel-border)] bg-[var(--esc-panel-surface)] p-6">
272
+ <div
273
+ v-if="
274
+ supportsAny([
275
+ 'imap_encryption',
276
+ 'imap_host',
277
+ 'imap_mailbox',
278
+ 'imap_password',
279
+ 'imap_port',
280
+ 'imap_username',
281
+ 'inbound_email_adapter',
282
+ 'inbound_email_address',
283
+ 'inbound_email_enabled',
284
+ 'mailgun_signing_key',
285
+ 'postmark_inbound_token',
286
+ 'ses_region',
287
+ 'ses_topic_arn',
288
+ ])
289
+ "
290
+ class="rounded-xl border border-[var(--esc-panel-border)] bg-[var(--esc-panel-surface)] p-6"
291
+ >
222
292
  <h3 class="mb-5 text-sm font-semibold text-[var(--esc-panel-text)]">Inbound Email</h3>
223
293
  <div class="space-y-5">
224
- <label class="flex items-center justify-between">
294
+ <label v-if="supports('inbound_email_enabled')" class="flex items-center justify-between">
225
295
  <div>
226
296
  <span class="text-sm font-medium text-[var(--esc-panel-text-secondary)]"
227
297
  >Inbound Email</span
@@ -247,8 +317,26 @@ function submit() {
247
317
  </button>
248
318
  </label>
249
319
 
250
- <template v-if="form.inbound_email_enabled">
251
- <div>
320
+ <template
321
+ v-if="
322
+ form.inbound_email_enabled &&
323
+ supportsAny([
324
+ 'imap_encryption',
325
+ 'imap_host',
326
+ 'imap_mailbox',
327
+ 'imap_password',
328
+ 'imap_port',
329
+ 'imap_username',
330
+ 'inbound_email_adapter',
331
+ 'inbound_email_address',
332
+ 'mailgun_signing_key',
333
+ 'postmark_inbound_token',
334
+ 'ses_region',
335
+ 'ses_topic_arn',
336
+ ])
337
+ "
338
+ >
339
+ <div v-if="supports('inbound_email_adapter')">
252
340
  <label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
253
341
  >Email Provider</label
254
342
  >
@@ -266,7 +354,7 @@ function submit() {
266
354
  </select>
267
355
  </div>
268
356
 
269
- <div>
357
+ <div v-if="supports('inbound_email_address')">
270
358
  <label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
271
359
  >Support Email Address</label
272
360
  >
@@ -282,7 +370,7 @@ function submit() {
282
370
  </div>
283
371
 
284
372
  <!-- Mailgun -->
285
- <template v-if="form.inbound_email_adapter === 'mailgun'">
373
+ <template v-if="form.inbound_email_adapter === 'mailgun' && supports('mailgun_signing_key')">
286
374
  <div>
287
375
  <label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
288
376
  >Signing Key</label
@@ -310,7 +398,9 @@ function submit() {
310
398
  </template>
311
399
 
312
400
  <!-- Postmark -->
313
- <template v-if="form.inbound_email_adapter === 'postmark'">
401
+ <template
402
+ v-if="form.inbound_email_adapter === 'postmark' && supports('postmark_inbound_token')"
403
+ >
314
404
  <div>
315
405
  <label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
316
406
  >Inbound Token</label
@@ -338,8 +428,10 @@ function submit() {
338
428
  </template>
339
429
 
340
430
  <!-- AWS SES -->
341
- <template v-if="form.inbound_email_adapter === 'ses'">
342
- <div>
431
+ <template
432
+ v-if="form.inbound_email_adapter === 'ses' && supportsAny(['ses_region', 'ses_topic_arn'])"
433
+ >
434
+ <div v-if="supports('ses_region')">
343
435
  <label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
344
436
  >Region</label
345
437
  >
@@ -350,7 +442,7 @@ function submit() {
350
442
  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
443
  />
352
444
  </div>
353
- <div>
445
+ <div v-if="supports('ses_topic_arn')">
354
446
  <label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
355
447
  >Topic ARN</label
356
448
  >
@@ -378,8 +470,20 @@ function submit() {
378
470
  </template>
379
471
 
380
472
  <!-- IMAP -->
381
- <template v-if="form.inbound_email_adapter === 'imap'">
382
- <div>
473
+ <template
474
+ v-if="
475
+ form.inbound_email_adapter === 'imap' &&
476
+ supportsAny([
477
+ 'imap_encryption',
478
+ 'imap_host',
479
+ 'imap_mailbox',
480
+ 'imap_password',
481
+ 'imap_port',
482
+ 'imap_username',
483
+ ])
484
+ "
485
+ >
486
+ <div v-if="supports('imap_host')">
383
487
  <label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
384
488
  >Host</label
385
489
  >
@@ -390,8 +494,8 @@ function submit() {
390
494
  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
495
  />
392
496
  </div>
393
- <div class="flex items-end gap-4">
394
- <div>
497
+ <div v-if="supportsAny(['imap_encryption', 'imap_port'])" class="flex items-end gap-4">
498
+ <div v-if="supports('imap_port')">
395
499
  <label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
396
500
  >Port</label
397
501
  >
@@ -403,7 +507,7 @@ function submit() {
403
507
  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
508
  />
405
509
  </div>
406
- <div>
510
+ <div v-if="supports('imap_encryption')">
407
511
  <label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
408
512
  >Encryption</label
409
513
  >
@@ -417,7 +521,7 @@ function submit() {
417
521
  </select>
418
522
  </div>
419
523
  </div>
420
- <div>
524
+ <div v-if="supports('imap_username')">
421
525
  <label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
422
526
  >Username</label
423
527
  >
@@ -427,7 +531,7 @@ function submit() {
427
531
  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
532
  />
429
533
  </div>
430
- <div>
534
+ <div v-if="supports('imap_password')">
431
535
  <label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
432
536
  >Password</label
433
537
  >
@@ -437,7 +541,7 @@ function submit() {
437
541
  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
542
  />
439
543
  </div>
440
- <div>
544
+ <div v-if="supports('imap_mailbox')">
441
545
  <label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
442
546
  >Mailbox</label
443
547
  >
@@ -454,10 +558,15 @@ function submit() {
454
558
  </div>
455
559
 
456
560
  <!-- Knowledge Base -->
457
- <div class="rounded-xl border border-[var(--esc-panel-border)] bg-[var(--esc-panel-surface)] p-6">
561
+ <div
562
+ v-if="
563
+ supportsAny(['knowledge_base_enabled', 'knowledge_base_feedback_enabled', 'knowledge_base_public'])
564
+ "
565
+ class="rounded-xl border border-[var(--esc-panel-border)] bg-[var(--esc-panel-surface)] p-6"
566
+ >
458
567
  <h3 class="mb-5 text-sm font-semibold text-[var(--esc-panel-text)]">Knowledge Base</h3>
459
568
  <div class="space-y-5">
460
- <label class="flex items-center justify-between">
569
+ <label v-if="supports('knowledge_base_enabled')" class="flex items-center justify-between">
461
570
  <div>
462
571
  <span class="text-sm font-medium text-[var(--esc-panel-text-secondary)]"
463
572
  >Enable Knowledge Base</span
@@ -482,7 +591,7 @@ function submit() {
482
591
  />
483
592
  </button>
484
593
  </label>
485
- <label class="flex items-center justify-between">
594
+ <label v-if="supports('knowledge_base_public')" class="flex items-center justify-between">
486
595
  <div>
487
596
  <span class="text-sm font-medium text-[var(--esc-panel-text-secondary)]"
488
597
  >Public Access</span
@@ -507,7 +616,7 @@ function submit() {
507
616
  />
508
617
  </button>
509
618
  </label>
510
- <label class="flex items-center justify-between">
619
+ <label v-if="supports('knowledge_base_feedback_enabled')" class="flex items-center justify-between">
511
620
  <div>
512
621
  <span class="text-sm font-medium text-[var(--esc-panel-text-secondary)]"
513
622
  >Article Feedback</span
@@ -536,7 +645,10 @@ function submit() {
536
645
  </div>
537
646
 
538
647
  <!-- Branding -->
539
- <div class="rounded-xl border border-[var(--esc-panel-border)] bg-[var(--esc-panel-surface)] p-6">
648
+ <div
649
+ v-if="supports('show_powered_by')"
650
+ class="rounded-xl border border-[var(--esc-panel-border)] bg-[var(--esc-panel-surface)] p-6"
651
+ >
540
652
  <h3 class="mb-5 text-sm font-semibold text-[var(--esc-panel-text)]">Branding</h3>
541
653
  <div class="space-y-5">
542
654
  <label class="flex items-center justify-between">
@@ -568,10 +680,22 @@ function submit() {
568
680
  </div>
569
681
 
570
682
  <!-- Support Widget -->
571
- <div class="rounded-xl border border-[var(--esc-panel-border)] bg-[var(--esc-panel-surface)] p-6">
683
+ <div
684
+ v-if="
685
+ supportsAny([
686
+ 'widget_color',
687
+ 'widget_enabled',
688
+ 'widget_greeting',
689
+ 'widget_position',
690
+ 'widget_departments',
691
+ 'widget_allowed_origins',
692
+ ])
693
+ "
694
+ class="rounded-xl border border-[var(--esc-panel-border)] bg-[var(--esc-panel-surface)] p-6"
695
+ >
572
696
  <h3 class="mb-5 text-sm font-semibold text-[var(--esc-panel-text)]">Support Widget</h3>
573
697
  <div class="space-y-5">
574
- <label class="flex items-center justify-between">
698
+ <label v-if="supports('widget_enabled')" class="flex items-center justify-between">
575
699
  <div>
576
700
  <span class="text-sm font-medium text-[var(--esc-panel-text-secondary)]"
577
701
  >Enable Widget</span
@@ -596,8 +720,19 @@ function submit() {
596
720
  />
597
721
  </button>
598
722
  </label>
599
- <template v-if="form.widget_enabled">
600
- <div>
723
+ <template
724
+ v-if="
725
+ form.widget_enabled &&
726
+ supportsAny([
727
+ 'widget_color',
728
+ 'widget_greeting',
729
+ 'widget_position',
730
+ 'widget_departments',
731
+ 'widget_allowed_origins',
732
+ ])
733
+ "
734
+ >
735
+ <div v-if="supports('widget_color')">
601
736
  <label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
602
737
  >Widget Color</label
603
738
  >
@@ -618,7 +753,7 @@ function submit() {
618
753
  />
619
754
  </div>
620
755
  </div>
621
- <div>
756
+ <div v-if="supports('widget_position')">
622
757
  <label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
623
758
  >Position</label
624
759
  >
@@ -630,7 +765,7 @@ function submit() {
630
765
  <option value="bottom-left">Bottom Left</option>
631
766
  </select>
632
767
  </div>
633
- <div>
768
+ <div v-if="supports('widget_greeting')">
634
769
  <label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
635
770
  >Greeting Message</label
636
771
  >
@@ -641,7 +776,7 @@ function submit() {
641
776
  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
777
  />
643
778
  </div>
644
- <div v-if="departments?.length">
779
+ <div v-if="supports('widget_departments') && departments?.length">
645
780
  <label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
646
781
  >Departments</label
647
782
  >
@@ -674,6 +809,26 @@ function submit() {
674
809
  </label>
675
810
  </div>
676
811
  </div>
812
+ <div v-if="supports('widget_allowed_origins')">
813
+ <label
814
+ for="widget-allowed-origins"
815
+ class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
816
+ >Sites that can embed the widget</label
817
+ >
818
+ <p class="mt-0.5 text-xs text-[var(--esc-panel-text-muted)]">
819
+ One site per line, such as https://shop.example.com. Use https://*.example.com for every
820
+ subdomain. Leave empty to allow this site only.
821
+ </p>
822
+ <textarea
823
+ id="widget-allowed-origins"
824
+ v-model="form.widget_allowed_origins"
825
+ rows="3"
826
+ maxlength="5000"
827
+ spellcheck="false"
828
+ placeholder="https://shop.example.com"
829
+ class="mt-2 w-full max-w-lg rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface-alt)] px-3 py-2 font-mono 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)]"
830
+ ></textarea>
831
+ </div>
677
832
  <div
678
833
  class="rounded-lg border border-[var(--esc-panel-border)] bg-[var(--esc-panel-surface-alt)] p-4"
679
834
  >
@@ -685,8 +840,9 @@ function submit() {
685
840
  </p>
686
841
  <code
687
842
  class="mt-2 block whitespace-pre-wrap break-all rounded-lg bg-[var(--esc-panel-bg)] p-3 text-xs text-[var(--esc-panel-text-tertiary)] select-all"
688
- >&lt;script src="/{{ page.props.escalated?.prefix || 'support' }}/widget/embed.js"
689
- data-color="{{ form.widget_color }}" data-position="{{
843
+ >&lt;script src="{{ siteOrigin }}/{{
844
+ page.props.escalated?.prefix || 'support'
845
+ }}/widget/embed.js" data-color="{{ form.widget_color }}" data-position="{{
690
846
  form.widget_position
691
847
  }}"&gt;&lt;/script&gt;</code
692
848
  >
@@ -696,10 +852,13 @@ function submit() {
696
852
  </div>
697
853
 
698
854
  <!-- Live Chat -->
699
- <div class="rounded-xl border border-[var(--esc-panel-border)] bg-[var(--esc-panel-surface)] p-6">
855
+ <div
856
+ v-if="supportsAny(['chat_enabled', 'chat_sound_notifications'])"
857
+ class="rounded-xl border border-[var(--esc-panel-border)] bg-[var(--esc-panel-surface)] p-6"
858
+ >
700
859
  <h3 class="mb-5 text-sm font-semibold text-[var(--esc-panel-text)]">Live Chat</h3>
701
860
  <div class="space-y-5">
702
- <label class="flex items-center justify-between">
861
+ <label v-if="supports('chat_enabled')" class="flex items-center justify-between">
703
862
  <div>
704
863
  <span class="text-sm font-medium text-[var(--esc-panel-text-secondary)]"
705
864
  >Enable Live Chat</span
@@ -716,7 +875,7 @@ function submit() {
716
875
  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
876
  />
718
877
  </label>
719
- <label class="flex items-center justify-between">
878
+ <label v-if="supports('chat_sound_notifications')" class="flex items-center justify-between">
720
879
  <div>
721
880
  <span class="text-sm font-medium text-[var(--esc-panel-text-secondary)]"
722
881
  >Sound Notifications</span
@@ -738,12 +897,23 @@ function submit() {
738
897
 
739
898
  <!-- Chat Routing -->
740
899
  <div
741
- v-if="form.chat_enabled"
900
+ v-if="
901
+ form.chat_enabled &&
902
+ supportsAny([
903
+ 'chat_auto_close_minutes',
904
+ 'chat_concurrent_limit',
905
+ 'chat_max_queue',
906
+ 'chat_offline_behavior',
907
+ 'chat_offline_message',
908
+ 'chat_queue_message',
909
+ 'chat_routing_strategy',
910
+ ])
911
+ "
742
912
  class="rounded-xl border border-[var(--esc-panel-border)] bg-[var(--esc-panel-surface)] p-6"
743
913
  >
744
914
  <h3 class="mb-5 text-sm font-semibold text-[var(--esc-panel-text)]">Chat Routing</h3>
745
915
  <div class="space-y-5">
746
- <div>
916
+ <div v-if="supports('chat_routing_strategy')">
747
917
  <label class="mb-1 block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
748
918
  >Routing Strategy</label
749
919
  >
@@ -756,7 +926,7 @@ function submit() {
756
926
  <option value="manual">Manual (Queue)</option>
757
927
  </select>
758
928
  </div>
759
- <div>
929
+ <div v-if="supports('chat_offline_behavior')">
760
930
  <label class="mb-1 block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
761
931
  >Offline Behavior</label
762
932
  >
@@ -769,8 +939,8 @@ function submit() {
769
939
  <option value="hide">Hide Chat</option>
770
940
  </select>
771
941
  </div>
772
- <div class="grid grid-cols-2 gap-4">
773
- <div>
942
+ <div v-if="supportsAny(['chat_concurrent_limit', 'chat_max_queue'])" class="grid grid-cols-2 gap-4">
943
+ <div v-if="supports('chat_max_queue')">
774
944
  <label class="mb-1 block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
775
945
  >Max Queue Size</label
776
946
  >
@@ -781,7 +951,7 @@ function submit() {
781
951
  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
952
  />
783
953
  </div>
784
- <div>
954
+ <div v-if="supports('chat_concurrent_limit')">
785
955
  <label class="mb-1 block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
786
956
  >Concurrent Limit</label
787
957
  >
@@ -793,7 +963,7 @@ function submit() {
793
963
  />
794
964
  </div>
795
965
  </div>
796
- <div>
966
+ <div v-if="supports('chat_auto_close_minutes')">
797
967
  <label class="mb-1 block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
798
968
  >Auto-close after (minutes)</label
799
969
  >
@@ -804,7 +974,7 @@ function submit() {
804
974
  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
975
  />
806
976
  </div>
807
- <div>
977
+ <div v-if="supports('chat_queue_message')">
808
978
  <label class="mb-1 block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
809
979
  >Queue Message</label
810
980
  >
@@ -815,7 +985,7 @@ function submit() {
815
985
  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
986
  />
817
987
  </div>
818
- <div>
988
+ <div v-if="supports('chat_offline_message')">
819
989
  <label class="mb-1 block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
820
990
  >Offline Message</label
821
991
  >
@@ -830,11 +1000,42 @@ function submit() {
830
1000
  </div>
831
1001
 
832
1002
  <!-- Widget Theme -->
833
- <div class="rounded-xl border border-[var(--esc-panel-border)] bg-[var(--esc-panel-surface)] p-6">
1003
+ <div
1004
+ v-if="
1005
+ supportsAny([
1006
+ 'widget_agent_bubble_color',
1007
+ 'widget_background_color',
1008
+ 'widget_border_radius',
1009
+ 'widget_chat_header_text',
1010
+ 'widget_custom_css',
1011
+ 'widget_customer_bubble_color',
1012
+ 'widget_font_family',
1013
+ 'widget_header_background',
1014
+ 'widget_launcher_size',
1015
+ 'widget_pre_chat_message',
1016
+ 'widget_primary_color',
1017
+ 'widget_show_branding',
1018
+ 'widget_text_color',
1019
+ ])
1020
+ "
1021
+ class="rounded-xl border border-[var(--esc-panel-border)] bg-[var(--esc-panel-surface)] p-6"
1022
+ >
834
1023
  <h3 class="mb-5 text-sm font-semibold text-[var(--esc-panel-text)]">Widget Theme</h3>
835
1024
  <div class="space-y-5">
836
- <div class="grid grid-cols-2 gap-4">
837
- <div>
1025
+ <div
1026
+ v-if="
1027
+ supportsAny([
1028
+ 'widget_agent_bubble_color',
1029
+ 'widget_background_color',
1030
+ 'widget_customer_bubble_color',
1031
+ 'widget_header_background',
1032
+ 'widget_primary_color',
1033
+ 'widget_text_color',
1034
+ ])
1035
+ "
1036
+ class="grid grid-cols-2 gap-4"
1037
+ >
1038
+ <div v-if="supports('widget_primary_color')">
838
1039
  <label class="mb-1 block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
839
1040
  >Primary Color</label
840
1041
  >
@@ -844,7 +1045,7 @@ function submit() {
844
1045
  class="h-10 w-full cursor-pointer rounded-lg border border-[var(--esc-panel-border-input)]"
845
1046
  />
846
1047
  </div>
847
- <div>
1048
+ <div v-if="supports('widget_header_background')">
848
1049
  <label class="mb-1 block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
849
1050
  >Header Background</label
850
1051
  >
@@ -854,7 +1055,7 @@ function submit() {
854
1055
  class="h-10 w-full cursor-pointer rounded-lg border border-[var(--esc-panel-border-input)]"
855
1056
  />
856
1057
  </div>
857
- <div>
1058
+ <div v-if="supports('widget_agent_bubble_color')">
858
1059
  <label class="mb-1 block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
859
1060
  >Agent Bubble Color</label
860
1061
  >
@@ -864,7 +1065,7 @@ function submit() {
864
1065
  class="h-10 w-full cursor-pointer rounded-lg border border-[var(--esc-panel-border-input)]"
865
1066
  />
866
1067
  </div>
867
- <div>
1068
+ <div v-if="supports('widget_customer_bubble_color')">
868
1069
  <label class="mb-1 block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
869
1070
  >Customer Bubble Color</label
870
1071
  >
@@ -874,7 +1075,7 @@ function submit() {
874
1075
  class="h-10 w-full cursor-pointer rounded-lg border border-[var(--esc-panel-border-input)]"
875
1076
  />
876
1077
  </div>
877
- <div>
1078
+ <div v-if="supports('widget_background_color')">
878
1079
  <label class="mb-1 block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
879
1080
  >Background Color</label
880
1081
  >
@@ -884,7 +1085,7 @@ function submit() {
884
1085
  class="h-10 w-full cursor-pointer rounded-lg border border-[var(--esc-panel-border-input)]"
885
1086
  />
886
1087
  </div>
887
- <div>
1088
+ <div v-if="supports('widget_text_color')">
888
1089
  <label class="mb-1 block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
889
1090
  >Text Color</label
890
1091
  >
@@ -895,7 +1096,7 @@ function submit() {
895
1096
  />
896
1097
  </div>
897
1098
  </div>
898
- <div>
1099
+ <div v-if="supports('widget_font_family')">
899
1100
  <label class="mb-1 block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
900
1101
  >Font Family</label
901
1102
  >
@@ -912,7 +1113,7 @@ function submit() {
912
1113
  <option value="Nunito">Nunito</option>
913
1114
  </select>
914
1115
  </div>
915
- <div>
1116
+ <div v-if="supports('widget_border_radius')">
916
1117
  <label class="mb-1 block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
917
1118
  >Border Radius ({{ form.widget_border_radius }}px)</label
918
1119
  >
@@ -924,7 +1125,7 @@ function submit() {
924
1125
  class="w-full"
925
1126
  />
926
1127
  </div>
927
- <div>
1128
+ <div v-if="supports('widget_launcher_size')">
928
1129
  <label class="mb-1 block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
929
1130
  >Launcher Size</label
930
1131
  >
@@ -946,7 +1147,7 @@ function submit() {
946
1147
  </label>
947
1148
  </div>
948
1149
  </div>
949
- <label class="flex items-center justify-between">
1150
+ <label v-if="supports('widget_show_branding')" class="flex items-center justify-between">
950
1151
  <span class="text-sm font-medium text-[var(--esc-panel-text-secondary)]">Show Branding</span>
951
1152
  <input
952
1153
  v-model="form.widget_show_branding"
@@ -956,7 +1157,7 @@ function submit() {
956
1157
  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
1158
  />
958
1159
  </label>
959
- <div>
1160
+ <div v-if="supports('widget_pre_chat_message')">
960
1161
  <label class="mb-1 block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
961
1162
  >Pre-chat Message</label
962
1163
  >
@@ -966,7 +1167,7 @@ function submit() {
966
1167
  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
1168
  />
968
1169
  </div>
969
- <div>
1170
+ <div v-if="supports('widget_chat_header_text')">
970
1171
  <label class="mb-1 block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
971
1172
  >Chat Header Text</label
972
1173
  >
@@ -976,7 +1177,7 @@ function submit() {
976
1177
  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
1178
  />
978
1179
  </div>
979
- <div>
1180
+ <div v-if="supports('widget_custom_css')">
980
1181
  <label class="mb-1 block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
981
1182
  >Custom CSS</label
982
1183
  >