@escalated-dev/escalated 0.7.0 → 0.7.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.
- package/LICENSE +21 -21
- package/README.md +31 -0
- package/package.json +12 -6
- package/src/components/ActiveChatsPanel.vue +246 -0
- package/src/components/ActivityTimeline.stories.js +55 -55
- package/src/components/ActivityTimeline.vue +83 -83
- package/src/components/AdminDashboard.stories.js +1423 -1095
- package/src/components/AgentLoadIndicator.stories.js +37 -37
- package/src/components/AgentLoadIndicator.vue +49 -49
- package/src/components/AgentPerformanceCard.vue +44 -44
- package/src/components/ArticleEditor.vue +82 -82
- package/src/components/AssigneeSelect.vue +37 -37
- package/src/components/AttachmentList.vue +13 -1
- package/src/components/AuditLogEntry.vue +95 -95
- package/src/components/BulkActionBar.vue +166 -166
- package/src/components/CategoryTree.vue +89 -89
- package/src/components/ChartWidget.vue +46 -46
- package/src/components/ChatActionBar.vue +226 -0
- package/src/components/ChatBubble.vue +162 -0
- package/src/components/ChatComposer.vue +308 -0
- package/src/components/ChatQueue.vue +222 -0
- package/src/components/ChatThread.vue +197 -0
- package/src/components/CollisionWarning.stories.js +30 -30
- package/src/components/CollisionWarning.vue +68 -68
- package/src/components/ConditionalFieldRules.vue +135 -135
- package/src/components/ContextPanel.vue +66 -66
- package/src/components/ContextPanelSection.vue +65 -65
- package/src/components/CustomFieldRenderer.vue +159 -159
- package/src/components/EscalatedLayout.vue +29 -6
- package/src/components/FileDropzone.vue +57 -57
- package/src/components/FollowButton.stories.js +30 -30
- package/src/components/FollowButton.vue +88 -88
- package/src/components/KeyboardShortcutHelp.vue +213 -213
- package/src/components/KnowledgePanel.vue +122 -122
- package/src/components/KpiCard.stories.js +32 -32
- package/src/components/KpiCard.vue +88 -88
- package/src/components/MacroDropdown.vue +150 -150
- package/src/components/MentionDropdown.vue +154 -0
- package/src/components/MetricComparison.vue +89 -0
- package/src/components/PercentileChart.vue +67 -0
- package/src/components/PeriodSelector.vue +98 -0
- package/src/components/PermissionMatrix.vue +107 -107
- package/src/components/PinnedNotes.vue +129 -129
- package/src/components/PluginSlot.vue +68 -62
- package/src/components/PresenceIndicator.vue +46 -2
- package/src/components/PriorityBadge.stories.js +33 -33
- package/src/components/PriorityBadge.vue +46 -46
- package/src/components/ReplyComposer.vue +81 -18
- package/src/components/ReplyThread.vue +40 -2
- package/src/components/ReportChart.vue +395 -0
- package/src/components/ReportExportButton.vue +108 -0
- package/src/components/SatisfactionRating.vue +180 -180
- package/src/components/SaveViewDialog.vue +172 -0
- package/src/components/SavedViewSidebar.vue +208 -0
- package/src/components/ScheduleEditor.vue +104 -104
- package/src/components/SideConversation.vue +165 -165
- package/src/components/SideConversationList.vue +147 -147
- package/src/components/SkillTagManager.vue +79 -79
- package/src/components/SlaComplianceChart.vue +46 -53
- package/src/components/SlaTimer.stories.js +35 -35
- package/src/components/SlaTimer.vue +62 -62
- package/src/components/SnoozeButton.vue +247 -0
- package/src/components/StatsCard.stories.js +24 -24
- package/src/components/StatsCard.vue +58 -58
- package/src/components/StatusBadge.stories.js +53 -53
- package/src/components/StatusBadge.vue +78 -78
- package/src/components/TagSelect.vue +84 -84
- package/src/components/TicketFilters.vue +270 -225
- package/src/components/TicketLinkPanel.vue +193 -193
- package/src/components/TicketList.vue +655 -594
- package/src/components/TicketMergeDialog.vue +157 -157
- package/src/components/TicketSplitDialog.vue +98 -0
- package/src/components/TotpInput.stories.js +9 -9
- package/src/components/TotpInput.vue +81 -81
- package/src/components/TwoFactorSetup.vue +113 -113
- package/src/components/VariableTokenInput.vue +111 -0
- package/src/components/WorkflowActionConfig.vue +287 -0
- package/src/components/WorkflowActionList.vue +350 -0
- package/src/components/WorkflowConditionBuilder.vue +265 -0
- package/src/components/WorkflowTriggerSelector.vue +125 -0
- package/src/composables/useChat.js +187 -0
- package/src/composables/useI18n.js +80 -80
- package/src/composables/useKeyboardShortcuts.js +46 -46
- package/src/composables/useMentions.js +134 -0
- package/src/composables/usePluginExtensions.js +159 -159
- package/src/composables/usePluginHooks.js +65 -65
- package/src/composables/useRealtime.js +182 -0
- package/src/defineEscalatedPlugin.js +76 -76
- package/src/index.js +84 -72
- package/src/locales/ar.json +727 -0
- package/src/locales/de.json +678 -430
- package/src/locales/en.json +717 -455
- package/src/locales/es.json +679 -430
- package/src/locales/fr.json +680 -431
- package/src/locales/index.js +12 -2
- package/src/locales/it.json +727 -0
- package/src/locales/ja.json +727 -0
- package/src/locales/ko.json +727 -0
- package/src/locales/nl.json +727 -0
- package/src/locales/pl.json +727 -0
- package/src/locales/pt-BR.json +727 -0
- package/src/locales/ru.json +727 -0
- package/src/locales/tr.json +727 -0
- package/src/locales/zh-CN.json +727 -0
- package/src/pages/Admin/ApiTokens/Index.vue +381 -381
- package/src/pages/Admin/AuditLog/Index.vue +154 -154
- package/src/pages/Admin/BusinessHours/Form.vue +172 -172
- package/src/pages/Admin/BusinessHours/Index.vue +113 -113
- package/src/pages/Admin/CannedResponses/Index.vue +127 -127
- package/src/pages/Admin/Capacity/Index.vue +134 -134
- package/src/pages/Admin/CustomFields/Form.vue +195 -195
- package/src/pages/Admin/CustomFields/Index.vue +134 -134
- package/src/pages/Admin/CustomObjects/Form.vue +202 -202
- package/src/pages/Admin/CustomObjects/Index.vue +127 -127
- package/src/pages/Admin/CustomObjects/Records.vue +228 -228
- package/src/pages/Admin/Departments/Form.vue +75 -75
- package/src/pages/Admin/Departments/Index.vue +110 -109
- package/src/pages/Admin/EscalationRules/Form.vue +157 -157
- package/src/pages/Admin/EscalationRules/Index.vue +178 -178
- package/src/pages/Admin/Import/Connect.vue +0 -1
- package/src/pages/Admin/Import/Index.vue +1 -1
- package/src/pages/Admin/Import/Progress.vue +1 -1
- package/src/pages/Admin/KnowledgeBase/Articles/Form.vue +142 -142
- package/src/pages/Admin/KnowledgeBase/Articles/Index.vue +195 -195
- package/src/pages/Admin/KnowledgeBase/Categories/Index.vue +193 -193
- package/src/pages/Admin/Macros/Index.vue +448 -448
- package/src/pages/Admin/Plugins/Index.vue +327 -327
- package/src/pages/Admin/Reports/AgentDetail.vue +132 -0
- package/src/pages/Admin/Reports/AgentMetrics.vue +115 -115
- package/src/pages/Admin/Reports/AgentRanking.vue +246 -0
- package/src/pages/Admin/Reports/Cohorts.vue +180 -0
- package/src/pages/Admin/Reports/Comparison.vue +141 -0
- package/src/pages/Admin/Reports/CsatReport.vue +127 -127
- package/src/pages/Admin/Reports/Dashboard.vue +36 -21
- package/src/pages/Admin/Reports/ResolutionTimes.vue +164 -0
- package/src/pages/Admin/Reports/ResponseTimes.vue +164 -0
- package/src/pages/Admin/Reports/SlaReport.vue +162 -166
- package/src/pages/Admin/Reports/SlaTrends.vue +183 -0
- package/src/pages/Admin/Reports.vue +206 -206
- package/src/pages/Admin/Roles/Form.vue +71 -71
- package/src/pages/Admin/Roles/Index.vue +122 -122
- package/src/pages/Admin/Settings/CsatSettings.vue +165 -165
- package/src/pages/Admin/Settings/DataRetention.vue +182 -182
- package/src/pages/Admin/Settings/EmailSettings.vue +243 -243
- package/src/pages/Admin/Settings/Sandbox.vue +135 -135
- package/src/pages/Admin/Settings/SsoSettings.vue +218 -218
- package/src/pages/Admin/Settings/TwoFactor.vue +110 -110
- package/src/pages/Admin/Settings.vue +1008 -468
- package/src/pages/Admin/Skills/Form.vue +53 -53
- package/src/pages/Admin/Skills/Index.vue +94 -94
- package/src/pages/Admin/SlaPolicies/Form.vue +118 -118
- package/src/pages/Admin/SlaPolicies/Index.vue +121 -120
- package/src/pages/Admin/Statuses/Form.vue +114 -114
- package/src/pages/Admin/Statuses/Index.vue +153 -153
- package/src/pages/Admin/Tags/Index.vue +191 -191
- package/src/pages/Admin/Tickets/Index.vue +126 -91
- package/src/pages/Admin/Tickets/Show.vue +29 -0
- package/src/pages/Admin/Webhooks/DeliveryLog.vue +120 -120
- package/src/pages/Admin/Webhooks/Form.vue +110 -110
- package/src/pages/Admin/Webhooks/Index.vue +136 -136
- package/src/pages/Admin/Workflows/Builder.vue +207 -0
- package/src/pages/Admin/Workflows/Index.vue +235 -0
- package/src/pages/Admin/Workflows/Logs.vue +286 -0
- package/src/pages/Agent/TicketIndex.vue +112 -88
- package/src/pages/Agent/TicketShow.vue +192 -60
- package/src/pages/Customer/Create.vue +1 -1
- package/src/pages/Customer/Index.vue +31 -31
- package/src/pages/Customer/KnowledgeBase/Article.vue +4 -2
- package/src/pages/Customer/KnowledgeBase/Index.vue +151 -151
- package/src/pages/Customer/Show.vue +69 -63
- package/src/pages/Guest/Create.vue +40 -15
- package/src/pages/Guest/Show.vue +124 -93
- package/src/plugin.js +25 -0
- package/src/utils/mentionHighlight.js +24 -0
- package/src/utils/sanitizeHtml.js +78 -64
- package/src/widget/EscalatedWidget.vue +804 -0
- package/src/widget/index.js +254 -0
- package/src/pages/Admin/Automations/Form.vue +0 -184
- package/src/pages/Admin/Automations/Index.vue +0 -129
|
@@ -1,178 +1,178 @@
|
|
|
1
|
-
<script setup>
|
|
2
|
-
import EscalatedLayout from '../../../components/EscalatedLayout.vue';
|
|
3
|
-
import { Link, router } from '@inertiajs/vue3';
|
|
4
|
-
import { ref, computed } from 'vue';
|
|
5
|
-
|
|
6
|
-
const props = defineProps({ rules: Array });
|
|
7
|
-
|
|
8
|
-
const selectedCategory = ref('');
|
|
9
|
-
const collapsedCategories = ref({});
|
|
10
|
-
|
|
11
|
-
function destroy(id) {
|
|
12
|
-
if (confirm('Delete this escalation rule?')) {
|
|
13
|
-
router.delete(route('escalated.admin.escalation-rules.destroy', id));
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
const categories = computed(() => {
|
|
18
|
-
const cats = new Set();
|
|
19
|
-
(props.rules || []).forEach((r) => cats.add(r.category || 'Uncategorized'));
|
|
20
|
-
return Array.from(cats).sort();
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
const filteredRules = computed(() => {
|
|
24
|
-
if (!selectedCategory.value) return props.rules || [];
|
|
25
|
-
return (props.rules || []).filter((r) => (r.category || 'Uncategorized') === selectedCategory.value);
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
const groupedRules = computed(() => {
|
|
29
|
-
const groups = {};
|
|
30
|
-
filteredRules.value.forEach((rule) => {
|
|
31
|
-
const cat = rule.category || 'Uncategorized';
|
|
32
|
-
if (!groups[cat]) groups[cat] = [];
|
|
33
|
-
groups[cat].push(rule);
|
|
34
|
-
});
|
|
35
|
-
return groups;
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
function toggleCategory(cat) {
|
|
39
|
-
collapsedCategories.value[cat] = !collapsedCategories.value[cat];
|
|
40
|
-
}
|
|
41
|
-
</script>
|
|
42
|
-
|
|
43
|
-
<template>
|
|
44
|
-
<EscalatedLayout title="Escalation Rules">
|
|
45
|
-
<div class="mb-4 flex items-center justify-between">
|
|
46
|
-
<div class="flex items-center gap-3">
|
|
47
|
-
<select
|
|
48
|
-
v-model="selectedCategory"
|
|
49
|
-
class="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)]"
|
|
50
|
-
>
|
|
51
|
-
<option value="">All Categories</option>
|
|
52
|
-
<option v-for="cat in categories" :key="cat" :value="cat">{{ cat }}</option>
|
|
53
|
-
</select>
|
|
54
|
-
</div>
|
|
55
|
-
<Link
|
|
56
|
-
:href="route('escalated.admin.escalation-rules.create')"
|
|
57
|
-
class="rounded-lg bg-gradient-to-r from-[var(--esc-panel-accent)] to-[var(--esc-panel-accent-secondary)] px-4 py-2 text-sm font-medium text-white shadow-lg shadow-[var(--esc-panel-bg)]/20 transition-all hover:from-[var(--esc-panel-accent-hover)] hover:to-[var(--esc-panel-accent-secondary-hover)]"
|
|
58
|
-
>
|
|
59
|
-
Add Rule
|
|
60
|
-
</Link>
|
|
61
|
-
</div>
|
|
62
|
-
|
|
63
|
-
<div
|
|
64
|
-
v-if="!rules?.length"
|
|
65
|
-
class="rounded-xl border border-[var(--esc-panel-border)] bg-[var(--esc-panel-surface)] px-4 py-12 text-center"
|
|
66
|
-
>
|
|
67
|
-
<svg
|
|
68
|
-
class="mx-auto mb-3 h-8 w-8 text-[var(--esc-panel-text-muted)]"
|
|
69
|
-
fill="none"
|
|
70
|
-
stroke="currentColor"
|
|
71
|
-
stroke-width="1.5"
|
|
72
|
-
viewBox="0 0 24 24"
|
|
73
|
-
>
|
|
74
|
-
<path
|
|
75
|
-
stroke-linecap="round"
|
|
76
|
-
stroke-linejoin="round"
|
|
77
|
-
d="M3 4.5h14.25M3 9h9.75M3 13.5h5.25m5.25-.75L17.25 9m0 0L21 12.75M17.25 9v12"
|
|
78
|
-
/>
|
|
79
|
-
</svg>
|
|
80
|
-
<p class="text-sm text-[var(--esc-panel-text-muted)]">No escalation rules yet</p>
|
|
81
|
-
<p class="mt-1 text-xs text-[var(--esc-panel-text-muted)]">
|
|
82
|
-
Set up automatic escalation for overdue tickets
|
|
83
|
-
</p>
|
|
84
|
-
</div>
|
|
85
|
-
|
|
86
|
-
<!-- Grouped by category -->
|
|
87
|
-
<div v-for="(catRules, category) in groupedRules" :key="category" class="mb-4">
|
|
88
|
-
<button
|
|
89
|
-
class="mb-2 flex w-full items-center gap-2 text-sm font-semibold text-[var(--esc-panel-text-secondary)] hover:text-[var(--esc-panel-text)]"
|
|
90
|
-
@click="toggleCategory(category)"
|
|
91
|
-
>
|
|
92
|
-
<svg
|
|
93
|
-
:class="[
|
|
94
|
-
'h-4 w-4 text-[var(--esc-panel-text-muted)] transition-transform',
|
|
95
|
-
!collapsedCategories[category] && 'rotate-90',
|
|
96
|
-
]"
|
|
97
|
-
fill="none"
|
|
98
|
-
stroke="currentColor"
|
|
99
|
-
stroke-width="1.5"
|
|
100
|
-
viewBox="0 0 24 24"
|
|
101
|
-
>
|
|
102
|
-
<path stroke-linecap="round" stroke-linejoin="round" d="M8.25 4.5l7.5 7.5-7.5 7.5" />
|
|
103
|
-
</svg>
|
|
104
|
-
{{ category }}
|
|
105
|
-
<span class="text-xs text-[var(--esc-panel-text-muted)]">({{ catRules.length }})</span>
|
|
106
|
-
</button>
|
|
107
|
-
|
|
108
|
-
<div
|
|
109
|
-
v-if="!collapsedCategories[category]"
|
|
110
|
-
class="overflow-hidden rounded-xl border border-[var(--esc-panel-border)] bg-[var(--esc-panel-surface)]"
|
|
111
|
-
>
|
|
112
|
-
<table class="min-w-full divide-y divide-[var(--esc-panel-border)]">
|
|
113
|
-
<thead>
|
|
114
|
-
<tr class="bg-[var(--esc-panel-hover)]">
|
|
115
|
-
<th
|
|
116
|
-
class="px-4 py-3 text-left text-[11px] font-semibold uppercase tracking-wider text-[var(--esc-panel-text-muted)]"
|
|
117
|
-
>
|
|
118
|
-
Order
|
|
119
|
-
</th>
|
|
120
|
-
<th
|
|
121
|
-
class="px-4 py-3 text-left text-[11px] font-semibold uppercase tracking-wider text-[var(--esc-panel-text-muted)]"
|
|
122
|
-
>
|
|
123
|
-
Name
|
|
124
|
-
</th>
|
|
125
|
-
<th
|
|
126
|
-
class="px-4 py-3 text-left text-[11px] font-semibold uppercase tracking-wider text-[var(--esc-panel-text-muted)]"
|
|
127
|
-
>
|
|
128
|
-
Trigger
|
|
129
|
-
</th>
|
|
130
|
-
<th
|
|
131
|
-
class="px-4 py-3 text-left text-[11px] font-semibold uppercase tracking-wider text-[var(--esc-panel-text-muted)]"
|
|
132
|
-
>
|
|
133
|
-
Active
|
|
134
|
-
</th>
|
|
135
|
-
<th
|
|
136
|
-
class="px-4 py-3 text-right text-[11px] font-semibold uppercase tracking-wider text-[var(--esc-panel-text-muted)]"
|
|
137
|
-
>
|
|
138
|
-
Actions
|
|
139
|
-
</th>
|
|
140
|
-
</tr>
|
|
141
|
-
</thead>
|
|
142
|
-
<tbody class="divide-y divide-[var(--esc-panel-border)]">
|
|
143
|
-
<tr
|
|
144
|
-
v-for="rule in catRules"
|
|
145
|
-
:key="rule.id"
|
|
146
|
-
class="transition-colors hover:bg-[var(--esc-panel-hover)]"
|
|
147
|
-
>
|
|
148
|
-
<td class="px-4 py-3 text-sm text-[var(--esc-panel-text-tertiary)]">{{ rule.order }}</td>
|
|
149
|
-
<td class="px-4 py-3 text-sm font-medium text-[var(--esc-panel-text-secondary)]">
|
|
150
|
-
{{ rule.name }}
|
|
151
|
-
</td>
|
|
152
|
-
<td class="px-4 py-3 text-sm text-[var(--esc-panel-text-tertiary)]">
|
|
153
|
-
{{ rule.trigger_type }}
|
|
154
|
-
</td>
|
|
155
|
-
<td class="px-4 py-3 text-sm">
|
|
156
|
-
<span
|
|
157
|
-
:class="rule.is_active ? 'text-emerald-400' : 'text-[var(--esc-panel-text-muted)]'"
|
|
158
|
-
>{{ rule.is_active ? 'Yes' : 'No' }}</span
|
|
159
|
-
>
|
|
160
|
-
</td>
|
|
161
|
-
<td class="px-4 py-3 text-right text-sm">
|
|
162
|
-
<Link
|
|
163
|
-
:href="route('escalated.admin.escalation-rules.edit', rule.id)"
|
|
164
|
-
class="text-[var(--esc-panel-text-secondary)] hover:text-[var(--esc-panel-text)]"
|
|
165
|
-
>
|
|
166
|
-
Edit
|
|
167
|
-
</Link>
|
|
168
|
-
<button class="ml-3 text-rose-400 hover:text-rose-300" @click="destroy(rule.id)">
|
|
169
|
-
Delete
|
|
170
|
-
</button>
|
|
171
|
-
</td>
|
|
172
|
-
</tr>
|
|
173
|
-
</tbody>
|
|
174
|
-
</table>
|
|
175
|
-
</div>
|
|
176
|
-
</div>
|
|
177
|
-
</EscalatedLayout>
|
|
178
|
-
</template>
|
|
1
|
+
<script setup>
|
|
2
|
+
import EscalatedLayout from '../../../components/EscalatedLayout.vue';
|
|
3
|
+
import { Link, router } from '@inertiajs/vue3';
|
|
4
|
+
import { ref, computed } from 'vue';
|
|
5
|
+
|
|
6
|
+
const props = defineProps({ rules: Array });
|
|
7
|
+
|
|
8
|
+
const selectedCategory = ref('');
|
|
9
|
+
const collapsedCategories = ref({});
|
|
10
|
+
|
|
11
|
+
function destroy(id) {
|
|
12
|
+
if (confirm('Delete this escalation rule?')) {
|
|
13
|
+
router.delete(route('escalated.admin.escalation-rules.destroy', id));
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const categories = computed(() => {
|
|
18
|
+
const cats = new Set();
|
|
19
|
+
(props.rules || []).forEach((r) => cats.add(r.category || 'Uncategorized'));
|
|
20
|
+
return Array.from(cats).sort();
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
const filteredRules = computed(() => {
|
|
24
|
+
if (!selectedCategory.value) return props.rules || [];
|
|
25
|
+
return (props.rules || []).filter((r) => (r.category || 'Uncategorized') === selectedCategory.value);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
const groupedRules = computed(() => {
|
|
29
|
+
const groups = {};
|
|
30
|
+
filteredRules.value.forEach((rule) => {
|
|
31
|
+
const cat = rule.category || 'Uncategorized';
|
|
32
|
+
if (!groups[cat]) groups[cat] = [];
|
|
33
|
+
groups[cat].push(rule);
|
|
34
|
+
});
|
|
35
|
+
return groups;
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
function toggleCategory(cat) {
|
|
39
|
+
collapsedCategories.value[cat] = !collapsedCategories.value[cat];
|
|
40
|
+
}
|
|
41
|
+
</script>
|
|
42
|
+
|
|
43
|
+
<template>
|
|
44
|
+
<EscalatedLayout title="Escalation Rules">
|
|
45
|
+
<div class="mb-4 flex items-center justify-between">
|
|
46
|
+
<div class="flex items-center gap-3">
|
|
47
|
+
<select
|
|
48
|
+
v-model="selectedCategory"
|
|
49
|
+
class="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)]"
|
|
50
|
+
>
|
|
51
|
+
<option value="">All Categories</option>
|
|
52
|
+
<option v-for="cat in categories" :key="cat" :value="cat">{{ cat }}</option>
|
|
53
|
+
</select>
|
|
54
|
+
</div>
|
|
55
|
+
<Link
|
|
56
|
+
:href="route('escalated.admin.escalation-rules.create')"
|
|
57
|
+
class="rounded-lg bg-gradient-to-r from-[var(--esc-panel-accent)] to-[var(--esc-panel-accent-secondary)] px-4 py-2 text-sm font-medium text-white shadow-lg shadow-[var(--esc-panel-bg)]/20 transition-all hover:from-[var(--esc-panel-accent-hover)] hover:to-[var(--esc-panel-accent-secondary-hover)]"
|
|
58
|
+
>
|
|
59
|
+
Add Rule
|
|
60
|
+
</Link>
|
|
61
|
+
</div>
|
|
62
|
+
|
|
63
|
+
<div
|
|
64
|
+
v-if="!rules?.length"
|
|
65
|
+
class="rounded-xl border border-[var(--esc-panel-border)] bg-[var(--esc-panel-surface)] px-4 py-12 text-center"
|
|
66
|
+
>
|
|
67
|
+
<svg
|
|
68
|
+
class="mx-auto mb-3 h-8 w-8 text-[var(--esc-panel-text-muted)]"
|
|
69
|
+
fill="none"
|
|
70
|
+
stroke="currentColor"
|
|
71
|
+
stroke-width="1.5"
|
|
72
|
+
viewBox="0 0 24 24"
|
|
73
|
+
>
|
|
74
|
+
<path
|
|
75
|
+
stroke-linecap="round"
|
|
76
|
+
stroke-linejoin="round"
|
|
77
|
+
d="M3 4.5h14.25M3 9h9.75M3 13.5h5.25m5.25-.75L17.25 9m0 0L21 12.75M17.25 9v12"
|
|
78
|
+
/>
|
|
79
|
+
</svg>
|
|
80
|
+
<p class="text-sm text-[var(--esc-panel-text-muted)]">No escalation rules yet</p>
|
|
81
|
+
<p class="mt-1 text-xs text-[var(--esc-panel-text-muted)]">
|
|
82
|
+
Set up automatic escalation for overdue tickets
|
|
83
|
+
</p>
|
|
84
|
+
</div>
|
|
85
|
+
|
|
86
|
+
<!-- Grouped by category -->
|
|
87
|
+
<div v-for="(catRules, category) in groupedRules" :key="category" class="mb-4">
|
|
88
|
+
<button
|
|
89
|
+
class="mb-2 flex w-full items-center gap-2 text-sm font-semibold text-[var(--esc-panel-text-secondary)] hover:text-[var(--esc-panel-text)]"
|
|
90
|
+
@click="toggleCategory(category)"
|
|
91
|
+
>
|
|
92
|
+
<svg
|
|
93
|
+
:class="[
|
|
94
|
+
'h-4 w-4 text-[var(--esc-panel-text-muted)] transition-transform',
|
|
95
|
+
!collapsedCategories[category] && 'rotate-90',
|
|
96
|
+
]"
|
|
97
|
+
fill="none"
|
|
98
|
+
stroke="currentColor"
|
|
99
|
+
stroke-width="1.5"
|
|
100
|
+
viewBox="0 0 24 24"
|
|
101
|
+
>
|
|
102
|
+
<path stroke-linecap="round" stroke-linejoin="round" d="M8.25 4.5l7.5 7.5-7.5 7.5" />
|
|
103
|
+
</svg>
|
|
104
|
+
{{ category }}
|
|
105
|
+
<span class="text-xs text-[var(--esc-panel-text-muted)]">({{ catRules.length }})</span>
|
|
106
|
+
</button>
|
|
107
|
+
|
|
108
|
+
<div
|
|
109
|
+
v-if="!collapsedCategories[category]"
|
|
110
|
+
class="overflow-hidden rounded-xl border border-[var(--esc-panel-border)] bg-[var(--esc-panel-surface)]"
|
|
111
|
+
>
|
|
112
|
+
<table class="min-w-full divide-y divide-[var(--esc-panel-border)]">
|
|
113
|
+
<thead>
|
|
114
|
+
<tr class="bg-[var(--esc-panel-hover)]">
|
|
115
|
+
<th
|
|
116
|
+
class="px-4 py-3 text-left text-[11px] font-semibold uppercase tracking-wider text-[var(--esc-panel-text-muted)]"
|
|
117
|
+
>
|
|
118
|
+
Order
|
|
119
|
+
</th>
|
|
120
|
+
<th
|
|
121
|
+
class="px-4 py-3 text-left text-[11px] font-semibold uppercase tracking-wider text-[var(--esc-panel-text-muted)]"
|
|
122
|
+
>
|
|
123
|
+
Name
|
|
124
|
+
</th>
|
|
125
|
+
<th
|
|
126
|
+
class="px-4 py-3 text-left text-[11px] font-semibold uppercase tracking-wider text-[var(--esc-panel-text-muted)]"
|
|
127
|
+
>
|
|
128
|
+
Trigger
|
|
129
|
+
</th>
|
|
130
|
+
<th
|
|
131
|
+
class="px-4 py-3 text-left text-[11px] font-semibold uppercase tracking-wider text-[var(--esc-panel-text-muted)]"
|
|
132
|
+
>
|
|
133
|
+
Active
|
|
134
|
+
</th>
|
|
135
|
+
<th
|
|
136
|
+
class="px-4 py-3 text-right text-[11px] font-semibold uppercase tracking-wider text-[var(--esc-panel-text-muted)]"
|
|
137
|
+
>
|
|
138
|
+
Actions
|
|
139
|
+
</th>
|
|
140
|
+
</tr>
|
|
141
|
+
</thead>
|
|
142
|
+
<tbody class="divide-y divide-[var(--esc-panel-border)]">
|
|
143
|
+
<tr
|
|
144
|
+
v-for="rule in catRules"
|
|
145
|
+
:key="rule.id"
|
|
146
|
+
class="transition-colors hover:bg-[var(--esc-panel-hover)]"
|
|
147
|
+
>
|
|
148
|
+
<td class="px-4 py-3 text-sm text-[var(--esc-panel-text-tertiary)]">{{ rule.order }}</td>
|
|
149
|
+
<td class="px-4 py-3 text-sm font-medium text-[var(--esc-panel-text-secondary)]">
|
|
150
|
+
{{ rule.name }}
|
|
151
|
+
</td>
|
|
152
|
+
<td class="px-4 py-3 text-sm text-[var(--esc-panel-text-tertiary)]">
|
|
153
|
+
{{ rule.trigger_type }}
|
|
154
|
+
</td>
|
|
155
|
+
<td class="px-4 py-3 text-sm">
|
|
156
|
+
<span
|
|
157
|
+
:class="rule.is_active ? 'text-emerald-400' : 'text-[var(--esc-panel-text-muted)]'"
|
|
158
|
+
>{{ rule.is_active ? 'Yes' : 'No' }}</span
|
|
159
|
+
>
|
|
160
|
+
</td>
|
|
161
|
+
<td class="px-4 py-3 text-right text-sm">
|
|
162
|
+
<Link
|
|
163
|
+
:href="route('escalated.admin.escalation-rules.edit', rule.id)"
|
|
164
|
+
class="text-[var(--esc-panel-text-secondary)] hover:text-[var(--esc-panel-text)]"
|
|
165
|
+
>
|
|
166
|
+
Edit
|
|
167
|
+
</Link>
|
|
168
|
+
<button class="ml-3 text-rose-400 hover:text-rose-300" @click="destroy(rule.id)">
|
|
169
|
+
Delete
|
|
170
|
+
</button>
|
|
171
|
+
</td>
|
|
172
|
+
</tr>
|
|
173
|
+
</tbody>
|
|
174
|
+
</table>
|
|
175
|
+
</div>
|
|
176
|
+
</div>
|
|
177
|
+
</EscalatedLayout>
|
|
178
|
+
</template>
|