summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbuttle <chris@gatopelao.org>2023-10-15 09:57:00 +0200
committerbuttle <chris@gatopelao.org>2023-10-15 09:57:00 +0200
commit39036133d3e8de097877becf3bd011f50132598c (patch)
tree8c6d1dec02ce9feccf73fb936be4b5d0c773155a
parenta9780148cfb58bf435e60b689f0c0d844e3d1848 (diff)
parentec241b224d0c977c16efb286849ecc247930dcee (diff)
Merge branch 'feat/search' into develop
-rw-r--r--liberaforms/static/css/main-backend.css3
-rw-r--r--liberaforms/static/js/inline_help.js50
-rw-r--r--liberaforms/static/sass/backend/_main.scss3
-rw-r--r--liberaforms/templates/site/partials/inline_help_menu.html4
-rw-r--r--liberaforms/utils/inline_help.py82
-rw-r--r--liberaforms/views/site.py12
6 files changed, 132 insertions, 22 deletions
diff --git a/liberaforms/static/css/main-backend.css b/liberaforms/static/css/main-backend.css
index 4a82b36b..8c600d69 100644
--- a/liberaforms/static/css/main-backend.css
+++ b/liberaforms/static/css/main-backend.css
@@ -14029,6 +14029,9 @@ a.badge {
.ds-inline-help .ds-inline-help-menu .nav-link:before {
content: " - ";
}
+.ds-inline-help .ds-inline-help-menu .ds-search {
+ background-color: var(--lf-gray-100);
+}
.ds-inline-help .ds-inline-help-page {
padding: 1rem;
background-color: var(--lf-gray-100);
diff --git a/liberaforms/static/js/inline_help.js b/liberaforms/static/js/inline_help.js
index f6e10ca1..e0c5cd97 100644
--- a/liberaforms/static/js/inline_help.js
+++ b/liberaforms/static/js/inline_help.js
@@ -78,6 +78,7 @@ function inline_help_go_back() {
function inline_help_reset() {
inline_help_cache = {}
inline_help_history = []
+ $("input[type='search']").val("")
}
function inline_help_retieve_page(file_name) {
return new Promise(function(resolve, reject) {
@@ -115,12 +116,61 @@ function inline_help_retieve_page(file_name) {
});
})
}
+function search_inline_help(event) {
+ if (event.key == "Enter") {
+ do_search().then(function(data) {
+ delete inline_help_cache["search"];
+ let search_item_pos = inline_help_history.indexOf("search");
+ if (search_item_pos > -1) {
+ inline_help_history.splice(search_item_pos, 1)
+ }
+ var html = ""
+ for (let page_name of Object.keys(data.result)) {
+ let block = "<h2>" + page_name + "</h2>"
+ lines = ""
+ for (let line of data.result[page_name]) {
+ lines = lines + line + "<br />"
+ }
+ html = html + block + lines
+ }
+ _inline_help_history_push("search")
+ let page_title = $("input[type='search']").attr('placeholder') + ": " + $("input[type=search]").val()
+ inline_help_cache["search"] = {"html": html, "title": page_title }
+ $('#inline_help_page').html(html)
+ $('#inline_help_page_title').html(page_title)
+ });
+ }
+}
+
+function do_search() {
+ return new Promise(function(resolve, reject) {
+ $.ajax({
+ url : "/site/search-help",
+ type: "POST",
+ contentType: "application/json",
+ data : JSON.stringify({"search_string": $("input[type=search]").val()}),
+ dataType: "json",
+ beforeSend: function(xhr, settings) {
+ if (!/^(GET|HEAD|OPTIONS|TRACE)$/i.test(settings.type)) {
+ xhr.setRequestHeader("X-CSRFToken", csrftoken)
+ }
+ },
+ success: function(data, textStatus, jqXHR) {
+ resolve(data) // Resolve promise and goto then()
+ },
+ error: function(err) {
+ reject(err) // Reject the promise and goto catch()
+ }
+ });
+ });
+}
const inline_help_template = `
<div id="inline_help" class="grid ds-inline-help pt-2" style="display:none; --lf-gap: 0;">
<div class="navbar g-col-12 ds-inline-help-page-header">
<div>
<a id="inline_help_back_button" href="#" onclick="js:inline_help_go_back()"" class="align-middle"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-chevron-left" aria-hidden="true"><polyline points="15 18 9 12 15 6"></polyline></svg><span>%Go_back%</span></a>
</div>
+
<div class="d-flex">
<button class="ds-button-navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarHelpContent" aria-controls="navbarHelpContent" aria-expanded="false" aria-label="Toggle navigation">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-more-vertical"><circle cx="12" cy="12" r="1"></circle><circle cx="12" cy="5" r="1"></circle><circle cx="12" cy="19" r="1"></circle></svg>
diff --git a/liberaforms/static/sass/backend/_main.scss b/liberaforms/static/sass/backend/_main.scss
index a061126e..b09d337c 100644
--- a/liberaforms/static/sass/backend/_main.scss
+++ b/liberaforms/static/sass/backend/_main.scss
@@ -51,6 +51,9 @@
content: ' - ';
}
}
+ .ds-search {
+ background-color: var(--lf-gray-100);
+ }
}
.ds-inline-help-page {
padding: $spacer;
diff --git a/liberaforms/templates/site/partials/inline_help_menu.html b/liberaforms/templates/site/partials/inline_help_menu.html
index fbc3e038..37cd9692 100644
--- a/liberaforms/templates/site/partials/inline_help_menu.html
+++ b/liberaforms/templates/site/partials/inline_help_menu.html
@@ -21,6 +21,10 @@
</li>
{% endfor %}
{% endif %}
+
+ <li class="nav-item mt-4">
+ <input id="search_text" class="form-control ds-search" type="search" placeholder='{{_("Search")}}' onkeypress="search_inline_help(event)" aria-label='{{_("Search")}}'>
+ </li>
</ul>
</div>
</nav>
diff --git a/liberaforms/utils/inline_help.py b/liberaforms/utils/inline_help.py
index 901e1d26..7851981c 100644
--- a/liberaforms/utils/inline_help.py
+++ b/liberaforms/utils/inline_help.py
@@ -13,6 +13,7 @@ from flask import current_app, g, render_template, jsonify, url_for
from flask_babel import gettext, force_locale
import flask_login
from liberaforms.utils import utils
+from liberaforms.utils import sanitizers
from liberaforms.utils import i18n
@@ -58,6 +59,63 @@ class InlineHelp():
def _external_link_icon(self):
return '<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-arrow-up-right"><line x1="7" y1="17" x2="17" y2="7"></line><polyline points="7 7 17 7 17 17"></polyline></svg>'
+ def render_markdown(self, j2_env, file_name) -> str:
+ #print(file_name)
+ template = j2_env.get_template(file_name)
+ markdown_help = template.render({
+ "help_page": self._help_page_link,
+ "is_admin": self.is_admin,
+ "is_editor": self.is_editor,
+ "is_guest": self.is_guest,
+ "is_root_user": self.is_root_user,
+ "is_multilanguage_site": bool(len(g.site.custom_languages) > 1),
+ "_": self.translate,
+ "url_for": url_for,
+ "BASE_URL": current_app.config["BASE_URL"],
+ #"external_link_icon": self._external_link_icon,
+ "default_enabled_language": self._get_default_enabled_language,
+ "token_lifespan": self._token_lifespan(),
+ "current_user": flask_login.current_user,
+ "site": g.site,
+ "with_link": self._build_link,
+ "app_config": current_app.config,
+ "human_readable_bytes": utils.human_readable_bytes,
+ "mimetype_risks": self.mimetype_risks,
+ "i18n_docs_site_url": i18n.get_docs_site_url})
+ return markdown_help
+
+ def search(self, search_string: str) -> dict:
+ result: dict = {}
+ j2_env = Environment(loader=FileSystemLoader(self.pages_dir))
+
+ pages = []
+ def load_pages(menu: dict):
+ for key, value in menu.items():
+ pages.append(key)
+ if "sub_pages" in value and value["sub_pages"]:
+ load_pages(value["sub_pages"])
+
+ load_pages(self.menu_data["user"])
+ if self.is_admin:
+ load_pages(self.menu_data["admin"])
+
+ for file_name in pages:
+ if file_name.startswith("_"):
+ continue
+ try:
+ rendered_markdown = self.render_markdown(j2_env, file_name)
+ for line in rendered_markdown.splitlines():
+ if search_string in line:
+ page_name = self.get_page_label(file_name)
+ page_link = '<a href="#" onclick=\'inline_help_goto_page("'+file_name+'")\'>'+page_name+'</a>'
+ if page_link not in result:
+ result[page_link] = []
+ text = sanitizers.remove_html_tags(markdown.markdown(line))
+ result[page_link].append(text)
+ except:
+ current_app.logger.debug(f"APP - Inline help. Cannot find {file_name}")
+ return result
+
def get_page_label(self, file_name):
for menu in self.menu_data.values():
for item, item_value in menu.items():
@@ -83,28 +141,8 @@ class InlineHelp():
current_app.logger.debug(f"INLINE-HELP - Cannot file help page: {file_name}")
return _("Cannot find the file %(file_name)s", file_name=file_name)
j2_env = Environment(loader=FileSystemLoader(self.pages_dir))
- template = j2_env.get_template(file_name)
- markdown_help = template.render({
- "help_page": self._help_page_link,
- "is_admin": self.is_admin,
- "is_editor": self.is_editor,
- "is_guest": self.is_guest,
- "is_root_user": self.is_root_user,
- "is_multilanguage_site": bool(len(g.site.custom_languages) > 1),
- "_": self.translate,
- "url_for": url_for,
- "BASE_URL": current_app.config["BASE_URL"],
- #"external_link_icon": self._external_link_icon,
- "default_enabled_language": self._get_default_enabled_language,
- "token_lifespan": self._token_lifespan(),
- "current_user": flask_login.current_user,
- "site": g.site,
- "with_link": self._build_link,
- "app_config": current_app.config,
- "human_readable_bytes": utils.human_readable_bytes,
- "mimetype_risks": self.mimetype_risks,
- "i18n_docs_site_url": i18n.get_docs_site_url})
- html = markdown.markdown(markdown_help)
+ rendered_markdown = self.render_markdown(j2_env, file_name)
+ html = markdown.markdown(rendered_markdown)
return html
def get_menu(self):
diff --git a/liberaforms/views/site.py b/liberaforms/views/site.py
index 1aac0946..faf8e1d5 100644
--- a/liberaforms/views/site.py
+++ b/liberaforms/views/site.py
@@ -693,6 +693,18 @@ def get_inline_help():
return jsonify(payload), 200
+@site_bp.route('/site/search-help', methods=['POST'])
+@auth.authenticated_user_required__json
+def search_help():
+ data = request.get_json()
+ search_string = data["search_string"] if "search_string" in data else None
+ if search_string:
+ inline_help = InlineHelp(g.language, flask_login.current_user.role)
+ result = inline_help.search(search_string)
+ return jsonify(result=result), 200
+ return jsonify(result={}), 200
+
+
# RSS
@site_bp.route('/feed', methods=['GET'])