1import { type ActionOption } from "@/components/Settings/SavedReplies/components/actionTypes";
2import { useTags, type Tag } from "@/composables/useTags";
3import { useAgentStore } from "@/stores/agent";
4import { useAuthStore } from "@/stores/auth";
5import { useConfigStore } from "@/stores/config";
6import { useTicketPriorityStore } from "@/stores/ticketPriority";
7import { useTicketStatusStore } from "@/stores/ticketStatus";
8import { SavedReplyActionType } from "@/types";
9import { storeToRefs } from "pinia";
10import { computed } from "vue";
11
12let shared: ReturnType<typeof buildActionOptions> | undefined;
13
14/**
15 * The pickable values for each saved reply action type. Shared so the settings
16 * editor and the reply composer offer the same list instead of each building
17 * its own. Built once: every action chip calls this, and a resource per caller
18 * means a list request per chip.
19 */
20export function useSavedReplyActionOptions() {
21 return (shared ??= buildActionOptions());
22}
23
24function buildActionOptions() {
25 const statusStore = useTicketStatusStore();
26 const priorityStore = useTicketPriorityStore();
27 const agentStore = useAgentStore();
28 const { tagListResource } = useTags();
29 const { teamRestrictionApplied } = storeToRefs(useConfigStore());
30 const { userTeams, isAdmin } = storeToRefs(useAuthStore());
31
32 /** Server-side filters for the link pickers, which search as you type. */
33 function linkFilters(type: SavedReplyActionType): Record<string, unknown> {
34 const filters: Record<string, unknown> = { disabled: 0 };
35 // A restricted agent can only route to their own teams
36 if (type === "Set Team" && !isAdmin.value && teamRestrictionApplied.value) {
37 filters.name = ["in", userTeams.value || []];
38 }
39 return filters;
40 }
41
42 /** Tags as a plain list; callers filter it further if they need to. */
43 function tagOptions(): ActionOption[] {
44 return ((tagListResource.data || []) as Tag[]).map((tag) => ({
45 label: tag.name,
46 value: tag.name,
47 color: tag.color,
48 }));
49 }
50
51 function valueOptions(type: SavedReplyActionType): ActionOption[] {
52 switch (type) {
53 case "Set Status":
54 return (statusStore.statuses.data || [])
55 .filter((status) => status.enabled)
56 .map((status) => ({
57 label: status.label_agent,
58 value: status.label_agent,
59 }));
60 case "Set Priority":
61 return (priorityStore.priorities.data || [])
62 .filter((priority) => !priority.disabled)
63 .map((priority) => ({ label: priority.name, value: priority.name }));
64 case "Assign Agent":
65 return agentStore.dropdown || [];
66 case "Add Tag":
67 case "Remove Tag":
68 return tagOptions();
69 default:
70 return [];
71 }
72 }
73
74 if (!agentStore.agents.data) agentStore.agents.fetch();
75
76 return { valueOptions, tagOptions, linkFilters };
77}
78