Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: ticket tags #1602

Merged
merged 4 commits into from
Oct 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 0 additions & 64 deletions desk/src/pages/ticket/TicketActions.vue

This file was deleted.

130 changes: 130 additions & 0 deletions desk/src/pages/ticket/TicketActionsTags.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
<template>
<div class="flex flex-col border-l">
<TicketSidebarHeader title="Actions & Tags" />
<span class="space-y-4 p-5">
<div class="space-y-2">
<div class="text-base font-medium">Actions</div>
<div class="flex flex-wrap gap-2 overflow-auto">
<span v-if="!actions.data" class="text-base">Nothing to show</span>
<Button
v-for="a in actions.data"
:key="a.name"
:label="a.button_label"
theme="gray"
variant="subtle"
@click="() => eic.call(ticket.data, a.action)"
>
<template v-if="a.button_icon" #prefix>
<Icon :icon="a.button_icon" />
</template>
<template v-if="a.is_external_link" #suffix>
<LucideExternalLink class="h-4 w-4" />
</template>
</Button>
</div>
</div>
<div class="space-y-2">
<div class="text-base font-medium">Tags</div>
<div class="flex flex-wrap gap-2 overflow-auto">
<Button
v-for="tag in ticket.data.tags"
:key="tag.name"
:label="tag"
theme="gray"
variant="outline"
>
<template #suffix>
<LucideX class="h-4 w-4" @click="rmTag.submit({ tag })" />
</template>
</Button>
<FormControl
v-if="showInput"
type="text"
placeholder="Tag"
autofocus
@keydown.enter="addTag.submit({ tag: $event.target.value })"
@keydown.esc="showInput = false"
>
<template #prefix>
<LucideTag class="h-4 w-4" />
</template>
</FormControl>
<Button
v-else
theme="gray"
variant="outline"
@click="() => (showInput = true)"
>
<template #icon>
<LucidePlus class="h-4 w-4" />
</template>
</Button>
</div>
</div>
</span>
</div>
</template>

<script setup lang="ts">
import { inject, ref } from "vue";
import { createResource, createListResource } from "frappe-ui";
import TicketSidebarHeader from "./TicketSidebarHeader.vue";
import { ITicket } from "./symbols";

const ticket = inject(ITicket);
const actions = createListResource({
doctype: "HD Action",
auto: true,
cache: "Actions",
filters: {
is_enabled: true,
},
fields: [
"name",
"button_label",
"button_icon",
"is_external_link",
"action",
"cond_hidden",
],
transform: (data) => {
const res = [];
for (const row of data) {
const isHidden = eic.call(ticket.data, row.cond_hidden);
if (!isHidden) res.push(row);
}
return res;
},
});
const showInput = ref(false);
const addTag = createResource({
url: "frappe.desk.doctype.tag.tag.add_tag",
debounce: 300,
makeParams: (params) => ({
tag: params.tag,
dt: "HD Ticket",
dn: ticket.data.name,
}),
onSuccess: () => {
ticket.reload().then(() => (showInput.value = false));
},
});
const rmTag = createResource({
url: "frappe.desk.doctype.tag.tag.remove_tag",
debounce: 300,
makeParams: (params) => ({
tag: params.tag,
dt: "HD Ticket",
dn: ticket.data.name,
}),
onSuccess: () => ticket.reload(),
});

/**
* Wrapper function for eval. Can be used with `.call()`. Helps in
* forcing context
*/
function eic(s: string) {
return eval(s);
}
</script>
10 changes: 5 additions & 5 deletions desk/src/pages/ticket/TicketAgentSidebar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -46,16 +46,16 @@
import { ref } from "vue";
import { Tooltip } from "frappe-ui";
import { TabGroup, TabList, Tab, TabPanels, TabPanel } from "@headlessui/vue";
import TicketActions from "./TicketActions.vue";
import TicketActionsTags from "./TicketActionsTags.vue";
import TicketContact from "./TicketContact.vue";
import TicketDetails from "./TicketDetails.vue";
import TicketHistory from "./TicketHistory.vue";
import TicketViews from "./TicketViews.vue";
import LucideInfo from "~icons/lucide/info";
import LucideContact2 from "~icons/lucide/contact-2";
import LucideHistory from "~icons/lucide/history";
import LucideView from "~icons/lucide/view";
import LucideInfo from "~icons/lucide/info";
import LucidePointer from "~icons/lucide/pointer";
import LucideView from "~icons/lucide/view";

const isExpanded = ref(true);
const items = [
Expand All @@ -65,8 +65,8 @@ const items = [
icon: LucideInfo,
},
{
name: "Actions",
component: TicketActions,
name: "Actions & Tags",
component: TicketActionsTags,
icon: LucidePointer,
},
{
Expand Down
19 changes: 18 additions & 1 deletion helpdesk/helpdesk/doctype/hd_ticket/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,11 @@ def get_one(name):
return {
**ticket,
"assignee": get_assignee(ticket._assign),
"communications": get_communications(name),
"comments": get_comments(name),
"communications": get_communications(name),
"contact": contact,
"history": get_history(name),
"tags": get_tags(name),
"template": get_template(ticket.template or DEFAULT_TICKET_TEMPLATE),
"views": get_views(name),
}
Expand Down Expand Up @@ -171,6 +172,22 @@ def get_views(ticket: str):
return views


def get_tags(ticket: str):
QBTag = frappe.qb.DocType("Tag Link")
rows = (
frappe.qb.from_(QBTag)
.select(QBTag.tag)
.where(QBTag.document_type == "HD Ticket")
.where(QBTag.document_name == ticket)
.orderby(QBTag.creation, order=Order.asc)
.run(as_dict=True)
)
res = []
for tag in rows:
res.append(tag.tag)
return res


@redis_cache()
def get_attachments(doctype, name):
QBFile = frappe.qb.DocType("File")
Expand Down
53 changes: 42 additions & 11 deletions helpdesk/helpdesk/doctype/hd_ticket/hd_ticket.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"sb_details",
"description",
"template",
"sla_tab",
"service_level_section",
"sla",
"response_by",
Expand All @@ -29,11 +30,13 @@
"service_level_agreement_creation",
"on_hold_since",
"total_hold_time",
"response_tab",
"response",
"first_response_time",
"first_responded_on",
"column_break_26",
"avg_response_time",
"resolution_tab",
"section_break_19",
"resolution_details",
"column_break1",
Expand All @@ -42,6 +45,7 @@
"resolution_date",
"resolution_time",
"user_resolution_time",
"reference_tab",
"additional_info",
"contact",
"customer",
Expand All @@ -50,11 +54,13 @@
"via_customer_portal",
"attachment",
"content_type",
"feedback_tab",
"customer_feedback_section",
"feedback_rating",
"feedback_text",
"feedback",
"feedback_extra"
"feedback_extra",
"meta_tab"
],
"fields": [
{
Expand Down Expand Up @@ -152,8 +158,7 @@
{
"collapsible": 1,
"fieldname": "service_level_section",
"fieldtype": "Section Break",
"label": "SLA Details"
"fieldtype": "Section Break"
},
{
"fieldname": "sla",
Expand Down Expand Up @@ -212,8 +217,7 @@
{
"collapsible": 1,
"fieldname": "response",
"fieldtype": "Section Break",
"label": "Response Details"
"fieldtype": "Section Break"
},
{
"bold": 1,
Expand Down Expand Up @@ -241,8 +245,7 @@
{
"collapsible": 1,
"fieldname": "section_break_19",
"fieldtype": "Section Break",
"label": "Resolution Details"
"fieldtype": "Section Break"
},
{
"depends_on": "eval:!doc.__islocal",
Expand Down Expand Up @@ -305,7 +308,6 @@
"collapsible": 1,
"fieldname": "additional_info",
"fieldtype": "Section Break",
"label": "Reference",
"options": "fa fa-pushpin",
"read_only": 1
},
Expand Down Expand Up @@ -351,8 +353,7 @@
},
{
"fieldname": "customer_feedback_section",
"fieldtype": "Section Break",
"label": "Customer Feedback"
"fieldtype": "Section Break"
},
{
"fieldname": "feedback_extra",
Expand All @@ -374,12 +375,42 @@
"fieldname": "feedback_text",
"fieldtype": "Data",
"label": "Feedback (Text)"
},
{
"fieldname": "sla_tab",
"fieldtype": "Tab Break",
"label": "SLA"
},
{
"fieldname": "response_tab",
"fieldtype": "Tab Break",
"label": "Response"
},
{
"fieldname": "resolution_tab",
"fieldtype": "Tab Break",
"label": "Resolution"
},
{
"fieldname": "reference_tab",
"fieldtype": "Tab Break",
"label": "Reference"
},
{
"fieldname": "feedback_tab",
"fieldtype": "Tab Break",
"label": "Feedback"
},
{
"fieldname": "meta_tab",
"fieldtype": "Tab Break",
"label": "Meta"
}
],
"icon": "fa fa-issue",
"idx": 61,
"links": [],
"modified": "2023-10-17 16:20:41.301974",
"modified": "2023-10-19 19:23:07.571029",
"modified_by": "Administrator",
"module": "Helpdesk",
"name": "HD Ticket",
Expand Down