diff --git a/assets/controllers/elements/collection_type_controller.js b/assets/controllers/elements/collection_type_controller.js
index 8b816f30..14b683e0 100644
--- a/assets/controllers/elements/collection_type_controller.js
+++ b/assets/controllers/elements/collection_type_controller.js
@@ -21,6 +21,7 @@ import {Controller} from "@hotwired/stimulus";
import * as bootbox from "bootbox";
import "../../css/components/bootbox_extensions.css";
+import accept from "attr-accept";
export default class extends Controller {
static values = {
@@ -112,6 +113,33 @@ export default class extends Controller {
dataTransfer.items.add(file);
rowInput.files = dataTransfer.files;
+
+ //Check the file extension and find the corresponding attachment type based on the data-filetype_filter attribute
+ const attachmentTypeSelect = newElement.querySelector("select");
+ if (attachmentTypeSelect) {
+ let foundMatch = false;
+ for (let j = 0; j < attachmentTypeSelect.options.length; j++) {
+ const option = attachmentTypeSelect.options[j];
+ //skip disabled options
+ if (option.disabled) {
+ continue;
+ }
+
+ const filter = option.getAttribute('data-filetype_filter');
+ if (filter) {
+ if (accept({name: file.name, type: file.type}, filter)) {
+ attachmentTypeSelect.value = option.value;
+ foundMatch = true;
+ break;
+ }
+ } else { //If no filter is set, chose this option until we find a better match
+ if (!foundMatch) {
+ attachmentTypeSelect.value = option.value;
+ foundMatch = true;
+ }
+ }
+ }
+ }
}
});
@@ -189,4 +217,4 @@ export default class extends Controller {
del();
}
}
-}
\ No newline at end of file
+}
diff --git a/assets/controllers/elements/part_select_controller.js b/assets/controllers/elements/part_select_controller.js
index 8a4e19b8..b69acbbc 100644
--- a/assets/controllers/elements/part_select_controller.js
+++ b/assets/controllers/elements/part_select_controller.js
@@ -18,7 +18,7 @@ export default class extends Controller {
let settings = {
allowEmptyOption: true,
- plugins: ['dropdown_input'],
+ plugins: ['dropdown_input', this.element.required ? null : 'clear_button'],
searchField: ["name", "description", "category", "footprint"],
valueField: "id",
labelField: "name",
diff --git a/package.json b/package.json
index 583b21a2..583d0b42 100644
--- a/package.json
+++ b/package.json
@@ -46,6 +46,7 @@
"@zxcvbn-ts/language-en": "^3.0.1",
"@zxcvbn-ts/language-fr": "^3.0.1",
"@zxcvbn-ts/language-ja": "^3.0.1",
+ "attr-accept": "^2.2.5",
"barcode-detector": "^3.0.5",
"bootbox": "^6.0.0",
"bootswatch": "^5.1.3",
diff --git a/src/Controller/InfoProviderController.php b/src/Controller/InfoProviderController.php
index b79c307c..e5a5d87b 100644
--- a/src/Controller/InfoProviderController.php
+++ b/src/Controller/InfoProviderController.php
@@ -40,10 +40,13 @@ use Symfony\Bridge\Doctrine\Attribute\MapEntity;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\HttpClient\Exception\ClientException;
+use Symfony\Component\HttpClient\Exception\TransportException;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
+use Symfony\Contracts\HttpClient\Exception\ExceptionInterface;
+
use function Symfony\Component\Translation\t;
#[Route('/tools/info_providers')]
@@ -178,6 +181,13 @@ class InfoProviderController extends AbstractController
$exceptionLogger->error('Error during info provider search: ' . $e->getMessage(), ['exception' => $e]);
} catch (OAuthReconnectRequiredException $e) {
$this->addFlash('error', t('info_providers.search.error.oauth_reconnect', ['%provider%' => $e->getProviderName()]));
+ } catch (TransportException $e) {
+ $this->addFlash('error', t('info_providers.search.error.transport_exception'));
+ $exceptionLogger->error('Transport error during info provider search: ' . $e->getMessage(), ['exception' => $e]);
+ } catch (\RuntimeException $e) {
+ $this->addFlash('error', t('info_providers.search.error.general_exception', ['%type%' => (new \ReflectionClass($e))->getShortName()]));
+ //Log the exception
+ $exceptionLogger->error('Error during info provider search: ' . $e->getMessage(), ['exception' => $e]);
}
diff --git a/translations/messages.en.xlf b/translations/messages.en.xlf
index f7f10146..dc8cbcbb 100644
--- a/translations/messages.en.xlf
+++ b/translations/messages.en.xlf
@@ -14274,5 +14274,17 @@ Buerklin-API Authentication server:
[Part] ID
+
+
+ info_providers.search.error.general_exception
+ Unknown error while trying to retrieve parts from info provider: %type%. Check that your providers are configured correctly and access keys are correct. See server logs for more information.
+
+
+
+
+ info_providers.search.error.transport_exception
+ Transport error while retrieving information from the providers. Check that your server has internet accesss. See server logs for more info.
+
+
diff --git a/yarn.lock b/yarn.lock
index ed92b354..24c8d5be 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2556,6 +2556,11 @@ async-function@^1.0.0:
resolved "https://registry.yarnpkg.com/async-function/-/async-function-1.0.0.tgz#509c9fca60eaf85034c6829838188e4e4c8ffb2b"
integrity sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==
+attr-accept@^2.2.5:
+ version "2.2.5"
+ resolved "https://registry.yarnpkg.com/attr-accept/-/attr-accept-2.2.5.tgz#d7061d958e6d4f97bf8665c68b75851a0713ab5e"
+ integrity sha512-0bDNnY/u6pPwHDMoF0FieU354oBi0a8rD9FcsLwzcGWbc8KS8KPIi7y+s13OlVY+gMWc/9xEMUgNE6Qm8ZllYQ==
+
available-typed-arrays@^1.0.7:
version "1.0.7"
resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz#a5cc375d6a03c2efc87a553f3e0b1522def14846"