@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.
@@ -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({ 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();
10
18
 
11
- const form = useForm({
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.post(route('escalated.admin.settings.update'));
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 class="rounded-xl border border-[var(--esc-panel-border)] bg-[var(--esc-panel-surface)] p-6">
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 class="rounded-xl border border-[var(--esc-panel-border)] bg-[var(--esc-panel-surface)] p-6">
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 class="rounded-xl border border-[var(--esc-panel-border)] bg-[var(--esc-panel-surface)] p-6">
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 class="rounded-xl border border-[var(--esc-panel-border)] bg-[var(--esc-panel-surface)] p-6">
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 v-if="form.inbound_email_enabled">
251
- <div>
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 v-if="form.inbound_email_adapter === 'postmark'">
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 v-if="form.inbound_email_adapter === 'ses'">
342
- <div>
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 v-if="form.inbound_email_adapter === 'imap'">
382
- <div>
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 class="rounded-xl border border-[var(--esc-panel-border)] bg-[var(--esc-panel-surface)] p-6">
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 class="rounded-xl border border-[var(--esc-panel-border)] bg-[var(--esc-panel-surface)] p-6">
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 class="rounded-xl border border-[var(--esc-panel-border)] bg-[var(--esc-panel-surface)] p-6">
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 v-if="form.widget_enabled">
600
- <div>
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 class="rounded-xl border border-[var(--esc-panel-border)] bg-[var(--esc-panel-surface)] p-6">
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="form.chat_enabled"
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 class="rounded-xl border border-[var(--esc-panel-border)] bg-[var(--esc-panel-surface)] p-6">
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 class="grid grid-cols-2 gap-4">
837
- <div>
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
  >