feat: Add custom icons with the app_include_icons hook (#22254)

* feat: Add custom icons with the `app_include_icons` hook

These custom icons are available on the desk only. They can be picked in the `ControlIcon` picker.

Co-authored-by: Abraham Kalungi <85731451+kalungia@users.noreply.github.com>

* fix: skip conf for including icons

* test: Fix test_include_icons

---------

Co-authored-by: Abraham Kalungi <85731451+kalungia@users.noreply.github.com>
Co-authored-by: Ankush Menat <ankushmenat@gmail.com>
This commit is contained in:
Corentin Flr 2023-09-20 16:53:17 +02:00 committed by GitHub
parent 42ee7f9b2d
commit 41d30e7213
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 40 additions and 2 deletions

View file

@ -35,6 +35,7 @@ app_include_css = [
"desk.bundle.css",
"report.bundle.css",
]
app_include_icons = ["frappe/public/icons/timeless/icons.svg"]
doctype_js = {
"Web Page": "public/js/frappe/utils/web_template.js",

View file

@ -0,0 +1,5 @@
<svg>
<symbol id="icon-TEST-ONLY">
<rect width="24" height="24" stroke="currentColor" />
</symbol>
</svg>

After

Width:  |  Height:  |  Size: 109 B

View file

@ -10,7 +10,7 @@ frappe.ui.form.ControlIcon = class ControlIcon extends frappe.ui.form.ControlDat
get_all_icons() {
frappe.symbols = [];
$("#frappe-symbols > symbol[id]").each(function () {
$("#all-symbols > svg > symbol[id]").each(function () {
this.id.includes("icon-") && frappe.symbols.push(this.id.replace("icon-", ""));
});
}

View file

@ -391,6 +391,27 @@ class TestWebsite(FrappeTestCase):
delattr(frappe.local, "request")
frappe.set_user("Guest")
def test_include_icons(self):
from frappe import get_hooks
TEST_ICONS_PATH = "frappe/public/icons/timeless/test.svg"
def patched_get_hooks(*args, **kwargs):
return_value = get_hooks(*args, **kwargs)
if isinstance(return_value, dict) and "app_include_icons" in return_value:
return_value.app_include_icons.append(TEST_ICONS_PATH)
return return_value
with patch.object(frappe, "get_hooks", patched_get_hooks):
frappe.set_user("Administrator")
set_request(method="GET", path="/app")
content = get_response_content("/app")
# icon is available in a symbol tag
self.assertIn('id="icon-TEST-ONLY"', content)
delattr(frappe.local, "request")
frappe.set_user("Guest")
def patched_get_hooks(hook, value):
def wrapper(*args, **kwargs):

View file

@ -365,6 +365,11 @@ app_license = "{app_license}"
# doctype_tree_js = {{"doctype" : "public/js/doctype_tree.js"}}
# doctype_calendar_js = {{"doctype" : "public/js/doctype_calendar.js"}}
# Svg Icons
# ------------------
# include app icons in desk
# app_include_icons = "{app_name}/public/icons.svg"
# Home Pages
# ----------

View file

@ -25,7 +25,11 @@
{%- endfor -%}
</head>
<body>
{% include "public/icons/timeless/icons.svg" %}
<div id="all-symbols" style="display:none!important;">
{%- for path in include_icons -%}
<!-- {{ path }} -->{%- include path ignore missing -%}
{%- endfor -%}
</div>
{% include "templates/includes/splash_screen.html" %}
<div class="main-section">
<header></header>

View file

@ -44,6 +44,7 @@ def get_context(context):
include_js = hooks.get("app_include_js", []) + frappe.conf.get("app_include_js", [])
include_css = hooks.get("app_include_css", []) + frappe.conf.get("app_include_css", [])
include_icons = hooks.get("app_include_icons", [])
context.update(
{
@ -51,6 +52,7 @@ def get_context(context):
"build_version": frappe.utils.get_build_version(),
"include_js": include_js,
"include_css": include_css,
"include_icons": include_icons,
"layout_direction": "rtl" if is_rtl() else "ltr",
"lang": frappe.local.lang,
"sounds": hooks["sounds"],