Compare commits

...

7 commits

Author SHA1 Message Date
Jan Böhmer
600686c32b Fixed phpstan issue
Some checks failed
Build assets artifact / Build assets artifact (push) Has been cancelled
Docker Image Build / docker (push) Has been cancelled
Docker Image Build (FrankenPHP) / docker (push) Has been cancelled
Static analysis / Static analysis (push) Has been cancelled
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.2, mysql) (push) Has been cancelled
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.3, mysql) (push) Has been cancelled
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.4, mysql) (push) Has been cancelled
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.5, mysql) (push) Has been cancelled
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.2, postgres) (push) Has been cancelled
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.3, postgres) (push) Has been cancelled
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.4, postgres) (push) Has been cancelled
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.5, postgres) (push) Has been cancelled
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.2, sqlite) (push) Has been cancelled
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.3, sqlite) (push) Has been cancelled
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.4, sqlite) (push) Has been cancelled
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.5, sqlite) (push) Has been cancelled
2025-10-19 16:20:08 +02:00
Jan Böhmer
2e3ff05d83 Merge remote-tracking branch 'origin/master' 2025-10-19 16:09:34 +02:00
Jan Böhmer
e9dcdbc30d Bump to Version 2.2.1 2025-10-19 16:09:29 +02:00
Jan Böhmer
6cbb482c0f
New Crowdin updates (#1083)
* New translations messages.en.xlf (English)

* New translations messages.en.xlf (English)

* New translations messages.en.xlf (English)

* New translations messages.en.xlf (English)

* New translations messages.en.xlf (German)
2025-10-19 16:08:42 +02:00
Jan Böhmer
68aafc4d2e Better align the part parameter tables to each other
Fixes issue #1066
2025-10-19 15:56:18 +02:00
Jan Böhmer
70354c8599 Try to show an more detailed error message, if digikey needs oauth reconnection 2025-10-19 15:45:48 +02:00
Jan Böhmer
43601e060c Update label when pressing enter in label dialog
Fixes issue #996
2025-10-19 15:15:25 +02:00
9 changed files with 234 additions and 63 deletions

View file

@ -1 +1 @@
2.2.0
2.2.1

View file

@ -25,6 +25,7 @@ namespace App\Controller;
use App\Entity\Parts\Manufacturer;
use App\Entity\Parts\Part;
use App\Exceptions\OAuthReconnectRequiredException;
use App\Form\InfoProviderSystem\PartSearchType;
use App\Services\InfoProviderSystem\ExistingPartFinder;
use App\Services\InfoProviderSystem\PartInfoRetriever;
@ -175,8 +176,11 @@ class InfoProviderController extends AbstractController
$this->addFlash('error',$e->getMessage());
//Log the exception
$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()]));
}
// modify the array to an array of arrays that has a field for a matching local Part
// the advantage to use that format even when we don't look for local parts is that we
// always work with the same interface

View file

@ -0,0 +1,48 @@
<?php
/*
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
*
* Copyright (C) 2019 - 2025 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/>.
*/
declare(strict_types=1);
namespace App\Exceptions;
use Throwable;
class OAuthReconnectRequiredException extends \RuntimeException
{
private string $providerName = "unknown";
public function __construct(string $message = "You need to reconnect the OAuth connection for this provider!", int $code = 0, ?Throwable $previous = null)
{
parent::__construct($message, $code, $previous);
}
public static function forProvider(string $providerName): self
{
$exception = new self("You need to reconnect the OAuth connection for the provider '$providerName'!");
$exception->providerName = $providerName;
return $exception;
}
public function getProviderName(): string
{
return $this->providerName;
}
}

View file

@ -24,6 +24,7 @@ declare(strict_types=1);
namespace App\Services\InfoProviderSystem\Providers;
use App\Entity\Parts\ManufacturingStatus;
use App\Exceptions\OAuthReconnectRequiredException;
use App\Services\InfoProviderSystem\DTOs\FileDTO;
use App\Services\InfoProviderSystem\DTOs\ParameterDTO;
use App\Services\InfoProviderSystem\DTOs\PartDetailDTO;
@ -117,12 +118,22 @@ class DigikeyProvider implements InfoProviderInterface
];
//$response = $this->digikeyClient->request('POST', '/Search/v3/Products/Keyword', [
$response = $this->digikeyClient->request('POST', '/products/v4/search/keyword', [
'json' => $request,
'auth_bearer' => $this->authTokenManager->getAlwaysValidTokenString(self::OAUTH_APP_NAME)
]);
try {
$response = $this->digikeyClient->request('POST', '/products/v4/search/keyword', [
'json' => $request,
'auth_bearer' => $this->authTokenManager->getAlwaysValidTokenString(self::OAUTH_APP_NAME)
]);
$response_array = $response->toArray();
} catch (\InvalidArgumentException $exception) {
//Check if the exception was caused by an invalid or expired token
if (str_contains($exception->getMessage(), 'access_token')) {
throw OAuthReconnectRequiredException::forProvider($this->getProviderKey());
}
throw $exception;
}
$response_array = $response->toArray();
$result = [];
@ -150,9 +161,18 @@ class DigikeyProvider implements InfoProviderInterface
public function getDetails(string $id): PartDetailDTO
{
$response = $this->digikeyClient->request('GET', '/products/v4/search/' . urlencode($id) . '/productdetails', [
'auth_bearer' => $this->authTokenManager->getAlwaysValidTokenString(self::OAUTH_APP_NAME)
]);
try {
$response = $this->digikeyClient->request('GET', '/products/v4/search/' . urlencode($id) . '/productdetails', [
'auth_bearer' => $this->authTokenManager->getAlwaysValidTokenString(self::OAUTH_APP_NAME)
]);
} catch (\InvalidArgumentException $exception) {
//Check if the exception was caused by an invalid or expired token
if (str_contains($exception->getMessage(), 'access_token')) {
throw OAuthReconnectRequiredException::forProvider($this->getProviderKey());
}
throw $exception;
}
$response_array = $response->toArray();
$product = $response_array['Product'];

View file

@ -214,11 +214,11 @@
{% endmacro %}
{% macro parameters_table(parameters) %}
<table class="table table-hover table-striped table-sm">
<table class="table table-hover table-striped table-sm" style="table-layout: fixed;">
<thead>
<tr>
<th>{% trans %}specifications.property{% endtrans %}</th>
<th>{% trans %}specifications.symbol{% endtrans %}</th>
<th class="col-sm-1">{% trans %}specifications.symbol{% endtrans %}</th>
<th>{% trans %}specifications.value{% endtrans %}</th>
</tr>
</thead>
@ -240,4 +240,4 @@
{% else %}
{{ datetime|format_datetime }}
{% endif %}
{% endmacro %}
{% endmacro %}

View file

@ -10,6 +10,9 @@
{% block card_content %}
{{ form_start(form) }}
{# Default submit to use when pressing enter. #}
<input type="submit" name="label_dialog[update]" class="d-none">
<ul class="nav nav-tabs">
<li class="nav-item">
<a class="nav-link active" data-bs-toggle="tab" id="common-tab" role="tab" aria-controls="common" aria-selected="true" href="#common"

View file

@ -4,6 +4,9 @@
{% for name, parameters in part.groupedParameters %}
{% if name is not empty %}<h5 class="mt-1">{{ name }}</h5>{% endif %}
{{ helper.parameters_table(parameters) }}
{% if not loop.last %}
<hr class="my-0">
{% endif %}
{% endfor %}
{% if description_params is not empty %}
@ -14,4 +17,4 @@
{% if comment_params is not empty %}
<h5 class="mt-1">{% trans %}parameters.auto_extracted_from_comment{% endtrans %}</h5>
{{ helper.parameters_table(comment_params) }}
{% endif %}
{% endif %}

View file

@ -8711,7 +8711,7 @@ Element 1 -&gt; Element 1.2</target>
</notes>
<segment state="translated">
<source>log.type.security.backup_keys_reset</source>
<target>Neue Backupkeys erzeugt</target>
<target>Neue Backup-Keys erzeugt</target>
</segment>
</unit>
<unit id="RF1.KEr" name="log.type.security.google_enabled">
@ -14189,5 +14189,66 @@ Bitte beachten Sie, dass Sie sich nicht als deaktivierter Benutzer ausgeben kön
<target>Maximale Anzahl von Zuordnungen erreicht</target>
</segment>
</unit>
<unit id="LWLi016" name="settings.system">
<segment state="translated">
<source>settings.system</source>
<target>System</target>
</segment>
</unit>
<unit id="8syOoyh" name="settings.behavior">
<segment state="translated">
<source>settings.behavior</source>
<target>Verhalten</target>
</segment>
</unit>
<unit id="lAiL2Jw" name="settings.ips">
<segment state="translated">
<source>settings.ips</source>
<target>Informationsquellen</target>
</segment>
</unit>
<unit id="GuUZqpX" name="settings.misc">
<segment state="translated">
<source>settings.misc</source>
<target>Verschiedenes</target>
</segment>
</unit>
<unit id="mNLyYXa" name="settings.system.localization.language_menu_entries">
<segment state="translated">
<source>settings.system.localization.language_menu_entries</source>
<target>Einträge des Sprachenmenüs</target>
</segment>
</unit>
<unit id="Ej2znKK" name="settings.system.localization.language_menu_entries.description">
<segment state="translated">
<source>settings.system.localization.language_menu_entries.description</source>
<target>Die Sprachen, die im Sprachen Dropdown-Menü angezeigt werden sollen. Die Reihenfolge kann via Drag&amp;Drop geändert werden. Lassen Sie das Feld leer, um alle verfügbaren Sprachen anzuzeigen.</target>
</segment>
</unit>
<unit id="xIZ_mEX" name="project.builds.no_bom_entries">
<segment state="translated">
<source>project.builds.no_bom_entries</source>
<target>Das Projekt hat keine BOM Einträge</target>
</segment>
</unit>
<unit id="pCKgjIr" name="settings.behavior.sidebar.data_structure_nodes_table_include_children">
<segment state="translated">
<source>settings.behavior.sidebar.data_structure_nodes_table_include_children</source>
<target>Tabellen sollen Kindelemente standardmäßig inkludieren</target>
</segment>
</unit>
<unit id="KJQHfwV" name="settings.behavior.sidebar.data_structure_nodes_table_include_children.help">
<segment state="translated">
<source>settings.behavior.sidebar.data_structure_nodes_table_include_children.help</source>
<target>Wenn ausgewählt, werden für Bauteiletabellen von Kategorien, Footprints, etc. alle Bauteile der Kindkategorie inkludiert. Wenn diese Option nicht ausgewählt ist, werden in den Bauteiletabellen nur die Bauteile angezeigt, die strikt zu der angeklickten Kategorie gehören (exklusive Kindelementen).</target>
</segment>
</unit>
<unit id="Gdlnmav" name="info_providers.search.error.oauth_reconnect">
<segment state="translated">
<source>info_providers.search.error.oauth_reconnect</source>
<target>Folgende Informationsquelle benötigt eine OAuth Neu-Verbindung: %provider%
Dies ist auf der Informationsquellen Übersichtsseite möglich.</target>
</segment>
</unit>
</file>
</xliff>

View file

@ -242,7 +242,7 @@
</notes>
<segment state="final">
<source>part.info.timetravel_hint</source>
<target><![CDATA[This is how the part appeared before %timestamp%. <i>Please note that this feature is experimental, so the info may not be correct.</i>]]></target>
<target>This is how the part appeared before %timestamp%. &lt;i&gt;Please note that this feature is experimental, so the info may not be correct.&lt;/i&gt;</target>
</segment>
</unit>
<unit id="3exvSpl" name="standard.label">
@ -731,10 +731,10 @@
</notes>
<segment state="translated">
<source>user.edit.tfa.disable_tfa_message</source>
<target><![CDATA[This will disable <b>all active two-factor authentication methods of the user</b> and delete the <b>backup codes</b>!
<br>
The user will have to set up all two-factor authentication methods again and print new backup codes! <br><br>
<b>Only do this if you are absolutely sure about the identity of the user (seeking help), otherwise the account could be compromised by an attacker!</b>]]></target>
<target>This will disable &lt;b&gt;all active two-factor authentication methods of the user&lt;/b&gt; and delete the &lt;b&gt;backup codes&lt;/b&gt;!
&lt;br&gt;
The user will have to set up all two-factor authentication methods again and print new backup codes! &lt;br&gt;&lt;br&gt;
&lt;b&gt;Only do this if you are absolutely sure about the identity of the user (seeking help), otherwise the account could be compromised by an attacker!&lt;/b&gt;</target>
</segment>
</unit>
<unit id="APsHYu0" name="user.edit.tfa.disable_tfa.btn">
@ -885,9 +885,9 @@ The user will have to set up all two-factor authentication methods again and pri
</notes>
<segment state="translated">
<source>entity.delete.message</source>
<target><![CDATA[This can not be undone!
<br>
Sub elements will be moved upwards.]]></target>
<target>This can not be undone!
&lt;br&gt;
Sub elements will be moved upwards.</target>
</segment>
</unit>
<unit id="2tKAqHw" name="entity.delete">
@ -1441,7 +1441,7 @@ Sub elements will be moved upwards.]]></target>
</notes>
<segment state="final">
<source>homepage.github.text</source>
<target><![CDATA[Source, downloads, bug reports, to-do-list etc. can be found on <a href="%href%" class="link-external" target="_blank">GitHub project page</a>]]></target>
<target>Source, downloads, bug reports, to-do-list etc. can be found on &lt;a href="%href%" class="link-external" target="_blank"&gt;GitHub project page&lt;/a&gt;</target>
</segment>
</unit>
<unit id="D5OKsgU" name="homepage.help.caption">
@ -1463,7 +1463,7 @@ Sub elements will be moved upwards.]]></target>
</notes>
<segment state="translated">
<source>homepage.help.text</source>
<target><![CDATA[Help and tips can be found in Wiki the <a href="%href%" class="link-external" target="_blank">GitHub page</a>]]></target>
<target>Help and tips can be found in Wiki the &lt;a href="%href%" class="link-external" target="_blank"&gt;GitHub page&lt;/a&gt;</target>
</segment>
</unit>
<unit id="dnirx4v" name="homepage.forum.caption">
@ -1705,7 +1705,7 @@ Sub elements will be moved upwards.]]></target>
</notes>
<segment state="translated">
<source>email.pw_reset.fallback</source>
<target><![CDATA[If this does not work for you, go to <a href="%url%">%url%</a> and enter the following info]]></target>
<target>If this does not work for you, go to &lt;a href="%url%"&gt;%url%&lt;/a&gt; and enter the following info</target>
</segment>
</unit>
<unit id="DduL9Hu" name="email.pw_reset.username">
@ -1735,7 +1735,7 @@ Sub elements will be moved upwards.]]></target>
</notes>
<segment state="translated">
<source>email.pw_reset.valid_unit %date%</source>
<target><![CDATA[The reset token will be valid until <i>%date%</i>.]]></target>
<target>The reset token will be valid until &lt;i&gt;%date%&lt;/i&gt;.</target>
</segment>
</unit>
<unit id="8sBnjRy" name="orderdetail.delete">
@ -3578,8 +3578,8 @@ Sub elements will be moved upwards.]]></target>
</notes>
<segment state="translated">
<source>tfa_google.disable.confirm_message</source>
<target><![CDATA[If you disable the Authenticator App, all backup codes will be deleted, so you may need to reprint them.<br>
Also note that without two-factor authentication, your account is no longer as well protected against attackers!]]></target>
<target>If you disable the Authenticator App, all backup codes will be deleted, so you may need to reprint them.&lt;br&gt;
Also note that without two-factor authentication, your account is no longer as well protected against attackers!</target>
</segment>
</unit>
<unit id="yu9MSt5" name="tfa_google.disabled_message">
@ -3599,7 +3599,7 @@ Also note that without two-factor authentication, your account is no longer as w
</notes>
<segment state="translated">
<source>tfa_google.step.download</source>
<target><![CDATA[Download an authenticator app (e.g. <a class="link-external" target="_blank" href="https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2">Google Authenticator</a> oder <a class="link-external" target="_blank" href="https://play.google.com/store/apps/details?id=org.fedorahosted.freeotp">FreeOTP Authenticator</a>)]]></target>
<target>Download an authenticator app (e.g. &lt;a class="link-external" target="_blank" href="https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2"&gt;Google Authenticator&lt;/a&gt; oder &lt;a class="link-external" target="_blank" href="https://play.google.com/store/apps/details?id=org.fedorahosted.freeotp"&gt;FreeOTP Authenticator&lt;/a&gt;)</target>
</segment>
</unit>
<unit id="eriwJoR" name="tfa_google.step.scan">
@ -3841,8 +3841,8 @@ Also note that without two-factor authentication, your account is no longer as w
</notes>
<segment state="translated">
<source>tfa_trustedDevices.explanation</source>
<target><![CDATA[When checking the second factor, the current computer can be marked as trustworthy, so no more two-factor checks on this computer are needed.
If you have done this incorrectly or if a computer is no longer trusted, you can reset the status of <i>all </i>computers here.]]></target>
<target>When checking the second factor, the current computer can be marked as trustworthy, so no more two-factor checks on this computer are needed.
If you have done this incorrectly or if a computer is no longer trusted, you can reset the status of &lt;i&gt;all &lt;/i&gt;computers here.</target>
</segment>
</unit>
<unit id="FZINq8z" name="tfa_trustedDevices.invalidate.confirm_title">
@ -5313,7 +5313,7 @@ If you have done this incorrectly or if a computer is no longer trusted, you can
</notes>
<segment state="translated">
<source>label_options.lines_mode.help</source>
<target><![CDATA[If you select Twig here, the content field is interpreted as Twig template. See <a href="https://twig.symfony.com/doc/3.x/templates.html">Twig documentation</a> and <a href="https://docs.part-db.de/usage/labels.html#twig-mode">Wiki</a> for more information.]]></target>
<target>If you select Twig here, the content field is interpreted as Twig template. See &lt;a href="https://twig.symfony.com/doc/3.x/templates.html"&gt;Twig documentation&lt;/a&gt; and &lt;a href="https://docs.part-db.de/usage/labels.html#twig-mode"&gt;Wiki&lt;/a&gt; for more information.</target>
</segment>
</unit>
<unit id="isvxbiX" name="label_options.page_size.label">
@ -7157,15 +7157,15 @@ Exampletown</target>
</notes>
<segment state="translated">
<source>mass_creation.lines.placeholder</source>
<target><![CDATA[Element 1
<target>Element 1
Element 1.1
Element 1.1.1
Element 1.2
Element 2
Element 3
Element 1 -> Element 1.1
Element 1 -> Element 1.2]]></target>
Element 1 -&gt; Element 1.1
Element 1 -&gt; Element 1.2</target>
</segment>
</unit>
<unit id="TWSqPFi" name="entity.mass_creation.btn">
@ -9444,25 +9444,25 @@ Element 1 -> Element 1.2]]></target>
<unit id="r4vDLAt" name="filter.parameter_value_constraint.operator.&lt;">
<segment state="translated">
<source>filter.parameter_value_constraint.operator.&lt;</source>
<target><![CDATA[Typ. Value <]]></target>
<target>Typ. Value &lt;</target>
</segment>
</unit>
<unit id="X9SA3UP" name="filter.parameter_value_constraint.operator.&gt;">
<segment state="translated">
<source>filter.parameter_value_constraint.operator.&gt;</source>
<target><![CDATA[Typ. Value >]]></target>
<target>Typ. Value &gt;</target>
</segment>
</unit>
<unit id="BQGaoQS" name="filter.parameter_value_constraint.operator.&lt;=">
<segment state="translated">
<source>filter.parameter_value_constraint.operator.&lt;=</source>
<target><![CDATA[Typ. Value <=]]></target>
<target>Typ. Value &lt;=</target>
</segment>
</unit>
<unit id="2ha3P6g" name="filter.parameter_value_constraint.operator.&gt;=">
<segment state="translated">
<source>filter.parameter_value_constraint.operator.&gt;=</source>
<target><![CDATA[Typ. Value >=]]></target>
<target>Typ. Value &gt;=</target>
</segment>
</unit>
<unit id="4DaBace" name="filter.parameter_value_constraint.operator.BETWEEN">
@ -9570,7 +9570,7 @@ Element 1 -> Element 1.2]]></target>
<unit id="4tHhDtU" name="parts_list.search.searching_for">
<segment state="translated">
<source>parts_list.search.searching_for</source>
<target><![CDATA[Searching parts with keyword <b>%keyword%</b>]]></target>
<target>Searching parts with keyword &lt;b&gt;%keyword%&lt;/b&gt;</target>
</segment>
</unit>
<unit id="4vomKLa" name="parts_list.search_options.caption">
@ -10230,13 +10230,13 @@ Element 1 -> Element 1.2]]></target>
<unit id="NdZ1t7a" name="project.builds.number_of_builds_possible">
<segment state="translated">
<source>project.builds.number_of_builds_possible</source>
<target><![CDATA[You have enough stocked to build <b>%max_builds%</b> builds of this project.]]></target>
<target>You have enough stocked to build &lt;b&gt;%max_builds%&lt;/b&gt; builds of this project.</target>
</segment>
</unit>
<unit id="iuSpPbg" name="project.builds.check_project_status">
<segment state="translated">
<source>project.builds.check_project_status</source>
<target><![CDATA[The current project status is <b>"%project_status%"</b>. You should check if you really want to build the project with this status!]]></target>
<target>The current project status is &lt;b&gt;"%project_status%"&lt;/b&gt;. You should check if you really want to build the project with this status!</target>
</segment>
</unit>
<unit id="Y7vSSxi" name="project.builds.following_bom_entries_miss_instock_n">
@ -10338,7 +10338,7 @@ Element 1 -> Element 1.2]]></target>
<unit id="GzqIwHH" name="entity.select.add_hint">
<segment state="translated">
<source>entity.select.add_hint</source>
<target><![CDATA[Use -> to create nested structures, e.g. "Node 1->Node 1.1"]]></target>
<target>Use -&gt; to create nested structures, e.g. "Node 1-&gt;Node 1.1"</target>
</segment>
</unit>
<unit id="S4CxO.T" name="entity.select.group.new_not_added_to_DB">
@ -10362,13 +10362,13 @@ Element 1 -> Element 1.2]]></target>
<unit id="XLnXtsR" name="homepage.first_steps.introduction">
<segment state="translated">
<source>homepage.first_steps.introduction</source>
<target><![CDATA[Your database is still empty. You might want to read the <a href="%url%">documentation</a> or start to creating the following data structures:]]></target>
<target>Your database is still empty. You might want to read the &lt;a href="%url%"&gt;documentation&lt;/a&gt; or start to creating the following data structures:</target>
</segment>
</unit>
<unit id="Q79MOIk" name="homepage.first_steps.create_part">
<segment state="translated">
<source>homepage.first_steps.create_part</source>
<target><![CDATA[Or you can directly <a href="%url%">create a new part</a>.]]></target>
<target>Or you can directly &lt;a href="%url%"&gt;create a new part&lt;/a&gt;.</target>
</segment>
</unit>
<unit id="vplYq4f" name="homepage.first_steps.hide_hint">
@ -10380,7 +10380,7 @@ Element 1 -> Element 1.2]]></target>
<unit id="MJoZl4f" name="homepage.forum.text">
<segment state="translated">
<source>homepage.forum.text</source>
<target><![CDATA[For questions about Part-DB use the <a href="%href%" class="link-external" target="_blank">discussion forum</a>]]></target>
<target>For questions about Part-DB use the &lt;a href="%href%" class="link-external" target="_blank"&gt;discussion forum&lt;/a&gt;</target>
</segment>
</unit>
<unit id="YsukbnK" name="log.element_edited.changed_fields.category">
@ -11040,7 +11040,7 @@ Element 1 -> Element 1.2]]></target>
<unit id="p_IxB9K" name="parts.import.help_documentation">
<segment state="translated">
<source>parts.import.help_documentation</source>
<target><![CDATA[See the <a href="%link%">documentation</a> for more information on the file format.]]></target>
<target>See the &lt;a href="%link%"&gt;documentation&lt;/a&gt; for more information on the file format.</target>
</segment>
</unit>
<unit id="awbvhVq" name="parts.import.help">
@ -11220,7 +11220,7 @@ Element 1 -> Element 1.2]]></target>
<unit id="o5u.Nnz" name="part.filter.lessThanDesired">
<segment state="translated">
<source>part.filter.lessThanDesired</source>
<target><![CDATA[In stock less than desired (total amount < min. amount)]]></target>
<target>In stock less than desired (total amount &lt; min. amount)</target>
</segment>
</unit>
<unit id="YN9eLcZ" name="part.filter.lotOwner">
@ -12032,13 +12032,13 @@ Please note, that you can not impersonate a disabled user. If you try you will g
<unit id="i68lU5x" name="part.merge.confirm.title">
<segment state="translated">
<source>part.merge.confirm.title</source>
<target><![CDATA[Do you really want to merge <b>%other%</b> into <b>%target%</b>?]]></target>
<target>Do you really want to merge &lt;b&gt;%other%&lt;/b&gt; into &lt;b&gt;%target%&lt;/b&gt;?</target>
</segment>
</unit>
<unit id="k0anzYV" name="part.merge.confirm.message">
<segment state="translated">
<source>part.merge.confirm.message</source>
<target><![CDATA[<b>%other%</b> will be deleted, and the part will be saved with the shown information.]]></target>
<target>&lt;b&gt;%other%&lt;/b&gt; will be deleted, and the part will be saved with the shown information.</target>
</segment>
</unit>
<unit id="mmW5Yl1" name="part.info.merge_modal.title">
@ -12392,7 +12392,7 @@ Please note, that you can not impersonate a disabled user. If you try you will g
<unit id="p7LGAIX" name="settings.ips.element14.apiKey.help">
<segment state="translated">
<source>settings.ips.element14.apiKey.help</source>
<target><![CDATA[You can register for an API key on <a href="https://partner.element14.com/">https://partner.element14.com/</a>.]]></target>
<target>You can register for an API key on &lt;a href="https://partner.element14.com/"&gt;https://partner.element14.com/&lt;/a&gt;.</target>
</segment>
</unit>
<unit id="ZdUHpZc" name="settings.ips.element14.storeId">
@ -12404,7 +12404,7 @@ Please note, that you can not impersonate a disabled user. If you try you will g
<unit id="XXGUxF6" name="settings.ips.element14.storeId.help">
<segment state="translated">
<source>settings.ips.element14.storeId.help</source>
<target><![CDATA[The store domain to retrieve the data from. This decides the language and currency of results. See <a href="https://partner.element14.com/docs/Product_Search_API_REST__Description">here</a> for a list of valid domains.]]></target>
<target>The store domain to retrieve the data from. This decides the language and currency of results. See &lt;a href="https://partner.element14.com/docs/Product_Search_API_REST__Description"&gt;here&lt;/a&gt; for a list of valid domains.</target>
</segment>
</unit>
<unit id="WKWZIm2" name="settings.ips.tme">
@ -12422,7 +12422,7 @@ Please note, that you can not impersonate a disabled user. If you try you will g
<unit id="_pYLrPT" name="settings.ips.tme.token.help">
<segment state="translated">
<source>settings.ips.tme.token.help</source>
<target><![CDATA[You can get an API token and secret on <a href="https://developers.tme.eu/en/">https://developers.tme.eu/en/</a>.]]></target>
<target>You can get an API token and secret on &lt;a href="https://developers.tme.eu/en/"&gt;https://developers.tme.eu/en/&lt;/a&gt;.</target>
</segment>
</unit>
<unit id="yswx4bq" name="settings.ips.tme.secret">
@ -12470,7 +12470,7 @@ Please note, that you can not impersonate a disabled user. If you try you will g
<unit id="gu.JlpT" name="settings.ips.mouser.apiKey.help">
<segment state="translated">
<source>settings.ips.mouser.apiKey.help</source>
<target><![CDATA[You can register for an API key on <a href="https://eu.mouser.com/api-hub/">https://eu.mouser.com/api-hub/</a>.]]></target>
<target>You can register for an API key on &lt;a href="https://eu.mouser.com/api-hub/"&gt;https://eu.mouser.com/api-hub/&lt;/a&gt;.</target>
</segment>
</unit>
<unit id="Q66CNjw" name="settings.ips.mouser.searchLimit">
@ -12548,7 +12548,7 @@ Please note, that you can not impersonate a disabled user. If you try you will g
<unit id="kKv0J3." name="settings.system.attachments">
<segment state="translated">
<source>settings.system.attachments</source>
<target><![CDATA[Attachments & Files]]></target>
<target>Attachments &amp; Files</target>
</segment>
</unit>
<unit id="dsRff8T" name="settings.system.attachments.maxFileSize">
@ -12572,7 +12572,7 @@ Please note, that you can not impersonate a disabled user. If you try you will g
<unit id="T.PBu5P" name="settings.system.attachments.allowDownloads.help">
<segment state="translated">
<source>settings.system.attachments.allowDownloads.help</source>
<target><![CDATA[With this option users can download external files into Part-DB by providing an URL. <b>Attention: This can be a security issue, as it might allow users to access intranet ressources via Part-DB!</b>]]></target>
<target>With this option users can download external files into Part-DB by providing an URL. &lt;b&gt;Attention: This can be a security issue, as it might allow users to access intranet ressources via Part-DB!&lt;/b&gt;</target>
</segment>
</unit>
<unit id=".OyihML" name="settings.system.attachments.downloadByDefault">
@ -12746,8 +12746,8 @@ Please note, that you can not impersonate a disabled user. If you try you will g
<unit id="0GRlEe5" name="settings.system.localization.base_currency_description">
<segment state="translated">
<source>settings.system.localization.base_currency_description</source>
<target><![CDATA[The currency that is used to store price information and exchange rates in. This currency is assumed, when no currency is set for a price information.
<b>Please note that the currencies are not converted, when changing this value. So changing the default currency after you already added price information, will result in wrong prices!</b>]]></target>
<target>The currency that is used to store price information and exchange rates in. This currency is assumed, when no currency is set for a price information.
&lt;b&gt;Please note that the currencies are not converted, when changing this value. So changing the default currency after you already added price information, will result in wrong prices!&lt;/b&gt;</target>
</segment>
</unit>
<unit id="cvpTUeY" name="settings.system.privacy">
@ -12777,7 +12777,7 @@ Please note, that you can not impersonate a disabled user. If you try you will g
<unit id="w07P3Dt" name="settings.misc.kicad_eda.category_depth.help">
<segment state="translated">
<source>settings.misc.kicad_eda.category_depth.help</source>
<target><![CDATA[This value determines the depth of the category tree, that is visible inside KiCad. 0 means that only the top level categories are visible. Set to a value > 0 to show more levels. Set to -1, to show all parts of Part-DB inside a sigle cnategory in KiCad.]]></target>
<target>This value determines the depth of the category tree, that is visible inside KiCad. 0 means that only the top level categories are visible. Set to a value &gt; 0 to show more levels. Set to -1, to show all parts of Part-DB inside a sigle cnategory in KiCad.</target>
</segment>
</unit>
<unit id="VwvmcWE" name="settings.behavior.sidebar">
@ -12795,7 +12795,7 @@ Please note, that you can not impersonate a disabled user. If you try you will g
<unit id="jc0JTvL" name="settings.behavior.sidebar.items.help">
<segment state="translated">
<source>settings.behavior.sidebar.items.help</source>
<target><![CDATA[The menus which appear at the sidebar by default. Order of items can be changed via drag & drop.]]></target>
<target>The menus which appear at the sidebar by default. Order of items can be changed via drag &amp; drop.</target>
</segment>
</unit>
<unit id="gVSWDkE" name="settings.behavior.sidebar.rootNodeEnabled">
@ -12843,7 +12843,7 @@ Please note, that you can not impersonate a disabled user. If you try you will g
<unit id="SUD8H3b" name="settings.behavior.table.parts_default_columns.help">
<segment state="translated">
<source>settings.behavior.table.parts_default_columns.help</source>
<target><![CDATA[The columns to show by default in part tables. Order of items can be changed via drag & drop.]]></target>
<target>The columns to show by default in part tables. Order of items can be changed via drag &amp; drop.</target>
</segment>
</unit>
<unit id="hazr_g5" name="settings.ips.oemsecrets">
@ -12897,7 +12897,7 @@ Please note, that you can not impersonate a disabled user. If you try you will g
<unit id="KLJYfJ0" name="settings.ips.oemsecrets.sortMode.M">
<segment state="translated">
<source>settings.ips.oemsecrets.sortMode.M</source>
<target><![CDATA[Completeness & Manufacturer name]]></target>
<target>Completeness &amp; Manufacturer name</target>
</segment>
</unit>
<unit id="8C9ijHM" name="entity.export.flash.error.no_entities">
@ -13509,7 +13509,7 @@ Please note, that you can not impersonate a disabled user. If you try you will g
<unit id="FsrRdkp" name="settings.behavior.homepage.items.help">
<segment state="translated">
<source>settings.behavior.homepage.items.help</source>
<target><![CDATA[The items to show at the homepage. Order can be changed via drag & drop.]]></target>
<target>The items to show at the homepage. Order can be changed via drag &amp; drop.</target>
</segment>
</unit>
<unit id="CYw3_pS" name="settings.system.customization.showVersionOnHomepage">
@ -14244,5 +14244,37 @@ Please note, that you can not impersonate a disabled user. If you try you will g
<target>If checked, the part tables for categories, footprints, etc. should include all parts of child categories. If not checked, only parts that strictly belong to the clicked node are shown.</target>
</segment>
</unit>
<unit id="Gdlnmav" name="info_providers.search.error.oauth_reconnect">
<segment>
<source>info_providers.search.error.oauth_reconnect</source>
<target>You need to reconnect OAuth for following providers: %provider%
You can do this in the provider info list.</target>
</segment>
</unit>
<unit id="xIZ_mEX" name="project.builds.no_bom_entries">
<segment state="translated">
<source>project.builds.no_bom_entries</source>
<target>Project has no BOM entries</target>
</segment>
</unit>
<unit id="pCKgjIr" name="settings.behavior.sidebar.data_structure_nodes_table_include_children">
<segment state="translated">
<source>settings.behavior.sidebar.data_structure_nodes_table_include_children</source>
<target>Tables should include children nodes by default</target>
</segment>
</unit>
<unit id="KJQHfwV" name="settings.behavior.sidebar.data_structure_nodes_table_include_children.help">
<segment state="translated">
<source>settings.behavior.sidebar.data_structure_nodes_table_include_children.help</source>
<target>If checked, the part tables for categories, footprints, etc. should include all parts of child categories. If not checked, only parts that strictly belong to the clicked node are shown.</target>
</segment>
</unit>
<unit id="Gdlnmav" name="info_providers.search.error.oauth_reconnect">
<segment state="translated">
<source>info_providers.search.error.oauth_reconnect</source>
<target>You need to reconnect OAuth for following providers: %provider%
You can do this in the provider info list.</target>
</segment>
</unit>
</file>
</xliff>