From 293afc3998028066eeb9ce8617edfb1983668c93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Wed, 28 Feb 2024 13:00:59 +0100 Subject: [PATCH 001/486] New Crowdin updates (#532) * New translations messages.en.xlf (Chinese Simplified) * New translations messages.en.xlf (Chinese Simplified) --- translations/messages.zh.xlf | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/translations/messages.zh.xlf b/translations/messages.zh.xlf index c6cbcb9d..43498457 100644 --- a/translations/messages.zh.xlf +++ b/translations/messages.zh.xlf @@ -9323,7 +9323,7 @@ Element 3 part.filter.lotNeedsRefill - 需要补充 + 任何需要补充的批次 @@ -9785,7 +9785,7 @@ Element 3 project.bom.quantity - BOM 数量 + 数量 @@ -9893,19 +9893,19 @@ Element 3 part.new_build_part.error.build_part_already_exists - 该项目已映射到部件。 + 已映射到部件 project.edit.associated_build_part - 该项目已映射到部件。 + 映射到部件 project.edit.associated_build_part.add - 该项目已映射到部件。 + 创建生产成果部件 @@ -10163,13 +10163,13 @@ Element 3 project.builds.stocked - 库存充足 + 在库 project.builds.needed - 需要补充 + 所需 @@ -10193,7 +10193,7 @@ Element 3 project.builds.following_bom_entries_miss_instock_n - 您没有足够的库存部件生产该项目 %number_of_builds% 次。 以下部件需要补充: + 没有足够的部件生产该项目 %number_of_builds% 次。 以下部件需要补充: @@ -10433,7 +10433,7 @@ Element 3 log.element_edited.changed_fields.quantity - BOM 数量 + 数量 From 409dcce3c76adf64d90f42f42888cba8a29d5024 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Thu, 29 Feb 2024 20:39:27 +0100 Subject: [PATCH 002/486] Use correct translations for livesearch field in navbar --- .../elements/part_livesearch_controller.js | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/assets/controllers/elements/part_livesearch_controller.js b/assets/controllers/elements/part_livesearch_controller.js index 7b717880..5ded2df2 100644 --- a/assets/controllers/elements/part_livesearch_controller.js +++ b/assets/controllers/elements/part_livesearch_controller.js @@ -24,6 +24,12 @@ import "../../css/components/autocomplete_bootstrap_theme.css"; import { createLocalStorageRecentSearchesPlugin } from '@algolia/autocomplete-plugin-recent-searches'; import {marked} from "marked"; +import { + trans, + SEARCH_PLACEHOLDER, + SEARCH_SUBMIT +} from '../../translator'; + export default class extends Controller { static targets = ["input"]; @@ -49,7 +55,10 @@ export default class extends Controller { panelPlacement: 'end', plugins: [recentSearchesPlugin], openOnFocus: true, - placeholder: "Search for parts", + placeholder: trans(SEARCH_PLACEHOLDER), + translations: { + submitButtonTitle: trans(SEARCH_SUBMIT) + }, // Use a navigator compatible with turbo: navigator: { From faadd8e9a45ff45c3faf7991e18e393495ff8a7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Thu, 29 Feb 2024 21:53:28 +0100 Subject: [PATCH 003/486] Improved layout for autocomplete dropdown --- .../elements/part_livesearch_controller.js | 17 ++++++++++++----- templates/_navbar_search.html.twig | 1 + 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/assets/controllers/elements/part_livesearch_controller.js b/assets/controllers/elements/part_livesearch_controller.js index 5ded2df2..d5facbea 100644 --- a/assets/controllers/elements/part_livesearch_controller.js +++ b/assets/controllers/elements/part_livesearch_controller.js @@ -27,7 +27,8 @@ import {marked} from "marked"; import { trans, SEARCH_PLACEHOLDER, - SEARCH_SUBMIT + SEARCH_SUBMIT, + STATISTICS_PARTS } from '../../translator'; export default class extends Controller { @@ -42,6 +43,9 @@ export default class extends Controller { // The URL template for the part detail pages const part_detail_uri_template = this.element.dataset.detailUrl; + //The URL of the placeholder picture + const placeholder_image = this.element.dataset.placeholderImage; + const that = this; const recentSearchesPlugin = createLocalStorageRecentSearchesPlugin({ @@ -106,25 +110,28 @@ export default class extends Controller { }, templates: { header({ html }) { - return html`Parts + return html`${trans(STATISTICS_PARTS)}
`; }, item({item, components, html}) { const details_url = part_detail_uri_template.replace('__ID__', item.id); - return html`
- ${item.name} + ${item.name}
- ${components.Highlight({hit: item, attribute: 'name'})} + + ${components.Highlight({hit: item, attribute: 'name'})} +
${components.Snippet({hit: item, attribute: 'description'})} + ${item.category ? html`

${item.category}

` : ""} + ${item.footprint ? html`

${item.footprint}

` : ""}
diff --git a/templates/_navbar_search.html.twig b/templates/_navbar_search.html.twig index 1dc2ae36..4b954b62 100644 --- a/templates/_navbar_search.html.twig +++ b/templates/_navbar_search.html.twig @@ -71,6 +71,7 @@ {# It is important that this element has an id field. Otherwise the dropdown panel wont appear after some link clicks #} From e00988047c6289093f0dbb0b04a9f6772885a33b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Thu, 29 Feb 2024 22:20:30 +0100 Subject: [PATCH 004/486] Added highlighting to search results --- .../elements/part_livesearch_controller.js | 38 ++++++++++++++++--- .../autocomplete_bootstrap_theme.css | 3 +- 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/assets/controllers/elements/part_livesearch_controller.js b/assets/controllers/elements/part_livesearch_controller.js index d5facbea..e79ed641 100644 --- a/assets/controllers/elements/part_livesearch_controller.js +++ b/assets/controllers/elements/part_livesearch_controller.js @@ -37,6 +37,19 @@ export default class extends Controller { _autocomplete; + _highlight = (text, query) => { + if (!text) return text; + if (!query) return text; + + const HIGHLIGHT_PRE_TAG = '__aa-highlight__' + const HIGHLIGHT_POST_TAG = '__/aa-highlight__' + + const escaped = query.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&'); + const regex = new RegExp(escaped, 'gi'); + + return text.replace(regex, (match) => `${HIGHLIGHT_PRE_TAG}${match}${HIGHLIGHT_POST_TAG}`); + } + initialize() { // The endpoint for searching parts const base_url = this.element.dataset.autocomplete; @@ -97,13 +110,28 @@ export default class extends Controller { getSources({ query }) { return [ + // The parts source { sourceId: 'parts', getItems() { const url = base_url.replace('__QUERY__', encodeURIComponent(query)); - return fetch(url) - .then((response) => response.json()); + const data = fetch(url) + .then((response) => response.json()) + ; + + //Iterate over all fields besides the id and highlight them + const fields = ["name", "description", "category", "footprint"]; + + data.then((items) => { + items.forEach((item) => { + for (const field of fields) { + item[field] = that._highlight(item[field], query); + } + }); + }); + + return data; }, getItemUrl({ item }) { return part_detail_uri_template.replace('__ID__', item.id); @@ -129,9 +157,9 @@ export default class extends Controller {
- ${components.Snippet({hit: item, attribute: 'description'})} - ${item.category ? html`

${item.category}

` : ""} - ${item.footprint ? html`

${item.footprint}

` : ""} + ${components.Highlight({hit: item, attribute: 'description'})} + ${item.category ? html`

${components.Highlight({hit: item, attribute: 'category'})}

` : ""} + ${item.footprint ? html`

${components.Highlight({hit: item, attribute: 'footprint'})}

` : ""}
diff --git a/assets/css/components/autocomplete_bootstrap_theme.css b/assets/css/components/autocomplete_bootstrap_theme.css index 62bd9927..d86232e5 100644 --- a/assets/css/components/autocomplete_bootstrap_theme.css +++ b/assets/css/components/autocomplete_bootstrap_theme.css @@ -629,9 +629,10 @@ body { display: none; } .aa-ItemContent mark { - background: none; + background: var(--bs-highlight-bg); color: var(--bs-body-color); font-style: normal; + padding: 0; font-weight: 700; font-weight: var(--aa-font-weight-bold); } From 1815162907b602fd651d1426cb0978397c04bb1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Thu, 29 Feb 2024 22:46:19 +0100 Subject: [PATCH 005/486] Added a search bar to homepage --- .../elements/part_livesearch_controller.js | 8 +++- templates/_navbar.html.twig | 5 ++- .../search.macro.html.twig} | 45 +++++++++++++++---- templates/homepage.html.twig | 12 ++--- 4 files changed, 52 insertions(+), 18 deletions(-) rename templates/{_navbar_search.html.twig => components/search.macro.html.twig} (76%) diff --git a/assets/controllers/elements/part_livesearch_controller.js b/assets/controllers/elements/part_livesearch_controller.js index e79ed641..e1350172 100644 --- a/assets/controllers/elements/part_livesearch_controller.js +++ b/assets/controllers/elements/part_livesearch_controller.js @@ -59,6 +59,9 @@ export default class extends Controller { //The URL of the placeholder picture const placeholder_image = this.element.dataset.placeholderImage; + //If the element is in navbar mode, or not + const navbar_mode = this.element.dataset.navbarMode === "true"; + const that = this; const recentSearchesPlugin = createLocalStorageRecentSearchesPlugin({ @@ -68,8 +71,9 @@ export default class extends Controller { this._autocomplete = autocomplete({ container: this.element, - panelContainer: document.getElementById("navbar-frame"), - panelPlacement: 'end', + //Place the panel in the navbar, if the element is in navbar mode + panelContainer: navbar_mode ? document.getElementById("navbar-frame") : document.body, + panelPlacement: this.element.dataset.panelPlacement, plugins: [recentSearchesPlugin], openOnFocus: true, placeholder: trans(SEARCH_PLACEHOLDER), diff --git a/templates/_navbar.html.twig b/templates/_navbar.html.twig index 2ae97371..0d775b8d 100644 --- a/templates/_navbar.html.twig +++ b/templates/_navbar.html.twig @@ -1,4 +1,5 @@ {% import "helper.twig" as helper %} +{% import "components/search.macro.html.twig" as search %}