1import TicketPriority from "@/components/TicketPriority.vue";
2import { useTicketPriorityStore } from "@/stores/ticketPriority";
3import { useTicketStatusStore } from "@/stores/ticketStatus";
4import { __ } from "@/translation";
5import type { Command } from "./paletteTypes";
6
7interface OptionListConfig {
8 /** Group heading, and the verb the rows read as: "Set status", "Filter by status". */
9 group: string;
10 onPick: (value: string) => void;
11 /** Ticks the row already in effect. */
12 current?: string | undefined;
13 /** "<prefix>: <value>" for root rows, where a bare "Urgent" is ambiguous. */
14 titlePrefix?: string | undefined;
15 hideWhenEmpty?: boolean | undefined;
16 weight?: number | undefined;
17}
18
19/** Shared by "Set status" and "Filter by status" — same options, different verb. */
20export function statusOptions(config: OptionListConfig): Command[] {
21 const statuses = useTicketStatusStore().statuses.data ?? [];
22 return statuses
23 .filter((status) => status.enabled)
24 .map((status) => ({
25 ...optionRow(config, status.label_agent),
26 id: `status-${status.label_agent}`,
27 dotClass: status.parsed_color,
28 }));
29}
30
31export function priorityOptions(config: OptionListConfig): Command[] {
32 const priorities = useTicketPriorityStore().priorities.data ?? [];
33 return priorities
34 .filter((priority) => !priority.disabled)
35 .map((priority) => ({
36 ...optionRow(config, priority.name),
37 id: `priority-${priority.name}`,
38 // The app's own level-aware icon, not a flat flag for every priority.
39 icon: TicketPriority,
40 iconProps: { priority: priority.name, iconOnly: true },
41 }));
42}
43
44/** Live option names as parent keywords — site-defined values a hardcoded list
45 * would miss. Empty until the store resolves; the title still matches. */
46export function statusKeywords(): string {
47 return (useTicketStatusStore().statuses.data ?? [])
48 .filter((status) => status.enabled)
49 .map((status) => status.label_agent)
50 .join(" ");
51}
52
53export function priorityKeywords(): string {
54 return (useTicketPriorityStore().priorities.data ?? [])
55 .filter((priority) => !priority.disabled)
56 .map((priority) => priority.name)
57 .join(" ");
58}
59
60function optionRow(config: OptionListConfig, value: string): Command {
61 const label = __(value);
62 return {
63 id: value,
64 title: config.titlePrefix ? `${__(config.titlePrefix)}: ${label}` : label,
65 group: config.group,
66 checked: value === config.current,
67 perform: () => config.onPick(value),
68 ...(config.hideWhenEmpty ? { hideWhenEmpty: true } : {}),
69 ...(config.weight ? { weight: config.weight } : {}),
70 // Matches "urgent" typed on its own, not just the composed title.
71 ...(config.titlePrefix ? { keywords: value } : {}),
72 };
73}
74