Skip to content

Commit

Permalink
Merge pull request #1980 from frappe/develop
Browse files Browse the repository at this point in the history
chore(release): dev to main
  • Loading branch information
RitvikSardana authored Sep 13, 2024
2 parents 4c62192 + b882193 commit 39faab9
Show file tree
Hide file tree
Showing 14 changed files with 270 additions and 28 deletions.
30 changes: 15 additions & 15 deletions desk/src/components/Settings/Branding.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<p class="text-sm text-gray-600">{{ config.title }}</p>
<div class="flex gap-4 items-center">
<Avatar
v-if="config.image && !websiteSettings.loading"
v-if="config.image && !config.loading"
size="3xl"
:image="config.image"
/>
Expand Down Expand Up @@ -51,9 +51,22 @@ import { createToast } from "@/utils";
const config = useConfigStore();
const websiteSettings = createResource({
url: "frappe.client.get_value",
cache: true,
params: {
doctype: "Website Settings",
fieldname: "favicon",
},
onSuccess(data) {
state.brandFavicon = data.favicon;
},
auto: true,
});
const state = reactive({
brandLogo: config.brandLogo,
brandFavicon: "",
brandFavicon: websiteSettings.data?.favicon || "",
});
const loadingState = reactive({
Expand All @@ -78,19 +91,6 @@ const brandingConfig = computed(() => [
},
]);
const websiteSettings = createResource({
url: "frappe.client.get_value",
cache: true,
params: {
doctype: "Website Settings",
fieldname: "favicon",
},
onSuccess(data) {
state.brandFavicon = data.favicon;
},
auto: true,
});
const settingsResource = createResource({
url: "frappe.client.set_value",
debounce: 1000,
Expand Down
2 changes: 1 addition & 1 deletion desk/src/pages/ticket/TicketNewArticles.vue
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
class="focus:ring-cyan-30 rounded-md border-2 border-hidden p-4 hover:bg-cyan-100 focus:outline-none focus:ring active:bg-cyan-50"
>
<RouterLink
class="group cursor-pointer space-x-1 hover:text-gray-900"
class="group cursor-pointer hover:text-gray-900"
:to="{
name: 'KBArticlePublic',
params: {
Expand Down
27 changes: 22 additions & 5 deletions helpdesk/api/article.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,41 @@
import frappe
from textblob import TextBlob
from textblob.exceptions import MissingCorpusError

from helpdesk.search import search as hd_search


def get_nouns(text: str):
blob = TextBlob(text)
def get_nouns(blob: TextBlob):
try:
return [word for word, pos in blob.pos_tags if pos[0] == "N"]
except LookupError:
return []


def get_noun_phrases(blob: TextBlob):
try:
return blob.noun_phrases
except (LookupError, MissingCorpusError):
return []


@frappe.whitelist()
def search(query: str):
out = hd_search(query, only_articles=True)
if not out: # fallback
if nouns := get_nouns(query):
query = " ".join(nouns)
out = hd_search(query, only_articles=True)
blob = TextBlob(query)
if noun_phrases := get_noun_phrases(blob):
and_query = " ".join(noun_phrases)
or_query = "|".join(noun_phrases)
out = hd_search(and_query, only_articles=True) or hd_search(
or_query, only_articles=True
)
if not out and (nouns := get_nouns(blob)):
and_query = " ".join(nouns)
or_query = "|".join(nouns)
out = hd_search(and_query, only_articles=True) or hd_search(
or_query, only_articles=True
)
if not out:
return []
return out[0].get("items", [])
6 changes: 6 additions & 0 deletions helpdesk/helpdesk/doctype/hd_settings/hd_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,9 @@ def on_update(self):
room = get_website_room()

frappe.publish_realtime(event, room=room, after_commit=True)

@property
def hd_search(self):
from helpdesk.api.article import search

return search
Empty file.
8 changes: 8 additions & 0 deletions helpdesk/helpdesk/doctype/hd_stopword/hd_stopword.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// Copyright (c) 2024, Frappe Technologies and contributors
// For license information, please see license.txt

// frappe.ui.form.on("HD Stopword", {
// refresh(frm) {

// },
// });
56 changes: 56 additions & 0 deletions helpdesk/helpdesk/doctype/hd_stopword/hd_stopword.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
{
"actions": [],
"allow_rename": 1,
"autoname": "field:word",
"creation": "2024-09-12 16:08:27.022111",
"doctype": "DocType",
"engine": "InnoDB",
"field_order": [
"word",
"column_break_jyol",
"enabled"
],
"fields": [
{
"fieldname": "word",
"fieldtype": "Data",
"label": "Word",
"unique": 1
},
{
"default": "1",
"fieldname": "enabled",
"fieldtype": "Check",
"label": "Enabled"
},
{
"fieldname": "column_break_jyol",
"fieldtype": "Column Break"
}
],
"index_web_pages_for_search": 1,
"links": [],
"modified": "2024-09-12 16:10:05.577545",
"modified_by": "Administrator",
"module": "Helpdesk",
"name": "HD Stopword",
"naming_rule": "By fieldname",
"owner": "Administrator",
"permissions": [
{
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "System Manager",
"share": 1,
"write": 1
}
],
"sort_field": "creation",
"sort_order": "DESC",
"states": []
}
9 changes: 9 additions & 0 deletions helpdesk/helpdesk/doctype/hd_stopword/hd_stopword.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Copyright (c) 2024, Frappe Technologies and contributors
# For license information, please see license.txt

# import frappe
from frappe.model.document import Document


class HDStopword(Document):
pass
9 changes: 9 additions & 0 deletions helpdesk/helpdesk/doctype/hd_stopword/test_hd_stopword.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Copyright (c) 2024, Frappe Technologies and Contributors
# See license.txt

# import frappe
from frappe.tests.utils import FrappeTestCase


class TestHDStopword(FrappeTestCase):
pass
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Copyright (c) 2024, Frappe Technologies and contributors
// For license information, please see license.txt

frappe.query_reports["Ticket-Search Analysis"] = {
filters: [
// {
// "fieldname": "my_filter",
// "label": __("My Filter"),
// "fieldtype": "Data",
// "reqd": 1,
// },
],
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"add_total_row": 0,
"columns": [],
"creation": "2024-09-11 22:31:05.837918",
"disabled": 0,
"docstatus": 0,
"doctype": "Report",
"filters": [],
"idx": 0,
"is_standard": "Yes",
"letterhead": null,
"modified": "2024-09-11 22:31:05.837918",
"modified_by": "Administrator",
"module": "Helpdesk",
"name": "Ticket-Search Analysis",
"owner": "Administrator",
"prepared_report": 0,
"ref_doctype": "HD Ticket",
"report_name": "Ticket-Search Analysis",
"report_type": "Script Report",
"roles": [
{
"role": "System Manager"
},
{
"role": "Agent"
},
{
"role": "Support Team"
},
{
"role": "Supported Site User"
},
{
"role": "External Agent"
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# Copyright (c) 2024, Frappe Technologies and contributors
# For license information, please see license.txt

import frappe
from frappe import _

from helpdesk.api.article import search


def execute(filters: dict | None = None):
"""Return columns and data for the report.
This is the main entry point for the report. It accepts the filters as a
dictionary and should return columns and data. It is called by the framework
every time the report is refreshed or a filter is updated.
"""
columns = get_columns()
data = get_data()

return columns, data


def get_columns() -> list[dict]:
"""Return columns for the report.
One field definition per column, just like a DocType field definition.
"""
return [
{
"label": _("Subject"),
"fieldname": "subject",
"fieldtype": "Data",
},
{
"label": _("Top Result"),
"fieldname": "top_res",
"fieldtype": "Text",
},
{
"label": _("Search Score"),
"fieldname": "score",
"fieldtype": "Float",
},
]


def get_top_res(search_term: str) -> float:
"""Return the search score for the top result for the search term."""
res = search(search_term)
headings = ""
score = 0
for item in res:
headings += item["headings"] or item["subject"]
headings += "\n"
score += item["score"]
return headings, score


def get_data() -> list[list]:
"""Return data for the report.
The report data is a list of rows, with each row being a list of cell values.
"""
tickets = frappe.get_all(
"HD Ticket", {"agent_group": ["like", "%FC%"]}, ["name", "subject"], limit=100
)
for ticket in tickets:
ticket["top_res"], ticket["score"] = get_top_res(ticket["subject"])
return [
[ticket["subject"], ticket["top_res"], ticket["score"]] for ticket in tickets
]
Loading

0 comments on commit 39faab9

Please sign in to comment.