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"