Merge branch 'quicksearch'

This commit is contained in:
Jan Böhmer 2024-02-29 23:04:42 +01:00
commit 77a5cadf51
10 changed files with 1475 additions and 210 deletions

View file

@ -0,0 +1,190 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
import { Controller } from "@hotwired/stimulus";
import { autocomplete } from '@algolia/autocomplete-js';
//import "@algolia/autocomplete-theme-classic/dist/theme.css";
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,
STATISTICS_PARTS
} from '../../translator';
/**
* This controller is responsible for the search fields in the navbar and the homepage.
* It uses the Algolia Autocomplete library to provide a fast and responsive search.
*/
export default class extends Controller {
static targets = ["input"];
_autocomplete;
// Highlight the search query in the results
_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;
// 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;
//If the element is in navbar mode, or not
const navbar_mode = this.element.dataset.navbarMode === "true";
const that = this;
const recentSearchesPlugin = createLocalStorageRecentSearchesPlugin({
key: 'RECENT_SEARCH',
limit: 5,
});
this._autocomplete = autocomplete({
container: this.element,
//Place the panel in the navbar, if the element is in navbar mode
panelContainer: navbar_mode ? document.getElementById("navbar-search-form") : document.body,
panelPlacement: this.element.dataset.panelPlacement,
plugins: [recentSearchesPlugin],
openOnFocus: true,
placeholder: trans(SEARCH_PLACEHOLDER),
translations: {
submitButtonTitle: trans(SEARCH_SUBMIT)
},
// Use a navigator compatible with turbo:
navigator: {
navigate({ itemUrl }) {
window.Turbo.visit(itemUrl, { action: "advance" });
},
navigateNewTab({ itemUrl }) {
const windowReference = window.open(itemUrl, '_blank', 'noopener');
if (windowReference) {
windowReference.focus();
}
},
navigateNewWindow({ itemUrl }) {
window.open(itemUrl, '_blank', 'noopener');
},
},
// If the form is submitted, forward the term to the form
onSubmit({state, event, ...setters}) {
//Put the current text into each target input field
const input = that.inputTarget;
if (!input) {
return;
}
//Do not submit the form, if the input is empty
if (state.query === "") {
return;
}
input.value = state.query;
input.form.requestSubmit();
},
getSources({ query }) {
return [
// The parts source
{
sourceId: 'parts',
getItems() {
const url = base_url.replace('__QUERY__', encodeURIComponent(query));
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);
},
templates: {
header({ html }) {
return html`<span class="aa-SourceHeaderTitle">${trans(STATISTICS_PARTS)}</span>
<div class="aa-SourceHeaderLine" />`;
},
item({item, components, html}) {
const details_url = part_detail_uri_template.replace('__ID__', item.id);
return html`
<a class="aa-ItemLink" href="${details_url}">
<div class="aa-ItemContent">
<div class="aa-ItemIcon aa-ItemIcon--picture aa-ItemIcon--alignTop">
<img src="${item.image !== "" ? item.image : placeholder_image}" alt="${item.name}" width="30" height="30"/>
</div>
<div class="aa-ItemContentBody">
<div class="aa-ItemContentTitle">
<b>
${components.Highlight({hit: item, attribute: 'name'})}
</b>
</div>
<div class="aa-ItemContentDescription">
${components.Highlight({hit: item, attribute: 'description'})}
${item.category ? html`<p class="m-0"><span class="fa-solid fa-tags fa-fw"></span>${components.Highlight({hit: item, attribute: 'category'})}</p>` : ""}
${item.footprint ? html`<p class="m-0"><span class="fa-solid fa-microchip fa-fw"></span>${components.Highlight({hit: item, attribute: 'footprint'})}</p>` : ""}
</div>
</div>
</div>
</a>
`;
},
},
},
];
},
});
}
}

File diff suppressed because it is too large Load diff

252
composer.lock generated
View file

@ -4670,16 +4670,16 @@
}, },
{ {
"name": "omines/datatables-bundle", "name": "omines/datatables-bundle",
"version": "0.8.0", "version": "0.8.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/omines/datatables-bundle.git", "url": "https://github.com/omines/datatables-bundle.git",
"reference": "d0503e8bd56f5c4b379e930f51f499d0a04d07c1" "reference": "3d31d1cddac5635803f59b3f7905feb0d4209c80"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/omines/datatables-bundle/zipball/d0503e8bd56f5c4b379e930f51f499d0a04d07c1", "url": "https://api.github.com/repos/omines/datatables-bundle/zipball/3d31d1cddac5635803f59b3f7905feb0d4209c80",
"reference": "d0503e8bd56f5c4b379e930f51f499d0a04d07c1", "reference": "3d31d1cddac5635803f59b3f7905feb0d4209c80",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -4691,36 +4691,36 @@
"symfony/translation": "^6.3|^7.0" "symfony/translation": "^6.3|^7.0"
}, },
"require-dev": { "require-dev": {
"doctrine/common": "^2.6|^3.3", "doctrine/common": "^3.4.3",
"doctrine/doctrine-bundle": "^2.11.1", "doctrine/doctrine-bundle": "^2.11.1",
"doctrine/orm": "^2.13.1", "doctrine/orm": "^2.17.2",
"doctrine/persistence": "^3.0.3", "doctrine/persistence": "^3.2.0",
"ext-curl": "*", "ext-curl": "*",
"ext-json": "*", "ext-json": "*",
"ext-mongodb": "*", "ext-mongodb": "*",
"ext-pdo_sqlite": "*", "ext-pdo_sqlite": "*",
"ext-zip": "*", "ext-zip": "*",
"friendsofphp/php-cs-fixer": "^v3.40.0", "friendsofphp/php-cs-fixer": "^v3.40.0",
"mongodb/mongodb": "^1.12", "mongodb/mongodb": "^1.17",
"ocramius/package-versions": "^2.8", "ocramius/package-versions": "^2.8",
"phpoffice/phpspreadsheet": "^1.24.1", "phpoffice/phpspreadsheet": "^1.29.0 || ^2.0",
"phpstan/extension-installer": "^1.1", "phpstan/extension-installer": "^1.3.1",
"phpstan/phpstan": "^1.8.2", "phpstan/phpstan": "^1.10.55",
"phpstan/phpstan-doctrine": "^1.3.12", "phpstan/phpstan-doctrine": "^1.3.54",
"phpstan/phpstan-phpunit": "^1.1", "phpstan/phpstan-phpunit": "^1.3.15",
"phpstan/phpstan-symfony": "^1.2.9", "phpstan/phpstan-symfony": "^1.3.6",
"phpunit/phpunit": "^10.5.1", "phpunit/phpunit": "^11.0.3",
"ruflin/elastica": "^6.0|^7.2", "ruflin/elastica": "^6.2|^7.3.1",
"symfony/browser-kit": "^6.1.3|^7.0", "symfony/browser-kit": "^6.3|^7.0",
"symfony/css-selector": "^6.1.3|^7.0", "symfony/css-selector": "^6.3|^7.0",
"symfony/doctrine-bridge": "^6.3|^7.0", "symfony/doctrine-bridge": "^6.3|^7.0.2",
"symfony/dom-crawler": "^6.1.3|^7.0", "symfony/dom-crawler": "^6.3|^7.0",
"symfony/intl": "^6.1|^7.0", "symfony/intl": "^6.3|^7.0.2",
"symfony/mime": "^6.1.3|^7.0", "symfony/mime": "^6.3|^7.0",
"symfony/phpunit-bridge": "^6.3|^7.0", "symfony/phpunit-bridge": "^6.3|^7.0.2",
"symfony/twig-bundle": "^6.1.1|^7.0", "symfony/twig-bundle": "^6.3|^7.0",
"symfony/var-dumper": "^6.1.3|^7.0", "symfony/var-dumper": "^6.3|^7.0.2",
"symfony/yaml": "^6.1.3|^7.0" "symfony/yaml": "^6.3|^7.0"
}, },
"suggest": { "suggest": {
"doctrine/doctrine-bundle": "For integrated access to Doctrine object managers", "doctrine/doctrine-bundle": "For integrated access to Doctrine object managers",
@ -4771,7 +4771,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/omines/datatables-bundle/issues", "issues": "https://github.com/omines/datatables-bundle/issues",
"source": "https://github.com/omines/datatables-bundle/tree/0.8.0" "source": "https://github.com/omines/datatables-bundle/tree/0.8.1"
}, },
"funding": [ "funding": [
{ {
@ -4779,7 +4779,7 @@
"type": "github" "type": "github"
} }
], ],
"time": "2023-12-05T08:18:04+00:00" "time": "2024-02-24T22:55:33+00:00"
}, },
{ {
"name": "onelogin/php-saml", "name": "onelogin/php-saml",
@ -6971,86 +6971,6 @@
], ],
"time": "2023-12-25T11:42:15+00:00" "time": "2023-12-25T11:42:15+00:00"
}, },
{
"name": "spomky-labs/cbor-bundle",
"version": "v3.0.0",
"source": {
"type": "git",
"url": "https://github.com/Spomky-Labs/cbor-bundle.git",
"reference": "157ca6ed2f6e957f9e95d71ca86bc67bf42ee79c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Spomky-Labs/cbor-bundle/zipball/157ca6ed2f6e957f9e95d71ca86bc67bf42ee79c",
"reference": "157ca6ed2f6e957f9e95d71ca86bc67bf42ee79c",
"shasum": ""
},
"require": {
"php": ">=8.0",
"spomky-labs/cbor-php": "^3.0",
"symfony/config": "^5.3|^6.0",
"symfony/dependency-injection": "^5.3|^6.0",
"symfony/http-kernel": "^5.3|^6.0"
},
"require-dev": {
"infection/infection": "^0.25.3",
"phpstan/extension-installer": "^1.1",
"phpstan/phpstan": "^1.0",
"phpstan/phpstan-beberlei-assert": "^1.0",
"phpstan/phpstan-deprecation-rules": "^1.0",
"phpstan/phpstan-phpunit": "^1.0",
"phpstan/phpstan-strict-rules": "^1.0",
"phpunit/phpunit": "^9.0",
"rector/rector": "^0.12.5",
"symfony/framework-bundle": "^5.3|^6.0",
"symfony/phpunit-bridge": "^5.3|^6.0",
"symplify/easy-coding-standard": "^9.4"
},
"type": "symfony-bundle",
"autoload": {
"psr-4": {
"SpomkyLabs\\CborBundle\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Florent Morselli",
"homepage": "https://github.com/Spomky"
},
{
"name": "All contributors",
"homepage": "https://github.com/spomky-labs/cbor-bundle/contributors"
}
],
"description": "CBOR Encoder/Decoder Bundle for Symfony.",
"homepage": "https://github.com/spomky-labs",
"keywords": [
"Concise Binary Object Representation",
"RFC7049",
"bundle",
"cbor",
"symfony"
],
"support": {
"issues": "https://github.com/Spomky-Labs/cbor-bundle/issues",
"source": "https://github.com/Spomky-Labs/cbor-bundle/tree/v3.0.0"
},
"funding": [
{
"url": "https://github.com/Spomky",
"type": "github"
},
{
"url": "https://www.patreon.com/FlorentMorselli",
"type": "patreon"
}
],
"time": "2021-11-23T21:41:00+00:00"
},
{ {
"name": "spomky-labs/cbor-php", "name": "spomky-labs/cbor-php",
"version": "3.0.4", "version": "3.0.4",
@ -14037,16 +13957,16 @@
}, },
{ {
"name": "web-auth/metadata-service", "name": "web-auth/metadata-service",
"version": "4.7.9", "version": "4.8.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/web-auth/webauthn-metadata-service.git", "url": "https://github.com/web-auth/webauthn-metadata-service.git",
"reference": "1da1fc6d8055c75af4e46cde169d7b920b8af90a" "reference": "039e3ce40a06ab12f0090ac410da8e7a07fc2c2b"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/web-auth/webauthn-metadata-service/zipball/1da1fc6d8055c75af4e46cde169d7b920b8af90a", "url": "https://api.github.com/repos/web-auth/webauthn-metadata-service/zipball/039e3ce40a06ab12f0090ac410da8e7a07fc2c2b",
"reference": "1da1fc6d8055c75af4e46cde169d7b920b8af90a", "reference": "039e3ce40a06ab12f0090ac410da8e7a07fc2c2b",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -14063,10 +13983,11 @@
"symfony/deprecation-contracts": "^3.2" "symfony/deprecation-contracts": "^3.2"
}, },
"suggest": { "suggest": {
"phpdocumentor/reflection-docblock": "As of 4.5.x, the phpdocumentor/reflection-docblock component will become mandatory for converting objects such as the Metadata Statement",
"psr/clock-implementation": "As of 4.5.x, the PSR Clock implementation will replace lcobucci/clock", "psr/clock-implementation": "As of 4.5.x, the PSR Clock implementation will replace lcobucci/clock",
"psr/log-implementation": "Recommended to receive logs from the library", "psr/log-implementation": "Recommended to receive logs from the library",
"web-token/jwt-key-mgmt": "Mandatory for fetching Metadata Statement from distant sources", "symfony/serializer": "As of 4.5.x, the symfony/serializer component will become mandatory for converting objects such as the Metadata Statement",
"web-token/jwt-signature-algorithm-ecdsa": "Mandatory for fetching Metadata Statement from distant sources" "web-token/jwt-library": "Mandatory for fetching Metadata Statement from distant sources"
}, },
"type": "library", "type": "library",
"extra": { "extra": {
@ -14102,7 +14023,7 @@
"webauthn" "webauthn"
], ],
"support": { "support": {
"source": "https://github.com/web-auth/webauthn-metadata-service/tree/4.7.9" "source": "https://github.com/web-auth/webauthn-metadata-service/tree/4.8.0"
}, },
"funding": [ "funding": [
{ {
@ -14114,20 +14035,20 @@
"type": "patreon" "type": "patreon"
} }
], ],
"time": "2023-10-07T13:59:48+00:00" "time": "2024-02-24T09:40:29+00:00"
}, },
{ {
"name": "web-auth/webauthn-lib", "name": "web-auth/webauthn-lib",
"version": "4.7.9", "version": "4.8.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/web-auth/webauthn-lib.git", "url": "https://github.com/web-auth/webauthn-lib.git",
"reference": "03a652042d7b5e919e449954d729ced26ee3c3c2" "reference": "dee648c4a0971633c9434391c710bd3f244d6aed"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/web-auth/webauthn-lib/zipball/03a652042d7b5e919e449954d729ced26ee3c3c2", "url": "https://api.github.com/repos/web-auth/webauthn-lib/zipball/dee648c4a0971633c9434391c710bd3f244d6aed",
"reference": "03a652042d7b5e919e449954d729ced26ee3c3c2", "reference": "dee648c4a0971633c9434391c710bd3f244d6aed",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -14148,10 +14069,7 @@
"suggest": { "suggest": {
"psr/log-implementation": "Recommended to receive logs from the library", "psr/log-implementation": "Recommended to receive logs from the library",
"symfony/event-dispatcher": "Recommended to use dispatched events", "symfony/event-dispatcher": "Recommended to use dispatched events",
"web-token/jwt-key-mgmt": "Mandatory for the AndroidSafetyNet Attestation Statement support", "web-token/jwt-library": "Mandatory for the AndroidSafetyNet Attestation Statement support"
"web-token/jwt-signature-algorithm-ecdsa": "Recommended for the AndroidSafetyNet Attestation Statement support",
"web-token/jwt-signature-algorithm-eddsa": "Recommended for the AndroidSafetyNet Attestation Statement support",
"web-token/jwt-signature-algorithm-rsa": "Mandatory for the AndroidSafetyNet Attestation Statement support"
}, },
"type": "library", "type": "library",
"extra": { "extra": {
@ -14187,7 +14105,7 @@
"webauthn" "webauthn"
], ],
"support": { "support": {
"source": "https://github.com/web-auth/webauthn-lib/tree/4.7.9" "source": "https://github.com/web-auth/webauthn-lib/tree/4.8.0"
}, },
"funding": [ "funding": [
{ {
@ -14199,39 +14117,38 @@
"type": "patreon" "type": "patreon"
} }
], ],
"time": "2024-02-05T17:20:58+00:00" "time": "2024-02-23T11:09:26+00:00"
}, },
{ {
"name": "web-auth/webauthn-symfony-bundle", "name": "web-auth/webauthn-symfony-bundle",
"version": "4.7.9", "version": "4.8.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/web-auth/webauthn-symfony-bundle.git", "url": "https://github.com/web-auth/webauthn-symfony-bundle.git",
"reference": "f7a677c4063d1266d66dd4ef26833985a6afb4b9" "reference": "d72050d6ce8cf6d7bd6180de7eb9204d1e4233a2"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/web-auth/webauthn-symfony-bundle/zipball/f7a677c4063d1266d66dd4ef26833985a6afb4b9", "url": "https://api.github.com/repos/web-auth/webauthn-symfony-bundle/zipball/d72050d6ce8cf6d7bd6180de7eb9204d1e4233a2",
"reference": "f7a677c4063d1266d66dd4ef26833985a6afb4b9", "reference": "d72050d6ce8cf6d7bd6180de7eb9204d1e4233a2",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"nyholm/psr7": "^1.5", "nyholm/psr7": "^1.5",
"php": ">=8.1", "php": ">=8.1",
"psr/event-dispatcher": "^1.0", "psr/event-dispatcher": "^1.0",
"spomky-labs/cbor-bundle": "^3.0",
"symfony/config": "^6.1|^7.0", "symfony/config": "^6.1|^7.0",
"symfony/dependency-injection": "^6.1|^7.0", "symfony/dependency-injection": "^6.1|^7.0",
"symfony/framework-bundle": "^6.1|^7.0", "symfony/framework-bundle": "^6.1|^7.0",
"symfony/http-client": "^6.1|^7.0", "symfony/http-client": "^6.1|^7.0",
"symfony/psr-http-message-bridge": "^2.1", "symfony/psr-http-message-bridge": "^2.1|^6.1|^7.0",
"symfony/security-bundle": "^6.1|^7.0", "symfony/security-bundle": "^6.1|^7.0",
"symfony/security-core": "^6.1|^7.0", "symfony/security-core": "^6.1|^7.0",
"symfony/security-http": "^6.1|^7.0", "symfony/security-http": "^6.1|^7.0",
"symfony/serializer": "^6.1|^7.0", "symfony/serializer": "^6.1|^7.0",
"symfony/validator": "^6.1|^7.0", "symfony/validator": "^6.1|^7.0",
"web-auth/webauthn-lib": "self.version", "web-auth/webauthn-lib": "self.version",
"web-token/jwt-signature": "^3.1" "web-token/jwt-library": "^3.3"
}, },
"type": "symfony-bundle", "type": "symfony-bundle",
"extra": { "extra": {
@ -14270,7 +14187,7 @@
"webauthn" "webauthn"
], ],
"support": { "support": {
"source": "https://github.com/web-auth/webauthn-symfony-bundle/tree/4.7.9" "source": "https://github.com/web-auth/webauthn-symfony-bundle/tree/4.8.0"
}, },
"funding": [ "funding": [
{ {
@ -14282,7 +14199,7 @@
"type": "patreon" "type": "patreon"
} }
], ],
"time": "2023-12-08T13:02:43+00:00" "time": "2024-02-23T11:09:26+00:00"
}, },
{ {
"name": "web-token/jwt-library", "name": "web-token/jwt-library",
@ -14381,71 +14298,6 @@
], ],
"time": "2024-02-22T08:15:45+00:00" "time": "2024-02-22T08:15:45+00:00"
}, },
{
"name": "web-token/jwt-signature",
"version": "3.3.0",
"source": {
"type": "git",
"url": "https://github.com/web-token/jwt-signature.git",
"reference": "eccfd59e658d4118414cf6d14229aa52eec387e7"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/web-token/jwt-signature/zipball/eccfd59e658d4118414cf6d14229aa52eec387e7",
"reference": "eccfd59e658d4118414cf6d14229aa52eec387e7",
"shasum": ""
},
"require": {
"php": ">=8.1",
"web-token/jwt-library": "^3.3"
},
"type": "library",
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Florent Morselli",
"homepage": "https://github.com/Spomky"
},
{
"name": "All contributors",
"homepage": "https://github.com/web-token/jwt-framework/contributors"
}
],
"description": "[DEPRECATED] Please use web-token/jwt-library instead.",
"homepage": "https://github.com/web-token",
"keywords": [
"JOSE",
"JWE",
"JWK",
"JWKSet",
"JWS",
"Jot",
"RFC7515",
"RFC7516",
"RFC7517",
"RFC7518",
"RFC7519",
"RFC7520",
"bundle",
"jwa",
"jwt",
"symfony"
],
"support": {
"source": "https://github.com/web-token/jwt-signature/tree/3.3.0"
},
"funding": [
{
"url": "https://www.patreon.com/FlorentMorselli",
"type": "patreon"
}
],
"abandoned": "web-token/jwt-library",
"time": "2024-02-22T07:19:34+00:00"
},
{ {
"name": "webmozart/assert", "name": "webmozart/assert",
"version": "1.11.0", "version": "1.11.0",

View file

@ -24,7 +24,6 @@ return [
Symfony\UX\Turbo\TurboBundle::class => ['all' => true], Symfony\UX\Turbo\TurboBundle::class => ['all' => true],
Jbtronics\TFAWebauthn\TFAWebauthnBundle::class => ['all' => true], Jbtronics\TFAWebauthn\TFAWebauthnBundle::class => ['all' => true],
Scheb\TwoFactorBundle\SchebTwoFactorBundle::class => ['all' => true], Scheb\TwoFactorBundle\SchebTwoFactorBundle::class => ['all' => true],
SpomkyLabs\CborBundle\SpomkyLabsCborBundle::class => ['all' => true],
Webauthn\Bundle\WebauthnBundle::class => ['all' => true], Webauthn\Bundle\WebauthnBundle::class => ['all' => true],
Nbgrp\OneloginSamlBundle\NbgrpOneloginSamlBundle::class => ['all' => true], Nbgrp\OneloginSamlBundle\NbgrpOneloginSamlBundle::class => ['all' => true],
Symfony\UX\StimulusBundle\StimulusBundle::class => ['all' => true], Symfony\UX\StimulusBundle\StimulusBundle::class => ['all' => true],

View file

@ -30,6 +30,9 @@
"build": "encore production --progress" "build": "encore production --progress"
}, },
"dependencies": { "dependencies": {
"@algolia/autocomplete-js": "^1.17.0",
"@algolia/autocomplete-plugin-recent-searches": "^1.17.0",
"@algolia/autocomplete-theme-classic": "^1.17.0",
"@ckeditor/ckeditor5-alignment": "^41.0.0", "@ckeditor/ckeditor5-alignment": "^41.0.0",
"@ckeditor/ckeditor5-autoformat": "^41.0.0", "@ckeditor/ckeditor5-autoformat": "^41.0.0",
"@ckeditor/ckeditor5-basic-styles": "^41.0.0", "@ckeditor/ckeditor5-basic-styles": "^41.0.0",

View file

@ -453,9 +453,6 @@
"shivas/versioning-bundle": { "shivas/versioning-bundle": {
"version": "3.1.3" "version": "3.1.3"
}, },
"spomky-labs/cbor-bundle": {
"version": "v2.0.3"
},
"symfony/apache-pack": { "symfony/apache-pack": {
"version": "1.0", "version": "1.0",
"recipe": { "recipe": {

View file

@ -1,4 +1,5 @@
{% import "helper.twig" as helper %} {% import "helper.twig" as helper %}
{% import "components/search.macro.html.twig" as search %}
<nav class="navbar navbar-expand-md bg-body-tertiary border-bottom shadow-sm fixed-top py-0" id="navbar"> <nav class="navbar navbar-expand-md bg-body-tertiary border-bottom shadow-sm fixed-top py-0" id="navbar">
<div class="container-fluid"> <div class="container-fluid">
@ -58,7 +59,9 @@
</ul> </ul>
{% if is_granted('@parts.read') %} {% if is_granted('@parts.read') %}
{% include "_navbar_search.html.twig" %} {{ search.search_form("navbar") }}
{# {% include "_navbar_search.html.twig" %} #}
{% endif %} {% endif %}

View file

@ -1,7 +1,8 @@
<form id="navbar-search-form" action="{{ path('parts_search') }}" class="d-flex my-lg-0 ms-auto" method="get" data-turbo-permanent> {% macro settings_drodown(show_label_instead_icon = true) %}
<div class="dropdown"> <div class="dropdown">
<button class="btn dropdown-toggle my-2" type="button" id="navbar-search-options" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false" data-bs-auto-close="false"> <button class="btn dropdown-toggle my-2" type="button" id="navbar-search-options" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false" data-bs-auto-close="false">
{% trans %}search.options.label{% endtrans %} {% if show_label_instead_icon %}{% trans %}search.options.label{% endtrans %}{% else %}<i class="fa-solid fa-gear"></i>{% endif %}
<span class="caret"></span> <span class="caret"></span>
</button> </button>
<div class="dropdown-menu" aria-labelledby="navbar-search-options"> <div class="dropdown-menu" aria-labelledby="navbar-search-options">
@ -68,7 +69,37 @@
</div> </div>
</div> </div>
</div> </div>
{% endmacro %}
<input type="search" class="form-control me-sm-2 my-2" placeholder="{% trans %}search.placeholder{% endtrans %}" name="keyword" required> {# Render a complete usable search form including the form tags. mode can be "standalone" or "navbar" #}
<button type="submit" class="form btn btn-outline-secondary my-2 text-nowrap">{% trans %}search.submit{% endtrans %}</button> {% macro search_form(mode = "standalone") %}
</form> {% set is_navbar = (mode == "navbar") %}
<form action="{{ path('parts_search') }}" class="d-flex {% if is_navbar %}my-lg-0{% endif%} ms-auto" method="get"
{# Navbar element needs to be persistent #}
{% if is_navbar %}id="navbar-search-form" data-turbo-permanent{% endif %}>
{# Show the options left in navbar #}
{% if is_navbar %}
{{ _self.settings_drodown(is_navbar) }}
{% endif %}
<div {{ stimulus_controller('elements/part_search') }}
class="mt-auto mb-auto {% if not is_navbar %}w-100{% endif %}"
{% if is_navbar %}id="navbar-quicksearch-container"{% endif %}
data-panel-placement="{% if is_navbar %}end{% else %}input-wrapper-width{% endif %}"
data-navbar-mode="{% if is_navbar %}true{% else %}false{% endif %}"
data-placeholder-image="{{ asset('img/part_placeholder.svg') }}"
data-autocomplete="{{ path('typeahead_parts', {'query': '__QUERY__'}) }}"
data-detail-url="{{ path('part_info', {'id': '__ID__'}) }}">
<input type="hidden" name="keyword" required {{ stimulus_target('elements/part_search', 'input') }}>
</div>
{# And right in the standalone mode #}
{% if not is_navbar %}
{{ _self.settings_drodown(is_navbar) }}
{% endif %}
</form>
{% endmacro %}

View file

@ -1,6 +1,7 @@
{% extends "base.html.twig" %} {% extends "base.html.twig" %}
{% import "components/new_version.macro.html.twig" as nv %} {% import "components/new_version.macro.html.twig" as nv %}
{% import "components/search.macro.html.twig" as search %}
{% block content %} {% block content %}
@ -8,6 +9,12 @@
{{ nv.new_version_alert(new_version_available, new_version, new_version_url) }} {{ nv.new_version_alert(new_version_available, new_version, new_version_url) }}
{% endif %} {% endif %}
{% if is_granted('@parts.read') %}
{{ search.search_form("standalone") }}
<div class="mb-2"></div>
{% endif %}
<div class="rounded p-4 bg-body-secondary"> <div class="rounded p-4 bg-body-secondary">
<h1 class="display-3">{{ partdb_title }}</h1> <h1 class="display-3">{{ partdb_title }}</h1>
<h4> <h4>

View file

@ -2,6 +2,59 @@
# yarn lockfile v1 # 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-recent-searches@^1.17.0":
version "1.17.0"
resolved "https://registry.yarnpkg.com/@algolia/autocomplete-plugin-recent-searches/-/autocomplete-plugin-recent-searches-1.17.0.tgz#ed340649481398feee12a9e7f1bfd66f90e1fbab"
integrity sha512-di5ZEFx0UgK7sR5pxon9NKiFrLL26J5xwL7ihhK4rHrSdRhSvRATr9d8uaShAZIveEUTMd/cZd6C+95Y1YrcdQ==
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": "@ampproject/remapping@^2.2.0":
version "2.2.1" version "2.2.1"
resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.1.tgz#99e8e11851128b8702cd57c33684f1d0f260b630" 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" readable-stream "^2.0.1"
wbuf "^1.1.0" 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: html-encoding-sniffer@^2.0.1:
version "2.0.1" version "2.0.1"
resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz#42a6dc4fd33f00281176e8b23759ca4e4fa185f3" 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" picocolors "^1.0.0"
source-map-js "^1.0.2" 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: prelude-ls@~1.1.2:
version "1.1.2" version "1.1.2"
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54"