1import TicketPriority from "@/components/TicketPriority.vue";
2import { router } from "@/router";
3import { GROUP, stripTags, type Command, type SearchItem } from "./paletteTypes";
4
5/** Server full-text hits; `rank` keeps the server's relevance order. */
6export function searchCommands(items: SearchItem[]): Command[] {
7 return items.map((item, index) => ({
8 id: `search-${item.doctype}-${item.name}`,
9 title: stripTags(item.title || item.content || item.name),
10 // The index's own highlighting — it knows which words matched.
11 marked: item.title || item.content || item.name,
12 subtitle: searchSubtitle(item),
13 icon: TicketPriority,
14 iconProps: { priority: item.priority, iconOnly: true },
15 group: GROUP.results,
16 rank: 950 - index,
17 perform: () => router.push(routeForSearchItem(item)),
18 }));
19}
20
21/** "Open · #0484" — enough to tell apart tickets sharing a subject. */
22function searchSubtitle(item: SearchItem): string {
23 const ticketId = ticketIdOf(item);
24 return [item.status, ticketId && `#${ticketId}`].filter(Boolean).join(" · ");
25}
26
27function ticketIdOf(item: SearchItem): string {
28 if (item.doctype === "OD Ticket") return item.name;
29 return item.reference_ticket || item.reference_name || "";
30}
31
32function routeForSearchItem(item: SearchItem) {
33 const ticketId = ticketIdOf(item);
34 if (item.doctype === "OD Ticket") {
35 return { name: "TicketAgent", params: { ticketId } };
36 }
37 const prefix =
38 item.doctype === "Comment" ? "comment" : "communication";
39 return {
40 name: "TicketAgent",
41 params: { ticketId },
42 hash: "#activity",
43 query: { highlight: `${prefix}-${item.name}` },
44 };
45}
46