@dragonmastery/dragoncore-vue 0.0.3 → 0.0.4
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 +2 -2
- package/dist/{ChangePasswordPage-Btu5lf-r.js → ChangePasswordPage-DCews8GU.js} +2 -2
- package/dist/{ChangePasswordPage-Btu5lf-r.js.map → ChangePasswordPage-DCews8GU.js.map} +1 -1
- package/dist/ChangePasswordPage-Dm5vW0nl.js +6 -0
- package/dist/CreateTeamForm-zVlGgmL9.js +27 -0
- package/dist/CreateTeamMemberForm-DkCbsJDn.js +27 -0
- package/dist/{CreateUserPage-Cmx8xjjv.js → CreateUserPage-B8qeBZij.js} +2 -2
- package/dist/{CreateUserPage-Cmx8xjjv.js.map → CreateUserPage-B8qeBZij.js.map} +1 -1
- package/dist/CreateUserPage-WjYDkwpb.js +6 -0
- package/dist/CreditBalanceDashboard-BTW4IK66.js +27 -0
- package/dist/CreditManagement-0JxmCIAd.js +27 -0
- package/dist/CustomerCreateSupportTicketForm-CQcv4vrX.js +27 -0
- package/dist/CustomerSupportTicketDetailPage-DQa_Zvfe.js +703 -0
- package/dist/CustomerSupportTicketDetailPage-DQa_Zvfe.js.map +1 -0
- package/dist/CustomerSupportTicketList-CMPRQ_7O.js +27 -0
- package/dist/CustomerSupportTicketParent-BOYIren9.js +7 -0
- package/dist/{CustomerSupportTicketParent-2mONd9kL.js → CustomerSupportTicketParent-sT8hpgrA.js} +6 -6
- package/dist/CustomerSupportTicketParent-sT8hpgrA.js.map +1 -0
- package/dist/CustomerSupportTicketSuccess-CnRWm6gX.js +27 -0
- package/dist/EditTeamForm-BM90JTjr.js +27 -0
- package/dist/EditTeamMemberForm-B8-pI6Xm.js +6 -0
- package/dist/{EditTeamMemberForm-ru4WgLz-.js → EditTeamMemberForm-CKbKomrL.js} +27 -5
- package/dist/EditTeamMemberForm-CKbKomrL.js.map +1 -0
- package/dist/EditUserPage-BG-Fkx_c.js +7 -0
- package/dist/{EditUserPage-BxJ5QvIM.js → EditUserPage-XqF25iwz.js} +4 -4
- package/dist/{EditUserPage-BxJ5QvIM.js.map → EditUserPage-XqF25iwz.js.map} +1 -1
- package/dist/ForgotPassword-CjWv2V7p.js +7 -0
- package/dist/{ForgotPassword-CqhenzUG.js → ForgotPassword-D3bjL48L.js} +2 -2
- package/dist/{ForgotPassword-CqhenzUG.js.map → ForgotPassword-D3bjL48L.js.map} +1 -1
- package/dist/LoginForm--br4Il85.js +7 -0
- package/dist/{LoginForm-_PZ51Uwe.js → LoginForm-C85U2E2r.js} +3 -3
- package/dist/{LoginForm-_PZ51Uwe.js.map → LoginForm-C85U2E2r.js.map} +1 -1
- package/dist/Logout-DHT-5Qz3.js +6 -0
- package/dist/{Logout-BMjiqHnS.js → Logout-DZuWLh0O.js} +3 -3
- package/dist/{Logout-BMjiqHnS.js.map → Logout-DZuWLh0O.js.map} +1 -1
- package/dist/ResetPassword-DAn7dYAp.js +27 -0
- package/dist/SavedFiltersPage-BNasEKOY.js +391 -0
- package/dist/SavedFiltersPage-BNasEKOY.js.map +1 -0
- package/dist/Signup-VZa7U-Ur.js +7 -0
- package/dist/{Signup-c2-_yMOM.js → Signup-hpV8J5cM.js} +3 -3
- package/dist/{Signup-c2-_yMOM.js.map → Signup-hpV8J5cM.js.map} +1 -1
- package/dist/StaffCreateSupportTicketForm-DoHCw60c.js +27 -0
- package/dist/StaffSupportTicketDetailPage-D49ibqrO.js +1884 -0
- package/dist/StaffSupportTicketDetailPage-D49ibqrO.js.map +1 -0
- package/dist/StaffSupportTicketList-BgCIa_9v.js +27 -0
- package/dist/StaffSupportTicketParent-C7Mm7W_0.js +7 -0
- package/dist/{StaffSupportTicketParent-Cx1buQZw.js → StaffSupportTicketParent-CxrPxXSH.js} +6 -6
- package/dist/StaffSupportTicketParent-CxrPxXSH.js.map +1 -0
- package/dist/StaffSupportTicketSuccess-DZF2WpZc.js +27 -0
- package/dist/SupportStaffPage-nd0HowtH.js +156 -0
- package/dist/SupportStaffPage-nd0HowtH.js.map +1 -0
- package/dist/SupportTicketDevLifecycleBadge-Cl4y47Sy.js +116 -0
- package/dist/SupportTicketDevLifecycleBadge-Cl4y47Sy.js.map +1 -0
- package/dist/SupportTicketMaintenancePage-rcJ7EfDj.js +56 -0
- package/dist/SupportTicketMaintenancePage-rcJ7EfDj.js.map +1 -0
- package/dist/TeamAttachmentsTab-BoOIuTU1.js +27 -0
- package/dist/{TeamHistoryTab-gB3H2KZv.js → TeamHistoryTab-CNelXR3Q.js} +19 -6
- package/dist/TeamHistoryTab-CNelXR3Q.js.map +1 -0
- package/dist/TeamHistoryTab-siesF93u.js +4 -0
- package/dist/TeamList-TpS3BhPd.js +27 -0
- package/dist/TeamMemberList-CQTxcWNS.js +27 -0
- package/dist/TeamMemberParent-Bt0kbyKQ.js +27 -0
- package/dist/{NoteList-C0hRPNMO.js → TeamNotesTab-BhVRLG8h.js} +30 -69
- package/dist/TeamNotesTab-BhVRLG8h.js.map +1 -0
- package/dist/TeamNotesTab-Crp-afAe.js +7 -0
- package/dist/TeamParent-BvLiiJq6.js +27 -0
- package/dist/TimelineNoteInput-BRsQ2QTz.js +490 -0
- package/dist/TimelineNoteInput-BRsQ2QTz.js.map +1 -0
- package/dist/{InlineAttachments-I39rOvip.js → TimelineSystemEvent-B69B3eeL.js} +589 -126
- package/dist/TimelineSystemEvent-B69B3eeL.js.map +1 -0
- package/dist/UserListPage-D68AjrjM.js +4 -0
- package/dist/{UserListPage-WU56KiWj.js → UserListPage-OGYOLwlw.js} +3 -3
- package/dist/{UserListPage-WU56KiWj.js.map → UserListPage-OGYOLwlw.js.map} +1 -1
- package/dist/UserProfilePage-Q68NAGQQ.js +7 -0
- package/dist/{UserProfilePage-BtLUY1kt.js → UserProfilePage-uAIfC_NW.js} +4 -4
- package/dist/{UserProfilePage-BtLUY1kt.js.map → UserProfilePage-uAIfC_NW.js.map} +1 -1
- package/dist/ViewTeam-Bb1WH_Us.js +27 -0
- package/dist/ViewTeamMember-CBTAnAhS.js +27 -0
- package/dist/{convertToLocalDateTime-D4IoNvRj.js → convertToLocalDateTime-DOSGtMn8.js} +13 -3
- package/dist/convertToLocalDateTime-DOSGtMn8.js.map +1 -0
- package/dist/{displayIdFormatter-Dz900Awr.js → displayIdFormatter-BoKcrgF5.js} +1 -1
- package/dist/{displayIdFormatter-Dz900Awr.js.map → displayIdFormatter-BoKcrgF5.js.map} +1 -1
- package/dist/extractRpcErrorMessage-C_UbKgHL.js +20 -0
- package/dist/extractRpcErrorMessage-C_UbKgHL.js.map +1 -0
- package/dist/index.d.ts +1658 -1384
- package/dist/index.js +25 -40
- package/dist/{src-o5fMIo5_.js → src-ChwBeNHB.js} +4006 -1522
- package/dist/src-ChwBeNHB.js.map +1 -0
- package/dist/{useMutation-CFwe7H9j.js → useMutation-B4_S4Xoa.js} +3 -3
- package/dist/{useMutation-CFwe7H9j.js.map → useMutation-B4_S4Xoa.js.map} +1 -1
- package/dist/{useQuery-p7oJO7OD.js → useQuery-B7ndu5_P.js} +3 -3
- package/dist/{useQuery-p7oJO7OD.js.map → useQuery-B7ndu5_P.js.map} +1 -1
- package/dist/{useQueryCache-ByayvZgZ.js → useQueryCache-DqcDMsxb.js} +2 -2
- package/dist/{useQueryCache-ByayvZgZ.js.map → useQueryCache-DqcDMsxb.js.map} +1 -1
- package/dist/{useRpcAuth-BLlRSHy8.js → useRpcAuth-Dp2sec-X.js} +13 -4
- package/dist/useRpcAuth-Dp2sec-X.js.map +1 -0
- package/package.json +3 -3
- package/dist/ChangePasswordPage-mBBuQMkT.js +0 -6
- package/dist/CreateTeamForm-n2ut93vM.js +0 -43
- package/dist/CreateTeamMemberForm-CcH3AxNL.js +0 -43
- package/dist/CreateUserPage-CDrGuW9B.js +0 -6
- package/dist/CreditBalanceDashboard-DLz0ioP3.js +0 -43
- package/dist/CreditManagement-D3q5S-qc.js +0 -43
- package/dist/CustomerCreateSupportTicketForm-Ci7QYkG-.js +0 -43
- package/dist/CustomerEditSupportTicketForm-Dd5ZB74k.js +0 -159
- package/dist/CustomerEditSupportTicketForm-Dd5ZB74k.js.map +0 -1
- package/dist/CustomerEditSupportTicketForm-lLchVjnw.js +0 -9
- package/dist/CustomerSupportTicketAttachmentsTab-gBrVO97t.js +0 -43
- package/dist/CustomerSupportTicketCustomerNotesTab-D0jhzbOY.js +0 -8
- package/dist/CustomerSupportTicketCustomerNotesTab-D1aa9It7.js +0 -23
- package/dist/CustomerSupportTicketCustomerNotesTab-D1aa9It7.js.map +0 -1
- package/dist/CustomerSupportTicketHistoryTab-BNTf8EZq.js +0 -6
- package/dist/CustomerSupportTicketHistoryTab-CFYN_Sa4.js +0 -17
- package/dist/CustomerSupportTicketHistoryTab-CFYN_Sa4.js.map +0 -1
- package/dist/CustomerSupportTicketList-BkOzFxMP.js +0 -6
- package/dist/CustomerSupportTicketList-C2nUPawb.js +0 -166
- package/dist/CustomerSupportTicketList-C2nUPawb.js.map +0 -1
- package/dist/CustomerSupportTicketParent-2mONd9kL.js.map +0 -1
- package/dist/CustomerSupportTicketParent-N8ko1yFE.js +0 -7
- package/dist/CustomerSupportTicketSuccess-w_-9NXT4.js +0 -43
- package/dist/CustomerViewSupportTicket-CVwNH0lS.js +0 -11
- package/dist/CustomerViewSupportTicket-tZkxragu.js +0 -363
- package/dist/CustomerViewSupportTicket-tZkxragu.js.map +0 -1
- package/dist/EditTeamForm-BioqiTWE.js +0 -43
- package/dist/EditTeamMemberForm-DCq0Gsn_.js +0 -7
- package/dist/EditTeamMemberForm-ru4WgLz-.js.map +0 -1
- package/dist/EditUserPage-XOBuxUxd.js +0 -7
- package/dist/FieldsetSection-CsHN38_o.js +0 -27
- package/dist/FieldsetSection-CsHN38_o.js.map +0 -1
- package/dist/ForgotPassword-CpqvcSFg.js +0 -7
- package/dist/InlineAttachments-I39rOvip.js.map +0 -1
- package/dist/LoginForm-AM0qkfbU.js +0 -7
- package/dist/Logout-BfiBjlaH.js +0 -6
- package/dist/NoteList-C0hRPNMO.js.map +0 -1
- package/dist/NotificationEmailsPage-BjRqtW95.js +0 -141
- package/dist/NotificationEmailsPage-BjRqtW95.js.map +0 -1
- package/dist/NotificationEmailsPage-bx-9rg3x.js +0 -7
- package/dist/ResetPassword-BQLkR9TZ.js +0 -43
- package/dist/Signup-CnCcQlB8.js +0 -7
- package/dist/StaffCreateSupportTicketForm-ChVFDJdA.js +0 -43
- package/dist/StaffEditSupportTicketForm-DY1Zkf5k.js +0 -9
- package/dist/StaffEditSupportTicketForm-DuUKuIGg.js +0 -263
- package/dist/StaffEditSupportTicketForm-DuUKuIGg.js.map +0 -1
- package/dist/StaffSupportTicketAttachmentsTab-DpDXsHXP.js +0 -43
- package/dist/StaffSupportTicketCustomerNotesTab-CusqQV2-.js +0 -23
- package/dist/StaffSupportTicketCustomerNotesTab-CusqQV2-.js.map +0 -1
- package/dist/StaffSupportTicketCustomerNotesTab-rbJHJ0_V.js +0 -8
- package/dist/StaffSupportTicketHistoryTab-D24myEm3.js +0 -17
- package/dist/StaffSupportTicketHistoryTab-D24myEm3.js.map +0 -1
- package/dist/StaffSupportTicketHistoryTab-nmVma5vp.js +0 -6
- package/dist/StaffSupportTicketInternalNotesTab-D8HM--dp.js +0 -23
- package/dist/StaffSupportTicketInternalNotesTab-D8HM--dp.js.map +0 -1
- package/dist/StaffSupportTicketInternalNotesTab-DihYd5XI.js +0 -8
- package/dist/StaffSupportTicketList-DelptSmK.js +0 -43
- package/dist/StaffSupportTicketParent-BCrj3ckV.js +0 -7
- package/dist/StaffSupportTicketParent-Cx1buQZw.js.map +0 -1
- package/dist/StaffSupportTicketSuccess-BYxtY5wZ.js +0 -43
- package/dist/StaffSupportTicketWorkflowTab-BrDDBeK9.js +0 -9
- package/dist/StaffSupportTicketWorkflowTab-DmVTPzxS.js +0 -1234
- package/dist/StaffSupportTicketWorkflowTab-DmVTPzxS.js.map +0 -1
- package/dist/SupportTicketHistoryTab-CLMopA7a.js +0 -220
- package/dist/SupportTicketHistoryTab-CLMopA7a.js.map +0 -1
- package/dist/SupportTicketStatusBadge-YdZzjvkh.js +0 -163
- package/dist/SupportTicketStatusBadge-YdZzjvkh.js.map +0 -1
- package/dist/TeamAttachmentsTab-BxUpTWYh.js +0 -43
- package/dist/TeamHistoryTab-CUCT9MRG.js +0 -5
- package/dist/TeamHistoryTab-gB3H2KZv.js.map +0 -1
- package/dist/TeamList-By6pzWm5.js +0 -43
- package/dist/TeamMemberList-CYV9fWEb.js +0 -43
- package/dist/TeamMemberParent-CVvGqpxD.js +0 -43
- package/dist/TeamNotesTab-pfXTDhg6.js +0 -23
- package/dist/TeamNotesTab-pfXTDhg6.js.map +0 -1
- package/dist/TeamNotesTab-u4cDC67X.js +0 -8
- package/dist/TeamParent-BxT1KubK.js +0 -43
- package/dist/UserListPage-DsQdH2Sm.js +0 -4
- package/dist/UserProfilePage-B73JhjUu.js +0 -7
- package/dist/ViewTeam-DzX-obEl.js +0 -43
- package/dist/ViewTeamMember-PF6S_4Pb.js +0 -43
- package/dist/ZiniaContainer-C7c7Vwkh.js +0 -18
- package/dist/ZiniaContainer-C7c7Vwkh.js.map +0 -1
- package/dist/convertToLocalDateTime-D4IoNvRj.js.map +0 -1
- package/dist/creditValueFormatter-DftEzu8d.js +0 -128
- package/dist/creditValueFormatter-DftEzu8d.js.map +0 -1
- package/dist/src-o5fMIo5_.js.map +0 -1
- package/dist/useRpcAuth-BLlRSHy8.js.map +0 -1
- /package/dist/{TeamMembersTab-CpE9BaCi.js → TeamMembersTab-DTJxmb-M.js} +0 -0
|
@@ -0,0 +1,703 @@
|
|
|
1
|
+
import { t as BATCH_MODE } from "./useRpcAuth-Dp2sec-X.js";
|
|
2
|
+
import "./useQueryCache-DqcDMsxb.js";
|
|
3
|
+
import { t as useMutation } from "./useMutation-B4_S4Xoa.js";
|
|
4
|
+
import { t as useQuery } from "./useQuery-B7ndu5_P.js";
|
|
5
|
+
import { c as SupportTicketTypeBadge_default, i as SupportTicketApprovalBadge_default, l as SupportTicketPriorityBadge_default, n as TimelineItem_default, o as formatCustomerCreditValue, r as formatTicketDate, t as TimelineSystemEvent_default } from "./TimelineSystemEvent-B69B3eeL.js";
|
|
6
|
+
import { t as extractRpcErrorMessage } from "./extractRpcErrorMessage-C_UbKgHL.js";
|
|
7
|
+
import { t as formatTicketDisplayId } from "./displayIdFormatter-BoKcrgF5.js";
|
|
8
|
+
import { a as SupportTicketAttachmentsCollapsible_default, i as parseRecordVersions, n as MetadataField_default, r as ActionBannerAlert_default, t as TimelineNoteInput_default } from "./TimelineNoteInput-BRsQ2QTz.js";
|
|
9
|
+
import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, inject, nextTick, normalizeClass, openBlock, reactive, ref, renderList, resolveComponent, toDisplayString, unref, vModelSelect, vModelText, watch, withCtx, withDirectives } from "vue";
|
|
10
|
+
import { useRoute, useRouter } from "vue-router";
|
|
11
|
+
import { OPERATORS, RecordConst, supportTicketPriorityToNumber } from "@dragonmastery/dragoncore-shared";
|
|
12
|
+
import { toast } from "vue3-toastify";
|
|
13
|
+
|
|
14
|
+
//#region src/slices/support_ticket/customer/components/CustomerActionBanner.vue
|
|
15
|
+
const _sfc_main$5 = /* @__PURE__ */ defineComponent({
|
|
16
|
+
__name: "CustomerActionBanner",
|
|
17
|
+
props: { ticket: {} },
|
|
18
|
+
setup(__props) {
|
|
19
|
+
const props = __props;
|
|
20
|
+
const isArchived = computed(() => !!props.ticket.archived_at);
|
|
21
|
+
const isApproved = computed(() => {
|
|
22
|
+
const t = props.ticket;
|
|
23
|
+
return !!t.is_locked && !!t.locked_approval_at && t.status !== "CANCELLED";
|
|
24
|
+
});
|
|
25
|
+
const isRejected = computed(() => {
|
|
26
|
+
const t = props.ticket;
|
|
27
|
+
return !!t.is_locked && !!t.locked_approval_at && t.status === "CANCELLED";
|
|
28
|
+
});
|
|
29
|
+
const lockedDateFormatted = computed(() => {
|
|
30
|
+
const at = props.ticket.locked_approval_at;
|
|
31
|
+
if (!at) return "";
|
|
32
|
+
return formatTicketDate(at).formatted;
|
|
33
|
+
});
|
|
34
|
+
return (_ctx, _cache) => {
|
|
35
|
+
return isArchived.value ? (openBlock(), createBlock(ActionBannerAlert_default, {
|
|
36
|
+
key: 0,
|
|
37
|
+
variant: "neutral",
|
|
38
|
+
icon: "archive"
|
|
39
|
+
}, {
|
|
40
|
+
default: withCtx(() => [..._cache[0] || (_cache[0] = [createTextVNode(" This ticket is archived. Comments, edits, and attachments are locked for both customer and staff. ", -1)])]),
|
|
41
|
+
_: 1
|
|
42
|
+
})) : isApproved.value ? (openBlock(), createBlock(ActionBannerAlert_default, {
|
|
43
|
+
key: 1,
|
|
44
|
+
variant: "success",
|
|
45
|
+
icon: "lock"
|
|
46
|
+
}, {
|
|
47
|
+
default: withCtx(() => [createTextVNode(" This ticket was approved on " + toDisplayString(lockedDateFormatted.value) + ". ", 1)]),
|
|
48
|
+
_: 1
|
|
49
|
+
})) : isRejected.value ? (openBlock(), createBlock(ActionBannerAlert_default, {
|
|
50
|
+
key: 2,
|
|
51
|
+
variant: "error",
|
|
52
|
+
icon: "lock"
|
|
53
|
+
}, {
|
|
54
|
+
default: withCtx(() => [createTextVNode(" This ticket was rejected on " + toDisplayString(lockedDateFormatted.value) + ". ", 1)]),
|
|
55
|
+
_: 1
|
|
56
|
+
})) : createCommentVNode("v-if", true);
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
var CustomerActionBanner_default = _sfc_main$5;
|
|
61
|
+
|
|
62
|
+
//#endregion
|
|
63
|
+
//#region src/slices/support_ticket/customer/components/CustomerMetadataCard.vue
|
|
64
|
+
const _hoisted_1$4 = { class: "border border-base-200 rounded-lg p-4 md:p-6" };
|
|
65
|
+
const _hoisted_2$4 = { class: "grid grid-cols-1 md:grid-cols-2 gap-x-8 gap-y-3" };
|
|
66
|
+
const _hoisted_3$3 = { class: "md:col-span-2" };
|
|
67
|
+
const _hoisted_4$3 = {
|
|
68
|
+
key: 0,
|
|
69
|
+
class: "whitespace-pre-wrap text-sm"
|
|
70
|
+
};
|
|
71
|
+
const _hoisted_5$3 = {
|
|
72
|
+
key: 0,
|
|
73
|
+
class: "text-base-content/50"
|
|
74
|
+
};
|
|
75
|
+
const _hoisted_6$2 = { class: "text-base-content/50" };
|
|
76
|
+
const _hoisted_7$2 = { class: "text-base-content/50" };
|
|
77
|
+
const _sfc_main$4 = /* @__PURE__ */ defineComponent({
|
|
78
|
+
__name: "CustomerMetadataCard",
|
|
79
|
+
props: { ticket: {} },
|
|
80
|
+
setup(__props) {
|
|
81
|
+
const props = __props;
|
|
82
|
+
const displayApprovalStatus = computed(() => {
|
|
83
|
+
const s = props.ticket.status;
|
|
84
|
+
if (s === "PENDING") return "PENDING";
|
|
85
|
+
if (s === "CANCELLED") return "REJECTED";
|
|
86
|
+
return "APPROVED";
|
|
87
|
+
});
|
|
88
|
+
const ticketDisplayId = computed(() => formatTicketDisplayId(props.ticket.display_id, props.ticket.display_id_prefix, props.ticket.id));
|
|
89
|
+
const createdFormatted = computed(() => {
|
|
90
|
+
const at = props.ticket.created_at;
|
|
91
|
+
return at ? formatTicketDate(at).formatted : "";
|
|
92
|
+
});
|
|
93
|
+
const createdRelative = computed(() => {
|
|
94
|
+
const at = props.ticket.created_at;
|
|
95
|
+
return at ? formatTicketDate(at).relative : "";
|
|
96
|
+
});
|
|
97
|
+
const showCredits = computed(() => {
|
|
98
|
+
return !!props.ticket.is_locked && !!props.ticket.locked_approval_at;
|
|
99
|
+
});
|
|
100
|
+
const creditDisplay = computed(() => formatCustomerCreditValue(props.ticket.credit_value));
|
|
101
|
+
const targetFormatted = computed(() => props.ticket.target_at ? formatTicketDate(props.ticket.target_at).formatted : "");
|
|
102
|
+
const targetRelative = computed(() => props.ticket.target_at ? formatTicketDate(props.ticket.target_at).relative : "");
|
|
103
|
+
const completedFormatted = computed(() => props.ticket.completed_at ? formatTicketDate(props.ticket.completed_at).formatted : "");
|
|
104
|
+
const completedRelative = computed(() => props.ticket.completed_at ? formatTicketDate(props.ticket.completed_at).relative : "");
|
|
105
|
+
return (_ctx, _cache) => {
|
|
106
|
+
return openBlock(), createElementBlock("div", _hoisted_1$4, [createElementVNode("div", _hoisted_2$4, [
|
|
107
|
+
createVNode(MetadataField_default, { label: "Status" }, {
|
|
108
|
+
default: withCtx(() => [createVNode(SupportTicketApprovalBadge_default, {
|
|
109
|
+
"approval-status": displayApprovalStatus.value,
|
|
110
|
+
size: "sm"
|
|
111
|
+
}, null, 8, ["approval-status"])]),
|
|
112
|
+
_: 1
|
|
113
|
+
}),
|
|
114
|
+
createVNode(MetadataField_default, { label: "Type" }, {
|
|
115
|
+
default: withCtx(() => [createVNode(SupportTicketTypeBadge_default, {
|
|
116
|
+
type: __props.ticket.type,
|
|
117
|
+
size: "sm"
|
|
118
|
+
}, null, 8, ["type"])]),
|
|
119
|
+
_: 1
|
|
120
|
+
}),
|
|
121
|
+
createVNode(MetadataField_default, { label: "Priority" }, {
|
|
122
|
+
default: withCtx(() => [createVNode(SupportTicketPriorityBadge_default, {
|
|
123
|
+
priority: __props.ticket.priority,
|
|
124
|
+
size: "sm"
|
|
125
|
+
}, null, 8, ["priority"])]),
|
|
126
|
+
_: 1
|
|
127
|
+
}),
|
|
128
|
+
createVNode(MetadataField_default, { label: "Requester" }, {
|
|
129
|
+
default: withCtx(() => [createTextVNode(toDisplayString(__props.ticket.created_by_display_name), 1)]),
|
|
130
|
+
_: 1
|
|
131
|
+
}),
|
|
132
|
+
createElementVNode("div", _hoisted_3$3, [createVNode(MetadataField_default, { label: "Description" }, {
|
|
133
|
+
empty: withCtx(() => [..._cache[0] || (_cache[0] = [createElementVNode("span", { class: "text-base-content/50 italic text-sm" }, "No description provided", -1)])]),
|
|
134
|
+
default: withCtx(() => [__props.ticket.description?.trim() ? (openBlock(), createElementBlock("p", _hoisted_4$3, toDisplayString(__props.ticket.description), 1)) : createCommentVNode("v-if", true)]),
|
|
135
|
+
_: 1
|
|
136
|
+
})]),
|
|
137
|
+
createVNode(MetadataField_default, {
|
|
138
|
+
label: "Ticket ID",
|
|
139
|
+
copyable: true
|
|
140
|
+
}, {
|
|
141
|
+
default: withCtx(() => [createTextVNode(toDisplayString(ticketDisplayId.value), 1)]),
|
|
142
|
+
_: 1
|
|
143
|
+
}),
|
|
144
|
+
createVNode(MetadataField_default, { label: "Created" }, {
|
|
145
|
+
default: withCtx(() => [createTextVNode(toDisplayString(createdFormatted.value) + " ", 1), createdRelative.value ? (openBlock(), createElementBlock("span", _hoisted_5$3, "· " + toDisplayString(createdRelative.value), 1)) : createCommentVNode("v-if", true)]),
|
|
146
|
+
_: 1
|
|
147
|
+
}),
|
|
148
|
+
showCredits.value ? (openBlock(), createBlock(MetadataField_default, {
|
|
149
|
+
key: 0,
|
|
150
|
+
label: "Credits"
|
|
151
|
+
}, {
|
|
152
|
+
default: withCtx(() => [createTextVNode(toDisplayString(creditDisplay.value), 1)]),
|
|
153
|
+
_: 1
|
|
154
|
+
})) : createCommentVNode("v-if", true),
|
|
155
|
+
__props.ticket.target_at ? (openBlock(), createBlock(MetadataField_default, {
|
|
156
|
+
key: 1,
|
|
157
|
+
label: "Target"
|
|
158
|
+
}, {
|
|
159
|
+
default: withCtx(() => [createTextVNode(toDisplayString(targetFormatted.value) + " ", 1), createElementVNode("span", _hoisted_6$2, "· " + toDisplayString(targetRelative.value), 1)]),
|
|
160
|
+
_: 1
|
|
161
|
+
})) : createCommentVNode("v-if", true),
|
|
162
|
+
__props.ticket.completed_at ? (openBlock(), createBlock(MetadataField_default, {
|
|
163
|
+
key: 2,
|
|
164
|
+
label: "Completed"
|
|
165
|
+
}, {
|
|
166
|
+
default: withCtx(() => [createTextVNode(toDisplayString(completedFormatted.value) + " ", 1), createElementVNode("span", _hoisted_7$2, "· " + toDisplayString(completedRelative.value), 1)]),
|
|
167
|
+
_: 1
|
|
168
|
+
})) : createCommentVNode("v-if", true)
|
|
169
|
+
])]);
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
var CustomerMetadataCard_default = _sfc_main$4;
|
|
174
|
+
|
|
175
|
+
//#endregion
|
|
176
|
+
//#region src/slices/support_ticket/customer/components/CustomerSupportTicketSubscribeControl.vue
|
|
177
|
+
const _hoisted_1$3 = {
|
|
178
|
+
key: 0,
|
|
179
|
+
class: "flex flex-wrap items-center gap-2"
|
|
180
|
+
};
|
|
181
|
+
const _hoisted_2$3 = { class: "text-sm text-base-content/70" };
|
|
182
|
+
const _hoisted_3$2 = ["disabled"];
|
|
183
|
+
const _hoisted_4$2 = {
|
|
184
|
+
key: 0,
|
|
185
|
+
class: "loading loading-spinner loading-xs"
|
|
186
|
+
};
|
|
187
|
+
const _hoisted_5$2 = { key: 1 };
|
|
188
|
+
const _sfc_main$3 = /* @__PURE__ */ defineComponent({
|
|
189
|
+
__name: "CustomerSupportTicketSubscribeControl",
|
|
190
|
+
props: { ticket: {} },
|
|
191
|
+
setup(__props) {
|
|
192
|
+
const props = __props;
|
|
193
|
+
const isToggling = ref(false);
|
|
194
|
+
const subscriptionOverride = ref(null);
|
|
195
|
+
watch(() => props.ticket.id, () => {
|
|
196
|
+
subscriptionOverride.value = null;
|
|
197
|
+
});
|
|
198
|
+
const isSubscribed = computed(() => subscriptionOverride.value ?? props.ticket.my_subscription != null);
|
|
199
|
+
const { mutate: toggleSubscription } = useMutation((api, id) => api.supportTickets.toggleSubscription(id), { invalidate: /^support-tickets?:/ });
|
|
200
|
+
async function handleToggle() {
|
|
201
|
+
try {
|
|
202
|
+
isToggling.value = true;
|
|
203
|
+
const result = await toggleSubscription(props.ticket.id);
|
|
204
|
+
subscriptionOverride.value = result.subscribed;
|
|
205
|
+
toast.success(result.subscribed ? "You are now subscribed to this ticket" : "You have unsubscribed from this ticket");
|
|
206
|
+
} catch (e) {
|
|
207
|
+
toast.error(extractRpcErrorMessage(e, "Failed to update subscription"));
|
|
208
|
+
} finally {
|
|
209
|
+
isToggling.value = false;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
return (_ctx, _cache) => {
|
|
213
|
+
return __props.ticket ? (openBlock(), createElementBlock("div", _hoisted_1$3, [createElementVNode("span", _hoisted_2$3, toDisplayString(isSubscribed.value ? "You will receive notifications for updates." : "Get notified when there are updates or new comments."), 1), createElementVNode("button", {
|
|
214
|
+
type: "button",
|
|
215
|
+
class: normalizeClass(isSubscribed.value ? "btn btn-sm btn-ghost" : "btn btn-sm btn-primary"),
|
|
216
|
+
disabled: isToggling.value,
|
|
217
|
+
onClick: handleToggle
|
|
218
|
+
}, [isToggling.value ? (openBlock(), createElementBlock("span", _hoisted_4$2)) : (openBlock(), createElementBlock("span", _hoisted_5$2, toDisplayString(isSubscribed.value ? "Unsubscribe" : "Subscribe"), 1))], 10, _hoisted_3$2)])) : createCommentVNode("v-if", true);
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
var CustomerSupportTicketSubscribeControl_default = _sfc_main$3;
|
|
223
|
+
|
|
224
|
+
//#endregion
|
|
225
|
+
//#region src/slices/support_ticket/customer/components/CustomerMetadataCardEdit.vue
|
|
226
|
+
const _hoisted_1$2 = { class: "border border-base-200 rounded-lg p-4 md:p-6" };
|
|
227
|
+
const _hoisted_2$2 = { class: "grid grid-cols-1 md:grid-cols-2 gap-4" };
|
|
228
|
+
const _hoisted_3$1 = { class: "form-control md:col-span-2" };
|
|
229
|
+
const _hoisted_4$1 = ["disabled"];
|
|
230
|
+
const _hoisted_5$1 = {
|
|
231
|
+
key: 0,
|
|
232
|
+
class: "label"
|
|
233
|
+
};
|
|
234
|
+
const _hoisted_6$1 = { class: "form-control md:col-span-2" };
|
|
235
|
+
const _hoisted_7$1 = ["disabled"];
|
|
236
|
+
const _hoisted_8$1 = { class: "form-control" };
|
|
237
|
+
const _hoisted_9$1 = ["disabled"];
|
|
238
|
+
const _hoisted_10$1 = { class: "form-control" };
|
|
239
|
+
const _hoisted_11$1 = ["disabled"];
|
|
240
|
+
const _hoisted_12$1 = { class: "flex justify-end gap-2 mt-4" };
|
|
241
|
+
const _hoisted_13$1 = ["disabled"];
|
|
242
|
+
const _hoisted_14$1 = ["disabled"];
|
|
243
|
+
const _hoisted_15 = {
|
|
244
|
+
key: 0,
|
|
245
|
+
class: "loading loading-spinner loading-xs mr-2"
|
|
246
|
+
};
|
|
247
|
+
const _sfc_main$2 = /* @__PURE__ */ defineComponent({
|
|
248
|
+
__name: "CustomerMetadataCardEdit",
|
|
249
|
+
props: {
|
|
250
|
+
ticket: {},
|
|
251
|
+
saving: { type: Boolean }
|
|
252
|
+
},
|
|
253
|
+
emits: ["save", "cancel"],
|
|
254
|
+
setup(__props, { emit: __emit }) {
|
|
255
|
+
const props = __props;
|
|
256
|
+
const emit = __emit;
|
|
257
|
+
const formData = reactive({
|
|
258
|
+
title: props.ticket.title || "",
|
|
259
|
+
description: props.ticket.description || "",
|
|
260
|
+
type: props.ticket.type,
|
|
261
|
+
priority: supportTicketPriorityToNumber(props.ticket.priority)
|
|
262
|
+
});
|
|
263
|
+
const titleError = computed(() => {
|
|
264
|
+
return formData.title.trim() === "";
|
|
265
|
+
});
|
|
266
|
+
function handleSave() {
|
|
267
|
+
if (titleError.value) return;
|
|
268
|
+
emit("save", {
|
|
269
|
+
id: props.ticket.id,
|
|
270
|
+
title: formData.title.trim(),
|
|
271
|
+
description: formData.description || "",
|
|
272
|
+
type: formData.type,
|
|
273
|
+
priority: formData.priority
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
function handleCancel() {
|
|
277
|
+
emit("cancel");
|
|
278
|
+
}
|
|
279
|
+
return (_ctx, _cache) => {
|
|
280
|
+
return openBlock(), createElementBlock("div", _hoisted_1$2, [
|
|
281
|
+
createElementVNode("div", _hoisted_2$2, [
|
|
282
|
+
createCommentVNode(" Title - full width "),
|
|
283
|
+
createElementVNode("div", _hoisted_3$1, [
|
|
284
|
+
_cache[5] || (_cache[5] = createElementVNode("label", { class: "label" }, [createElementVNode("span", { class: "label-text font-medium" }, "Title")], -1)),
|
|
285
|
+
withDirectives(createElementVNode("input", {
|
|
286
|
+
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => formData.title = $event),
|
|
287
|
+
type: "text",
|
|
288
|
+
class: normalizeClass(["input input-bordered w-full", { "input-error": titleError.value }]),
|
|
289
|
+
placeholder: "Enter ticket title",
|
|
290
|
+
disabled: __props.saving
|
|
291
|
+
}, null, 10, _hoisted_4$1), [[vModelText, formData.title]]),
|
|
292
|
+
titleError.value ? (openBlock(), createElementBlock("label", _hoisted_5$1, [..._cache[4] || (_cache[4] = [createElementVNode("span", { class: "label-text-alt text-error" }, "Title is required.", -1)])])) : createCommentVNode("v-if", true)
|
|
293
|
+
]),
|
|
294
|
+
createCommentVNode(" Description - full width "),
|
|
295
|
+
createElementVNode("div", _hoisted_6$1, [_cache[6] || (_cache[6] = createElementVNode("label", { class: "label" }, [createElementVNode("span", { class: "label-text font-medium" }, "Description")], -1)), withDirectives(createElementVNode("textarea", {
|
|
296
|
+
"onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => formData.description = $event),
|
|
297
|
+
class: "textarea textarea-bordered w-full",
|
|
298
|
+
rows: "6",
|
|
299
|
+
placeholder: "Describe the ticket in detail",
|
|
300
|
+
disabled: __props.saving
|
|
301
|
+
}, null, 8, _hoisted_7$1), [[vModelText, formData.description]])]),
|
|
302
|
+
createCommentVNode(" Type "),
|
|
303
|
+
createElementVNode("div", _hoisted_8$1, [_cache[8] || (_cache[8] = createElementVNode("label", { class: "label" }, [createElementVNode("span", { class: "label-text font-medium" }, "Type")], -1)), withDirectives(createElementVNode("select", {
|
|
304
|
+
"onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => formData.type = $event),
|
|
305
|
+
class: "select select-bordered w-full",
|
|
306
|
+
disabled: __props.saving
|
|
307
|
+
}, [..._cache[7] || (_cache[7] = [
|
|
308
|
+
createElementVNode("option", { value: "IMPROVEMENT" }, "Improvement", -1),
|
|
309
|
+
createElementVNode("option", { value: "BUG" }, "Bug", -1),
|
|
310
|
+
createElementVNode("option", { value: "FEATURE_REQUEST" }, "Feature Request", -1),
|
|
311
|
+
createElementVNode("option", { value: "OPERATIONAL" }, "Operational", -1)
|
|
312
|
+
])], 8, _hoisted_9$1), [[vModelSelect, formData.type]])]),
|
|
313
|
+
createCommentVNode(" Priority "),
|
|
314
|
+
createElementVNode("div", _hoisted_10$1, [_cache[10] || (_cache[10] = createElementVNode("label", { class: "label" }, [createElementVNode("span", { class: "label-text font-medium" }, "Priority")], -1)), withDirectives(createElementVNode("select", {
|
|
315
|
+
"onUpdate:modelValue": _cache[3] || (_cache[3] = ($event) => formData.priority = $event),
|
|
316
|
+
class: "select select-bordered w-full",
|
|
317
|
+
disabled: __props.saving
|
|
318
|
+
}, [..._cache[9] || (_cache[9] = [
|
|
319
|
+
createElementVNode("option", { value: 1 }, "Low", -1),
|
|
320
|
+
createElementVNode("option", { value: 2 }, "Medium", -1),
|
|
321
|
+
createElementVNode("option", { value: 3 }, "High", -1),
|
|
322
|
+
createElementVNode("option", { value: 4 }, "Critical", -1)
|
|
323
|
+
])], 8, _hoisted_11$1), [[
|
|
324
|
+
vModelSelect,
|
|
325
|
+
formData.priority,
|
|
326
|
+
void 0,
|
|
327
|
+
{ number: true }
|
|
328
|
+
]])])
|
|
329
|
+
]),
|
|
330
|
+
createCommentVNode(" Action Buttons "),
|
|
331
|
+
createElementVNode("div", _hoisted_12$1, [createElementVNode("button", {
|
|
332
|
+
class: "btn btn-ghost",
|
|
333
|
+
onClick: handleCancel,
|
|
334
|
+
disabled: __props.saving
|
|
335
|
+
}, "Cancel", 8, _hoisted_13$1), createElementVNode("button", {
|
|
336
|
+
class: "btn btn-primary",
|
|
337
|
+
onClick: handleSave,
|
|
338
|
+
disabled: __props.saving
|
|
339
|
+
}, [__props.saving ? (openBlock(), createElementBlock("span", _hoisted_15)) : createCommentVNode("v-if", true), createTextVNode(" " + toDisplayString(__props.saving ? "Saving..." : "Save"), 1)], 8, _hoisted_14$1)])
|
|
340
|
+
]);
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
});
|
|
344
|
+
var CustomerMetadataCardEdit_default = _sfc_main$2;
|
|
345
|
+
|
|
346
|
+
//#endregion
|
|
347
|
+
//#region src/slices/support_ticket/customer/components/CustomerTimeline.vue
|
|
348
|
+
const _hoisted_1$1 = { class: "flex flex-col gap-4 w-full" };
|
|
349
|
+
const _hoisted_2$1 = {
|
|
350
|
+
key: 0,
|
|
351
|
+
class: "text-base-content/50 text-sm text-center py-8"
|
|
352
|
+
};
|
|
353
|
+
const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
354
|
+
__name: "CustomerTimeline",
|
|
355
|
+
props: {
|
|
356
|
+
ticket: {},
|
|
357
|
+
notes: {},
|
|
358
|
+
systemEvents: {},
|
|
359
|
+
commentsLocked: { type: Boolean },
|
|
360
|
+
onAddNote: { type: Function }
|
|
361
|
+
},
|
|
362
|
+
setup(__props, { expose: __expose }) {
|
|
363
|
+
const props = __props;
|
|
364
|
+
const noteInputRef = ref(null);
|
|
365
|
+
const mergedTimelineItems = computed(() => {
|
|
366
|
+
const items = [];
|
|
367
|
+
for (const note of props.notes ?? []) items.push({
|
|
368
|
+
type: "customer-note",
|
|
369
|
+
timestamp: note.createdAt,
|
|
370
|
+
id: `note-${note.createdAt}-${note.authorName}`,
|
|
371
|
+
data: note
|
|
372
|
+
});
|
|
373
|
+
for (const event of props.systemEvents ?? []) items.push({
|
|
374
|
+
type: "system-event",
|
|
375
|
+
timestamp: event.timestamp,
|
|
376
|
+
id: event.id,
|
|
377
|
+
data: event
|
|
378
|
+
});
|
|
379
|
+
items.sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime());
|
|
380
|
+
return items;
|
|
381
|
+
});
|
|
382
|
+
function resetInput() {
|
|
383
|
+
noteInputRef.value?.reset();
|
|
384
|
+
}
|
|
385
|
+
__expose({ resetInput });
|
|
386
|
+
return (_ctx, _cache) => {
|
|
387
|
+
return openBlock(), createElementBlock("div", _hoisted_1$1, [
|
|
388
|
+
createVNode(TimelineNoteInput_default, {
|
|
389
|
+
ref_key: "noteInputRef",
|
|
390
|
+
ref: noteInputRef,
|
|
391
|
+
"show-type-toggle": false,
|
|
392
|
+
disabled: __props.commentsLocked ?? false,
|
|
393
|
+
"on-submit": __props.onAddNote
|
|
394
|
+
}, null, 8, ["disabled", "on-submit"]),
|
|
395
|
+
mergedTimelineItems.value.length === 0 ? (openBlock(), createElementBlock("p", _hoisted_2$1, " No activity yet. ")) : createCommentVNode("v-if", true),
|
|
396
|
+
(openBlock(true), createElementBlock(Fragment, null, renderList(mergedTimelineItems.value, (item) => {
|
|
397
|
+
return openBlock(), createElementBlock(Fragment, { key: item.id }, [item.type === "customer-note" ? (openBlock(), createBlock(TimelineItem_default, {
|
|
398
|
+
key: 0,
|
|
399
|
+
"author-name": item.data.authorName,
|
|
400
|
+
"created-at": item.data.createdAt,
|
|
401
|
+
variant: "customer"
|
|
402
|
+
}, {
|
|
403
|
+
default: withCtx(() => [createTextVNode(toDisplayString(item.data.body ?? ""), 1)]),
|
|
404
|
+
_: 2
|
|
405
|
+
}, 1032, ["author-name", "created-at"])) : item.type === "system-event" ? (openBlock(), createBlock(TimelineSystemEvent_default, {
|
|
406
|
+
key: 1,
|
|
407
|
+
author: item.data.author,
|
|
408
|
+
message: item.data.message,
|
|
409
|
+
timestamp: item.data.timestamp,
|
|
410
|
+
"old-value": item.data.oldValue,
|
|
411
|
+
"new-value": item.data.newValue
|
|
412
|
+
}, null, 8, [
|
|
413
|
+
"author",
|
|
414
|
+
"message",
|
|
415
|
+
"timestamp",
|
|
416
|
+
"old-value",
|
|
417
|
+
"new-value"
|
|
418
|
+
])) : createCommentVNode("v-if", true)], 64);
|
|
419
|
+
}), 128))
|
|
420
|
+
]);
|
|
421
|
+
};
|
|
422
|
+
}
|
|
423
|
+
});
|
|
424
|
+
var CustomerTimeline_default = _sfc_main$1;
|
|
425
|
+
|
|
426
|
+
//#endregion
|
|
427
|
+
//#region src/slices/support_ticket/customer/CustomerSupportTicketDetailPage.vue
|
|
428
|
+
const _hoisted_1 = {
|
|
429
|
+
key: 0,
|
|
430
|
+
class: "flex justify-center items-center p-8"
|
|
431
|
+
};
|
|
432
|
+
const _hoisted_2 = { class: "alert alert-error mb-4 max-w-4xl mx-auto px-4" };
|
|
433
|
+
const _hoisted_3 = { class: "flex-1" };
|
|
434
|
+
const _hoisted_4 = { class: "mt-2" };
|
|
435
|
+
const _hoisted_5 = { class: "px-4 py-6 max-w-4xl mx-auto" };
|
|
436
|
+
const _hoisted_6 = { class: "mb-6" };
|
|
437
|
+
const _hoisted_7 = { class: "text-2xl font-bold text-base-content break-words leading-tight mt-2" };
|
|
438
|
+
const _hoisted_8 = { class: "mb-6" };
|
|
439
|
+
const _hoisted_9 = {
|
|
440
|
+
key: 0,
|
|
441
|
+
class: "flex gap-2 mb-6"
|
|
442
|
+
};
|
|
443
|
+
const _hoisted_10 = { class: "mb-6" };
|
|
444
|
+
const _hoisted_11 = { class: "mb-8" };
|
|
445
|
+
const _hoisted_12 = { class: "mb-8" };
|
|
446
|
+
const _hoisted_13 = {
|
|
447
|
+
key: 1,
|
|
448
|
+
class: "alert alert-error mb-4"
|
|
449
|
+
};
|
|
450
|
+
const _hoisted_14 = {
|
|
451
|
+
key: 2,
|
|
452
|
+
class: "flex justify-center items-center py-8"
|
|
453
|
+
};
|
|
454
|
+
const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
455
|
+
__name: "CustomerSupportTicketDetailPage",
|
|
456
|
+
props: {
|
|
457
|
+
ticket: {},
|
|
458
|
+
isLoading: { type: Boolean },
|
|
459
|
+
error: {}
|
|
460
|
+
},
|
|
461
|
+
setup(__props) {
|
|
462
|
+
const props = __props;
|
|
463
|
+
const route = useRoute();
|
|
464
|
+
const router = useRouter();
|
|
465
|
+
const support_ticket_id = route.params.id;
|
|
466
|
+
const isEditMode = computed(() => route.query.mode === "edit");
|
|
467
|
+
const isSaving = ref(false);
|
|
468
|
+
const refreshTicket = inject("refreshTicket");
|
|
469
|
+
const isLocked = computed(() => {
|
|
470
|
+
if (!props.ticket) return false;
|
|
471
|
+
return !!props.ticket.is_locked;
|
|
472
|
+
});
|
|
473
|
+
const isCommentsLocked = computed(() => {
|
|
474
|
+
if (!props.ticket) return false;
|
|
475
|
+
return !!props.ticket.archived_at;
|
|
476
|
+
});
|
|
477
|
+
const { data: timelineData, error: timelineError, refetch: refetchTimeline } = useQuery(async (api) => {
|
|
478
|
+
const [customerNotes, recordVersions] = await Promise.all([api.notes.getNotes({
|
|
479
|
+
record_id: {
|
|
480
|
+
operator: OPERATORS.EQUALS,
|
|
481
|
+
value: support_ticket_id
|
|
482
|
+
},
|
|
483
|
+
record_type: {
|
|
484
|
+
operator: OPERATORS.EQUALS,
|
|
485
|
+
value: "support_ticket"
|
|
486
|
+
},
|
|
487
|
+
is_internal: {
|
|
488
|
+
operator: OPERATORS.EQUALS,
|
|
489
|
+
value: false
|
|
490
|
+
},
|
|
491
|
+
first: 100,
|
|
492
|
+
sortBy: "created_at",
|
|
493
|
+
sortDirection: "asc"
|
|
494
|
+
}), api.recordVersions.listRecordVersionsCustomer(support_ticket_id, RecordConst.SUPPORT_TICKET, {
|
|
495
|
+
record_types: [RecordConst.SUPPORT_TICKET, RecordConst.SUPPORT_TICKET_ACTIVITY],
|
|
496
|
+
first: 100,
|
|
497
|
+
sortBy: "recorded_at",
|
|
498
|
+
sortDirection: "asc"
|
|
499
|
+
})]);
|
|
500
|
+
return {
|
|
501
|
+
customerNotes,
|
|
502
|
+
recordVersions
|
|
503
|
+
};
|
|
504
|
+
}, {
|
|
505
|
+
enabled: !!support_ticket_id && !!props.ticket,
|
|
506
|
+
batchMode: BATCH_MODE.batch,
|
|
507
|
+
trackedSegment: "customer-support-ticket-timeline"
|
|
508
|
+
});
|
|
509
|
+
const customerNotesForTimeline = computed(() => {
|
|
510
|
+
return (timelineData.value?.customerNotes?.items ?? []).map((n) => ({
|
|
511
|
+
authorName: n.created_by_display_name ?? n.created_by ?? "(unknown)",
|
|
512
|
+
createdAt: n.created_at,
|
|
513
|
+
body: n.body ?? ""
|
|
514
|
+
})).sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime());
|
|
515
|
+
});
|
|
516
|
+
const allSystemEvents = computed(() => {
|
|
517
|
+
const data = timelineData.value?.recordVersions;
|
|
518
|
+
const versions = data?.items ?? [];
|
|
519
|
+
const userDisplayMap = data?.user_display_map;
|
|
520
|
+
return parseRecordVersions(versions, userDisplayMap ? new Map(Object.entries(userDisplayMap)) : void 0);
|
|
521
|
+
});
|
|
522
|
+
const filteredSystemEvents = computed(() => {
|
|
523
|
+
if (!props.ticket) return [];
|
|
524
|
+
const events = allSystemEvents.value;
|
|
525
|
+
const isPending = props.ticket.status === "PENDING" || !props.ticket.is_locked;
|
|
526
|
+
const STAFF_ONLY_FIELDS = new Set([
|
|
527
|
+
"dev_lifecycle",
|
|
528
|
+
"delivered_value",
|
|
529
|
+
"start_at"
|
|
530
|
+
]);
|
|
531
|
+
return events.filter((event) => {
|
|
532
|
+
if (event.fieldName) {
|
|
533
|
+
if (STAFF_ONLY_FIELDS.has(event.fieldName)) return false;
|
|
534
|
+
if (isPending && event.fieldName === "credit_value") return false;
|
|
535
|
+
return true;
|
|
536
|
+
}
|
|
537
|
+
const message = event.message.toLowerCase();
|
|
538
|
+
if (message.includes("dev lifecycle") || message.includes("moved") || message.includes("delivered value") || message.includes("start date")) return false;
|
|
539
|
+
if (isPending && (message.includes("credits") || message.includes("credit"))) return false;
|
|
540
|
+
return true;
|
|
541
|
+
});
|
|
542
|
+
});
|
|
543
|
+
const { mutate: createNote } = useMutation((api, input) => api.notes.createNote(input), { invalidate: /^notes?:/ });
|
|
544
|
+
const { mutate: updateTicket } = useMutation((api, input) => api.supportTickets.updateTicket(input), { invalidate: /^support-tickets?:/ });
|
|
545
|
+
async function handleAddNote(payload) {
|
|
546
|
+
try {
|
|
547
|
+
await createNote({
|
|
548
|
+
record_id: support_ticket_id,
|
|
549
|
+
record_type: "support_ticket",
|
|
550
|
+
body: payload.content,
|
|
551
|
+
tag: null,
|
|
552
|
+
is_internal: false
|
|
553
|
+
});
|
|
554
|
+
await refetchTimeline();
|
|
555
|
+
toast.success("Comment added");
|
|
556
|
+
} catch {
|
|
557
|
+
toast.error("Failed to add comment");
|
|
558
|
+
throw new Error("Failed to add comment");
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
function enterEditMode() {
|
|
562
|
+
router.push({
|
|
563
|
+
name: route.name || "CustomerViewSupportTicket",
|
|
564
|
+
params: route.params,
|
|
565
|
+
query: {
|
|
566
|
+
...route.query,
|
|
567
|
+
mode: "edit"
|
|
568
|
+
}
|
|
569
|
+
});
|
|
570
|
+
}
|
|
571
|
+
async function exitEditMode() {
|
|
572
|
+
await router.push({
|
|
573
|
+
name: route.name || "CustomerViewSupportTicket",
|
|
574
|
+
params: route.params,
|
|
575
|
+
query: {
|
|
576
|
+
...route.query,
|
|
577
|
+
mode: void 0
|
|
578
|
+
}
|
|
579
|
+
});
|
|
580
|
+
}
|
|
581
|
+
async function handleSave(payload) {
|
|
582
|
+
isSaving.value = true;
|
|
583
|
+
try {
|
|
584
|
+
await updateTicket(payload);
|
|
585
|
+
await exitEditMode();
|
|
586
|
+
await nextTick();
|
|
587
|
+
toast.success("Ticket updated successfully");
|
|
588
|
+
if (refreshTicket) await refreshTicket();
|
|
589
|
+
} catch (e) {
|
|
590
|
+
const errorMessage = e instanceof Error ? e.message : "Failed to update ticket";
|
|
591
|
+
toast.error(errorMessage);
|
|
592
|
+
} finally {
|
|
593
|
+
isSaving.value = false;
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
return (_ctx, _cache) => {
|
|
597
|
+
const _component_router_link = resolveComponent("router-link");
|
|
598
|
+
return openBlock(), createElementBlock(Fragment, null, [createCommentVNode(" Loading State (only on initial load; refetch keeps content visible) "), __props.isLoading && !__props.ticket ? (openBlock(), createElementBlock("div", _hoisted_1, [..._cache[1] || (_cache[1] = [createElementVNode("span", { class: "loading loading-spinner loading-lg" }, null, -1)])])) : __props.error ? (openBlock(), createElementBlock(Fragment, { key: 1 }, [createCommentVNode(" Error State "), createElementVNode("div", _hoisted_2, [_cache[3] || (_cache[3] = createElementVNode("svg", {
|
|
599
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
600
|
+
class: "stroke-current shrink-0 h-6 w-6",
|
|
601
|
+
fill: "none",
|
|
602
|
+
viewBox: "0 0 24 24"
|
|
603
|
+
}, [createElementVNode("path", {
|
|
604
|
+
"stroke-linecap": "round",
|
|
605
|
+
"stroke-linejoin": "round",
|
|
606
|
+
"stroke-width": "2",
|
|
607
|
+
d: "M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z"
|
|
608
|
+
})], -1)), createElementVNode("div", _hoisted_3, [createElementVNode("span", null, toDisplayString(__props.error.message || "An error occurred"), 1), createElementVNode("div", _hoisted_4, [createVNode(_component_router_link, {
|
|
609
|
+
to: { name: "CustomerSupportTicketList" },
|
|
610
|
+
class: "link link-primary"
|
|
611
|
+
}, {
|
|
612
|
+
default: withCtx(() => [..._cache[2] || (_cache[2] = [createTextVNode(" Go back to ticket list ", -1)])]),
|
|
613
|
+
_: 1
|
|
614
|
+
})])])])], 2112)) : __props.ticket ? (openBlock(), createElementBlock(Fragment, { key: 2 }, [createCommentVNode(" Main Content "), createElementVNode("div", _hoisted_5, [
|
|
615
|
+
createCommentVNode(" Header "),
|
|
616
|
+
createElementVNode("div", _hoisted_6, [createElementVNode("h1", _hoisted_7, toDisplayString(__props.ticket.title), 1)]),
|
|
617
|
+
createCommentVNode(" Action Banner "),
|
|
618
|
+
createElementVNode("div", _hoisted_8, [createVNode(CustomerActionBanner_default, { ticket: __props.ticket }, null, 8, ["ticket"])]),
|
|
619
|
+
createCommentVNode(" Edit / Cancel "),
|
|
620
|
+
!isLocked.value && !isCommentsLocked.value ? (openBlock(), createElementBlock("div", _hoisted_9, [!isEditMode.value ? (openBlock(), createElementBlock("button", {
|
|
621
|
+
key: 0,
|
|
622
|
+
onClick: enterEditMode,
|
|
623
|
+
class: "btn btn-sm"
|
|
624
|
+
}, [..._cache[4] || (_cache[4] = [createElementVNode("svg", {
|
|
625
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
626
|
+
fill: "none",
|
|
627
|
+
viewBox: "0 0 24 24",
|
|
628
|
+
"stroke-width": "1.5",
|
|
629
|
+
stroke: "currentColor",
|
|
630
|
+
class: "w-4 h-4 mr-2"
|
|
631
|
+
}, [createElementVNode("path", {
|
|
632
|
+
"stroke-linecap": "round",
|
|
633
|
+
"stroke-linejoin": "round",
|
|
634
|
+
d: "M16.862 4.487l1.687-1.688a1.875 1.875 0 112.652 2.652L10.582 16.07a4.5 4.5 0 01-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 011.13-1.897l8.932-8.931zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0115.75 21H5.25A2.25 2.25 0 013 18.75V8.25A2.25 2.25 0 015.25 6H10"
|
|
635
|
+
})], -1), createTextVNode(" Edit ", -1)])])) : (openBlock(), createElementBlock("button", {
|
|
636
|
+
key: 1,
|
|
637
|
+
onClick: exitEditMode,
|
|
638
|
+
class: "btn btn-sm"
|
|
639
|
+
}, [..._cache[5] || (_cache[5] = [createElementVNode("svg", {
|
|
640
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
641
|
+
fill: "none",
|
|
642
|
+
viewBox: "0 0 24 24",
|
|
643
|
+
"stroke-width": "1.5",
|
|
644
|
+
stroke: "currentColor",
|
|
645
|
+
class: "w-4 h-4 mr-2"
|
|
646
|
+
}, [createElementVNode("path", {
|
|
647
|
+
"stroke-linecap": "round",
|
|
648
|
+
"stroke-linejoin": "round",
|
|
649
|
+
d: "M6 18L18 6M6 6l12 12"
|
|
650
|
+
})], -1), createTextVNode(" Cancel ", -1)])]))])) : createCommentVNode("v-if", true),
|
|
651
|
+
createCommentVNode(" Subscribe / Unsubscribe "),
|
|
652
|
+
createElementVNode("div", _hoisted_10, [createVNode(CustomerSupportTicketSubscribeControl_default, { ticket: __props.ticket }, null, 8, ["ticket"])]),
|
|
653
|
+
createCommentVNode(" Metadata Card (Display or Edit) "),
|
|
654
|
+
createElementVNode("div", _hoisted_11, [!isEditMode.value ? (openBlock(), createBlock(CustomerMetadataCard_default, {
|
|
655
|
+
key: 0,
|
|
656
|
+
ticket: __props.ticket
|
|
657
|
+
}, null, 8, ["ticket"])) : (openBlock(), createBlock(CustomerMetadataCardEdit_default, {
|
|
658
|
+
key: 1,
|
|
659
|
+
ticket: __props.ticket,
|
|
660
|
+
saving: isSaving.value,
|
|
661
|
+
onSave: handleSave,
|
|
662
|
+
onCancel: exitEditMode
|
|
663
|
+
}, null, 8, ["ticket", "saving"]))]),
|
|
664
|
+
createCommentVNode(" Attachments (separate from timeline so adding a comment doesn't cause refetch) "),
|
|
665
|
+
createElementVNode("div", _hoisted_12, [createVNode(SupportTicketAttachmentsCollapsible_default, {
|
|
666
|
+
"record-id": __props.ticket.id,
|
|
667
|
+
locked: isCommentsLocked.value,
|
|
668
|
+
editable: !isCommentsLocked.value,
|
|
669
|
+
onUploaded: unref(refetchTimeline),
|
|
670
|
+
onDeleted: unref(refetchTimeline)
|
|
671
|
+
}, null, 8, [
|
|
672
|
+
"record-id",
|
|
673
|
+
"locked",
|
|
674
|
+
"editable",
|
|
675
|
+
"onUploaded",
|
|
676
|
+
"onDeleted"
|
|
677
|
+
])]),
|
|
678
|
+
createCommentVNode(" Timeline: stay mounted once we have data so adding a comment doesn't unmount/remount "),
|
|
679
|
+
createElementVNode("div", null, [unref(timelineData) != null ? (openBlock(), createBlock(CustomerTimeline_default, {
|
|
680
|
+
key: 0,
|
|
681
|
+
ticket: __props.ticket,
|
|
682
|
+
notes: customerNotesForTimeline.value,
|
|
683
|
+
"system-events": filteredSystemEvents.value,
|
|
684
|
+
"comments-locked": isCommentsLocked.value,
|
|
685
|
+
"on-add-note": handleAddNote
|
|
686
|
+
}, null, 8, [
|
|
687
|
+
"ticket",
|
|
688
|
+
"notes",
|
|
689
|
+
"system-events",
|
|
690
|
+
"comments-locked"
|
|
691
|
+
])) : unref(timelineError) ? (openBlock(), createElementBlock("div", _hoisted_13, [createElementVNode("span", null, toDisplayString(unref(timelineError)?.message ?? "Failed to load timeline"), 1), createElementVNode("button", {
|
|
692
|
+
class: "btn btn-sm btn-outline mt-2",
|
|
693
|
+
onClick: _cache[0] || (_cache[0] = (...args) => unref(refetchTimeline) && unref(refetchTimeline)(...args))
|
|
694
|
+
}, " Retry ")])) : (openBlock(), createElementBlock("div", _hoisted_14, [..._cache[6] || (_cache[6] = [createElementVNode("span", { class: "loading loading-spinner loading-lg" }, null, -1)])]))])
|
|
695
|
+
])], 2112)) : createCommentVNode("v-if", true)], 2112);
|
|
696
|
+
};
|
|
697
|
+
}
|
|
698
|
+
});
|
|
699
|
+
var CustomerSupportTicketDetailPage_default = _sfc_main;
|
|
700
|
+
|
|
701
|
+
//#endregion
|
|
702
|
+
export { CustomerSupportTicketDetailPage_default as default };
|
|
703
|
+
//# sourceMappingURL=CustomerSupportTicketDetailPage-DQa_Zvfe.js.map
|