1import { useTags, type Tag } from "@/composables/useTags";
2import { reloadTicketFeed, useTicket } from "@/composables/useTicket";
3import { __ } from "@/translation";
4import { call, toast } from "frappe-ui";
5import type { Command } from "./paletteTypes";
6
7import LucideTags from "~icons/lucide/tags";
8
9/** Toggle list: applied tags ticked; Enter flips one and pops back a level. */
10export async function tagChildren(ticketId: string): Promise<Command[]> {
11 const { tagListResource } = useTags();
12 // Always refetch: tags can be created mid-session from the sidebar picker.
13 await tagListResource.reload();
14 const applied = appliedTags(ticketId);
15 return (tagListResource.data ?? []).map((tag: Tag) => ({
16 id: `tag-${tag.name}`,
17 title: tag.name,
18 group: "Tags",
19 icon: LucideTags,
20 checked: applied.has(tag.name),
21 keepOpen: true,
22 perform: () => toggleTag(ticketId, tag),
23 }));
24}
25
26/** `_user_tags` is a comma-joined column, sometimes with a leading comma. */
27function appliedTags(ticketId: string): Set<string> {
28 const raw = useTicket(ticketId).ticket.doc?._user_tags ?? "";
29 return new Set(
30 raw
31 .split(",")
32 .map((tag: string) => tag.trim())
33 .filter(Boolean)
34 );
35}
36
37/** Applied state is read at call time, so toggling the same row twice works. */
38async function toggleTag(ticketId: string, tag: Tag): Promise<void> {
39 const applied = appliedTags(ticketId).has(tag.name);
40 try {
41 const userTags = await call("opendesk.api.tags.update_tags", {
42 doctype: "OD Ticket",
43 name: ticketId,
44 added: applied ? [] : [{ name: tag.name, color: tag.color || "Gray" }],
45 removed: applied ? [tag.name] : [],
46 });
47 const { ticket } = useTicket(ticketId);
48 // The response carries the new _user_tags: one round trip, no doc reload.
49 if (ticket.doc) ticket.doc._user_tags = userTags;
50 reloadTicketFeed(ticketId);
51 } catch (error: any) {
52 toast.error(error?.messages?.join(", ") || __("Failed to update tags"));
53 throw error; // the palette flips the optimistic tick back
54 }
55}
56