diff --git a/assets/controllers/elements/part_livesearch_controller.js b/assets/controllers/elements/part_livesearch_controller.js
new file mode 100644
index 00000000..32edecb6
--- /dev/null
+++ b/assets/controllers/elements/part_livesearch_controller.js
@@ -0,0 +1,77 @@
+/*
+ * This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
+ *
+ * Copyright (C) 2019 - 2024 Jan Böhmer (https://github.com/jbtronics)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+import { Controller } from "@hotwired/stimulus";
+import { autocomplete } from '@algolia/autocomplete-js';
+import "@algolia/autocomplete-theme-classic/dist/theme.css";
+import {marked} from "marked";
+
+export default class extends Controller {
+
+ _autocomplete;
+
+ connect() {
+ // The endpoint for searching parts
+ const base_url = this.element.dataset.autocomplete;
+ // The URL template for the part detail pages
+ const part_detail_uri_template = this.element.dataset.detailUrl;
+
+ this._autocomplete = autocomplete({
+ container: this.element,
+ placeholder: "Search for parts",
+ getSources({ query }) {
+ return [
+ {
+ sourceId: 'parts',
+ getItems() {
+ const url = base_url.replace('__QUERY__', encodeURIComponent(query));
+
+ return fetch(url)
+ .then((response) => response.json());
+ },
+ templates: {
+ item({item, components, html}) {
+ const details_url = part_detail_uri_template.replace('__ID__', item.id);
+
+
+ return html`
+
+
+
+

+
+
+
+ ${components.Highlight({hit: item, attribute: 'name'})}
+
+
+ ${components.Snippet({hit: item, attribute: 'description'})}
+
+
+
+
+ `;
+ },
+ },
+ },
+ ];
+ },
+ });
+ }
+}
\ No newline at end of file
diff --git a/package.json b/package.json
index 8a9d78fe..bd0e7701 100644
--- a/package.json
+++ b/package.json
@@ -30,6 +30,9 @@
"build": "encore production --progress"
},
"dependencies": {
+ "@algolia/autocomplete-js": "^1.17.0",
+ "@algolia/autocomplete-plugin-redirect-url": "^1.17.0",
+ "@algolia/autocomplete-theme-classic": "^1.17.0",
"@ckeditor/ckeditor5-alignment": "^41.0.0",
"@ckeditor/ckeditor5-autoformat": "^41.0.0",
"@ckeditor/ckeditor5-basic-styles": "^41.0.0",
diff --git a/templates/homepage.html.twig b/templates/homepage.html.twig
index 138257c7..f711b227 100644
--- a/templates/homepage.html.twig
+++ b/templates/homepage.html.twig
@@ -4,6 +4,12 @@
{% block content %}
+
+
+
+
+
{% if is_granted('@system.show_updates') %}
{{ nv.new_version_alert(new_version_available, new_version, new_version_url) }}
{% endif %}
diff --git a/yarn.lock b/yarn.lock
index 3edd73be..bf65595e 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2,6 +2,59 @@
# yarn lockfile v1
+"@algolia/autocomplete-core@1.17.0":
+ version "1.17.0"
+ resolved "https://registry.yarnpkg.com/@algolia/autocomplete-core/-/autocomplete-core-1.17.0.tgz#b9e62d9677dc0ee818bb59d917ff58908356a9a0"
+ integrity sha512-6E4sVb5+fGtSQs9mULlxUH84OWFUVZPMapa5dMCtUc7KyDRLY6+X/dA8xbDA8CX5phdBn1plLUET1B6NZnrZuw==
+ dependencies:
+ "@algolia/autocomplete-plugin-algolia-insights" "1.17.0"
+ "@algolia/autocomplete-shared" "1.17.0"
+
+"@algolia/autocomplete-js@1.17.0", "@algolia/autocomplete-js@^1.17.0":
+ version "1.17.0"
+ resolved "https://registry.yarnpkg.com/@algolia/autocomplete-js/-/autocomplete-js-1.17.0.tgz#91f0ef2232646316a26c79dadbeb2e7791de623c"
+ integrity sha512-RbD98hXtZOl6VohSAo7kMOFWQHR1x4wWaJFadJradFQ1TAA9hFEyirSIM+yT96UpKkdi08V2EBI+YwZ3/VETvw==
+ dependencies:
+ "@algolia/autocomplete-core" "1.17.0"
+ "@algolia/autocomplete-preset-algolia" "1.17.0"
+ "@algolia/autocomplete-shared" "1.17.0"
+ htm "^3.1.1"
+ preact "^10.13.2"
+
+"@algolia/autocomplete-plugin-algolia-insights@1.17.0":
+ version "1.17.0"
+ resolved "https://registry.yarnpkg.com/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.17.0.tgz#dcec9b03a47375860a9f927816a1275d885ebdff"
+ integrity sha512-zbWImu+VxBDzUQONEhQXq3OzlipHLEtWbL4Nf/VOb1p1qHG/f96jCegOzzEZVPiQvZpRJnmhCUmsYNHlIBxKWw==
+ dependencies:
+ "@algolia/autocomplete-shared" "1.17.0"
+
+"@algolia/autocomplete-plugin-redirect-url@^1.17.0":
+ version "1.17.0"
+ resolved "https://registry.yarnpkg.com/@algolia/autocomplete-plugin-redirect-url/-/autocomplete-plugin-redirect-url-1.17.0.tgz#843a7af551a29e6c5d2a6585c17b7dcff50bee12"
+ integrity sha512-C/xvPKKM0+uHRvKDi7sE/P8qEtlo9lhDEB2YQJRY9X90osqlqwY4HqRZbauz4wGnHckrG0iqIN+xcCNEFN3Jxg==
+ dependencies:
+ "@algolia/autocomplete-core" "1.17.0"
+ "@algolia/autocomplete-js" "1.17.0"
+ "@algolia/autocomplete-preset-algolia" "1.17.0"
+ "@algolia/autocomplete-shared" "1.17.0"
+
+"@algolia/autocomplete-preset-algolia@1.17.0":
+ version "1.17.0"
+ resolved "https://registry.yarnpkg.com/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.17.0.tgz#9d7d9673a922d75dfbedd3119e7ffa76f4c118c6"
+ integrity sha512-DhTkMs/9BzThhTU2nSTpQxVxHLzaRDZLid4Tf56D8s9IhEGfmzbNuLRmJNzgAOPv1smHtUErndmC+S9QNMDEJA==
+ dependencies:
+ "@algolia/autocomplete-shared" "1.17.0"
+
+"@algolia/autocomplete-shared@1.17.0":
+ version "1.17.0"
+ resolved "https://registry.yarnpkg.com/@algolia/autocomplete-shared/-/autocomplete-shared-1.17.0.tgz#7d0a8e504fe555c48df7ae6854d3d6633b0b32f5"
+ integrity sha512-7su4KH/2q2Fhud2VujUNhCMbIh7yp6wqWR3UuVje5P3kDRhTotPRmg3iRQi48YRYkk9o+airsrLl+rxJ/9FWng==
+
+"@algolia/autocomplete-theme-classic@^1.17.0":
+ version "1.17.0"
+ resolved "https://registry.yarnpkg.com/@algolia/autocomplete-theme-classic/-/autocomplete-theme-classic-1.17.0.tgz#bbd79df8f5240b3ddd3f9cdc9b8273753f15cd25"
+ integrity sha512-FsW/J/mG1YIPv93/QQ7KxMVNXAiVi9accGgoK2y3zDz58WpVgUug97SUoQzP4I9EMZAZAHQo0QbWXxpqTWkcOA==
+
"@ampproject/remapping@^2.2.0":
version "2.2.1"
resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.1.tgz#99e8e11851128b8702cd57c33684f1d0f260b630"
@@ -4268,6 +4321,11 @@ hpack.js@^2.1.6:
readable-stream "^2.0.1"
wbuf "^1.1.0"
+htm@^3.1.1:
+ version "3.1.1"
+ resolved "https://registry.yarnpkg.com/htm/-/htm-3.1.1.tgz#49266582be0dc66ed2235d5ea892307cc0c24b78"
+ integrity sha512-983Vyg8NwUE7JkZ6NmOqpCZ+sh1bKv2iYTlUkzlWmA5JD2acKoxd4KVxbMmxX/85mtfdnDmTFoNKcg5DGAvxNQ==
+
html-encoding-sniffer@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz#42a6dc4fd33f00281176e8b23759ca4e4fa185f3"
@@ -5997,6 +6055,11 @@ postcss@^8.2.14, postcss@^8.2.15, postcss@^8.4.12, postcss@^8.4.24, postcss@^8.4
picocolors "^1.0.0"
source-map-js "^1.0.2"
+preact@^10.13.2:
+ version "10.19.6"
+ resolved "https://registry.yarnpkg.com/preact/-/preact-10.19.6.tgz#66007b67aad4d11899f583df1b0116d94a89b8f5"
+ integrity sha512-gympg+T2Z1fG1unB8NH29yHJwnEaCH37Z32diPDku316OTnRPeMbiRV9kTrfZpocXjdfnWuFUl/Mj4BHaf6gnw==
+
prelude-ls@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54"