Compare commits

..

18 Commits

Author SHA1 Message Date
Jan Böhmer
753ecee849 Merge remote-tracking branch 'origin/master' 2026-03-15 22:09:22 +01:00
Jan Böhmer
8f6ed74d93 Bumped version to 2.9.1 2026-03-15 22:09:10 +01:00
Jan Böhmer
17f11c02f3 New Crowdin updates (#1301)
* New translations validators.en.xlf (Chinese Simplified)

* New translations messages.en.xlf (English)

* New translations messages.en.xlf (German)
2026-03-15 22:08:38 +01:00
Jan Böhmer
a070ebb2ce Fixed 500 error with displaying part prices, when a user has a currency preference different of base currency, and there is no conversion rate known for it
This fixes issue #1317
2026-03-15 22:02:10 +01:00
Jan Böhmer
44bb132de1 Merge remote-tracking branch 'origin/master' 2026-03-15 21:47:21 +01:00
Jan Böhmer
95f3fc66c2 Do not throw an 500 error, if mapping is not possible
This fixes issue #1298
2026-03-15 21:47:15 +01:00
Jan Böhmer
74e5102943 Automatically detect the delimiter of generic BOM imports
The detectFields does this anyway, so use that guessed value further on
2026-03-15 21:35:38 +01:00
swdee
60c5e24c94 Bug fix: Remove fallback from LCSC barcode part resolver (#1302) 2026-03-15 18:57:54 +01:00
Jan Böhmer
de371877b9 Make GenericWebProvider more forgiving with URLs and accept the "fixed" strings traefik provides as security measure
This fixes issue #1296
2026-03-15 18:55:16 +01:00
Jan Böhmer
baeef1228a updated dependencies 2026-03-15 15:06:24 +01:00
Jan Böhmer
45da6dacff Update KiCad symbols and footprints lists (#1303)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-11 11:28:23 +01:00
Moritz Wörmann
c4d8192e76 add data-tube=false to SAML auth button (#1308) 2026-03-11 11:28:09 +01:00
dependabot[bot]
dca0cb8a16 Bump docker/setup-buildx-action from 3 to 4 (#1309)
Bumps [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) from 3 to 4.
- [Release notes](https://github.com/docker/setup-buildx-action/releases)
- [Commits](https://github.com/docker/setup-buildx-action/compare/v3...v4)

---
updated-dependencies:
- dependency-name: docker/setup-buildx-action
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-11 11:15:36 +01:00
dependabot[bot]
3abc0d8b38 Bump docker/build-push-action from 6 to 7 (#1311)
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 6 to 7.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/v6...v7)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-11 11:15:20 +01:00
dependabot[bot]
9ea3ead246 Bump docker/login-action from 3 to 4 (#1310)
Bumps [docker/login-action](https://github.com/docker/login-action) from 3 to 4.
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](https://github.com/docker/login-action/compare/v3...v4)

---
updated-dependencies:
- dependency-name: docker/login-action
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-11 11:12:27 +01:00
dependabot[bot]
1de440d71e Bump docker/metadata-action from 5 to 6 (#1312)
Bumps [docker/metadata-action](https://github.com/docker/metadata-action) from 5 to 6.
- [Release notes](https://github.com/docker/metadata-action/releases)
- [Commits](https://github.com/docker/metadata-action/compare/v5...v6)

---
updated-dependencies:
- dependency-name: docker/metadata-action
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-11 11:08:29 +01:00
dependabot[bot]
5243f90dd8 Bump web-auth/webauthn-symfony-bundle from 5.2.3 to 5.2.4 (#1313)
Bumps [web-auth/webauthn-symfony-bundle](https://github.com/web-auth/webauthn-symfony-bundle) from 5.2.3 to 5.2.4.
- [Commits](https://github.com/web-auth/webauthn-symfony-bundle/compare/5.2.3...5.2.4)

---
updated-dependencies:
- dependency-name: web-auth/webauthn-symfony-bundle
  dependency-version: 5.2.4
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-11 11:07:56 +01:00
Jan Böhmer
343c078b7d fixed intendation of force visibility checkbox in category admin 2026-03-07 23:58:32 +01:00
20 changed files with 1158 additions and 996 deletions

View File

@@ -36,7 +36,7 @@ jobs:
-
name: Docker meta
id: docker_meta
uses: docker/metadata-action@v5
uses: docker/metadata-action@v6
with:
# list of Docker images to use as base name for tags
images: |
@@ -66,11 +66,11 @@ jobs:
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
uses: docker/setup-buildx-action@v4
-
name: Login to DockerHub
if: github.event_name != 'pull_request'
uses: docker/login-action@v3
uses: docker/login-action@v4
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
@@ -78,7 +78,7 @@ jobs:
-
name: Build and push by digest
id: build
uses: docker/build-push-action@v6
uses: docker/build-push-action@v7
with:
context: .
platforms: ${{ matrix.platform }}
@@ -121,12 +121,12 @@ jobs:
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
uses: docker/setup-buildx-action@v4
-
name: Docker meta
id: docker_meta
uses: docker/metadata-action@v5
uses: docker/metadata-action@v6
with:
images: |
jbtronics/part-db1
@@ -142,7 +142,7 @@ jobs:
-
name: Login to DockerHub
uses: docker/login-action@v3
uses: docker/login-action@v4
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

View File

@@ -36,7 +36,7 @@ jobs:
-
name: Docker meta
id: docker_meta
uses: docker/metadata-action@v5
uses: docker/metadata-action@v6
with:
# list of Docker images to use as base name for tags
images: |
@@ -66,11 +66,11 @@ jobs:
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
uses: docker/setup-buildx-action@v4
-
name: Login to DockerHub
if: github.event_name != 'pull_request'
uses: docker/login-action@v3
uses: docker/login-action@v4
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
@@ -78,7 +78,7 @@ jobs:
-
name: Build and push by digest
id: build
uses: docker/build-push-action@v6
uses: docker/build-push-action@v7
with:
context: .
file: Dockerfile-frankenphp
@@ -122,12 +122,12 @@ jobs:
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
uses: docker/setup-buildx-action@v4
-
name: Docker meta
id: docker_meta
uses: docker/metadata-action@v5
uses: docker/metadata-action@v6
with:
images: |
partdborg/part-db
@@ -143,7 +143,7 @@ jobs:
-
name: Login to DockerHub
uses: docker/login-action@v3
uses: docker/login-action@v4
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

View File

@@ -1 +1 @@
2.9.0
2.9.1

497
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -2390,6 +2390,9 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param;
* serialize_payload_fields?: mixed, // Set to null to serialize all payload fields when a validation error is thrown, or set the fields you want to include explicitly. // Default: []
* query_parameter_validation?: bool|Param, // Deprecated: Will be removed in API Platform 5.0. // Default: true
* },
* jsonapi?: array{
* use_iri_as_id?: bool|Param, // Set to false to use entity identifiers instead of IRIs as the "id" field in JSON:API responses. // Default: true
* },
* eager_loading?: bool|array{
* enabled?: bool|Param, // Default: true
* fetch_partial?: bool|Param, // Fetch only partial data according to serialization groups. If enabled, Doctrine ORM entities will not work as expected if any of the other fields are used. // Default: false
@@ -2401,11 +2404,12 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param;
* enable_json_streamer?: bool|Param, // Enable json streamer. // Default: false
* enable_swagger_ui?: bool|Param, // Enable Swagger UI // Default: true
* enable_re_doc?: bool|Param, // Enable ReDoc // Default: true
* enable_scalar?: bool|Param, // Enable Scalar API Reference // Default: true
* enable_entrypoint?: bool|Param, // Enable the entrypoint // Default: true
* enable_docs?: bool|Param, // Enable the docs // Default: true
* enable_profiler?: bool|Param, // Enable the data collector and the WebProfilerBundle integration. // Default: true
* enable_phpdoc_parser?: bool|Param, // Enable resource metadata collector using PHPStan PhpDocParser. // Default: true
* enable_link_security?: bool|Param, // Enable security for Links (sub resources) // Default: false
* enable_link_security?: bool|Param, // Deprecated: This option is always enabled and will be removed in API Platform 5.0. // Enable security for Links (sub resources). // Default: true
* collection?: array{
* exists_parameter_name?: scalar|Param|null, // The name of the query parameter to filter on nullable field values. // Default: "exists"
* order?: scalar|Param|null, // The default order of results. // Default: "ASC"
@@ -2505,6 +2509,9 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param;
* elasticsearch?: bool|array{
* enabled?: bool|Param, // Default: false
* hosts?: list<scalar|Param|null>,
* ssl_ca_bundle?: scalar|Param|null, // Path to the SSL CA bundle file for Elasticsearch SSL verification. // Default: null
* ssl_verification?: bool|Param, // Enable or disable SSL verification for Elasticsearch connections. // Default: true
* client?: "elasticsearch"|"opensearch"|Param, // The search engine client to use: "elasticsearch" or "opensearch". // Default: "elasticsearch"
* },
* openapi?: array{
* contact?: array{
@@ -2523,12 +2530,18 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param;
* identifier?: scalar|Param|null, // An SPDX license expression for the API. The identifier field is mutually exclusive of the url field. // Default: null
* },
* swagger_ui_extra_configuration?: mixed, // To pass extra configuration to Swagger UI, like docExpansion or filter. // Default: []
* scalar_extra_configuration?: mixed, // To pass extra configuration to Scalar API Reference, like theme or darkMode. // Default: []
* overrideResponses?: bool|Param, // Whether API Platform adds automatic responses to the OpenAPI documentation. // Default: true
* error_resource_class?: scalar|Param|null, // The class used to represent errors in the OpenAPI documentation. // Default: null
* validation_error_resource_class?: scalar|Param|null, // The class used to represent validation errors in the OpenAPI documentation. // Default: null
* },
* maker?: bool|array{
* enabled?: bool|Param, // Default: true
* namespace_prefix?: scalar|Param|null, // Add a prefix to all maker generated classes. e.g set it to "Api" to set the maker namespace to "App\Api\" (if the maker.root_namespace config is App). e.g. App\Api\State\MyStateProcessor // Default: ""
* },
* mcp?: bool|array{
* enabled?: bool|Param, // Default: true
* format?: scalar|Param|null, // The serialization format used for MCP tool input/output. Must be a format registered in api_platform.formats (e.g. "jsonld", "json", "jsonapi"). // Default: "jsonld"
* },
* exception_to_status?: array<string, int|Param>,
* formats?: array<string, array{ // Default: {"jsonld":{"mime_types":["application/ld+json"]}}
@@ -2613,12 +2626,37 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param;
* rules?: mixed,
* policy?: mixed,
* middleware?: mixed,
* parameters?: mixed,
* parameters?: array<string, array{ // Default: []
* key?: mixed,
* schema?: mixed,
* open_api?: mixed,
* provider?: mixed,
* filter?: mixed,
* property?: mixed,
* description?: mixed,
* properties?: mixed,
* required?: mixed,
* priority?: mixed,
* hydra?: mixed,
* constraints?: mixed,
* security?: mixed,
* security_message?: mixed,
* extra_properties?: mixed,
* filter_context?: mixed,
* native_type?: mixed,
* cast_to_array?: mixed,
* cast_to_native_type?: mixed,
* cast_fn?: mixed,
* default?: mixed,
* filter_class?: mixed,
* ...<mixed>
* }>,
* strict_query_parameter_validation?: mixed,
* hide_hydra_operation?: mixed,
* json_stream?: mixed,
* extra_properties?: mixed,
* map?: mixed,
* mcp?: mixed,
* route_name?: mixed,
* errors?: mixed,
* read?: mixed,
@@ -2626,6 +2664,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param;
* validate?: mixed,
* write?: mixed,
* serialize?: mixed,
* content_negotiation?: mixed,
* priority?: mixed,
* name?: mixed,
* allow_create?: mixed,

View File

@@ -1,4 +1,4 @@
# Generated on Tue Mar 3 14:26:21 UTC 2026
# Generated on Mon Mar 9 04:23:25 UTC 2026
# This file contains all footprints available in the offical KiCAD library
Audio_Module:Reverb_BTDR-1H
Audio_Module:Reverb_BTDR-1V

View File

@@ -1,4 +1,4 @@
# Generated on Tue Mar 3 14:27:05 UTC 2026
# Generated on Mon Mar 9 04:24:12 UTC 2026
# This file contains all symbols available in the offical KiCAD library
4xxx:14528
4xxx:14529
@@ -22324,6 +22324,7 @@ Transistor_FET:PSMN5R2-60YL
Transistor_FET:QM6006D
Transistor_FET:QM6015D
Transistor_FET:Q_Dual_NMOS_G1S2G2D2S1D1
Transistor_FET:Q_Dual_NMOS_PMOS_G1S2G2D2S1D1
Transistor_FET:Q_Dual_NMOS_S1G1D2S2G2D1
Transistor_FET:Q_Dual_NMOS_S1G1S2G2D2D1
Transistor_FET:Q_Dual_NMOS_S1G1S2G2D2D2D1D1

View File

@@ -240,7 +240,8 @@ class ProjectController extends AbstractController
}
// Detect fields and get suggestions
$detected_fields = $BOMImporter->detectFields($file_content);
$detected_delimiter = $BOMImporter->detectDelimiter($file_content);
$detected_fields = $BOMImporter->detectFields($file_content, $detected_delimiter);
$suggested_mapping = $BOMImporter->getSuggestedFieldMapping($detected_fields);
// Create mapping of original field names to sanitized field names for template
@@ -257,7 +258,7 @@ class ProjectController extends AbstractController
$builder->add('delimiter', ChoiceType::class, [
'label' => 'project.bom_import.delimiter',
'required' => true,
'data' => ',',
'data' => $detected_delimiter,
'choices' => [
'project.bom_import.delimiter.comma' => ',',
'project.bom_import.delimiter.semicolon' => ';',

View File

@@ -721,26 +721,36 @@ class BOMImporter
return $mapped;
}
/**
* Try to detect the separator used in the CSV data by analyzing the first line and counting occurrences of common delimiters.
* @param string $data
* @return string
*/
public function detectDelimiter(string $data): string
{
$delimiters = [',', ';', "\t"];
$lines = explode("\n", $data, 2);
$header_line = $lines[0] ?? '';
$delimiter_counts = [];
foreach ($delimiters as $delim) {
$delimiter_counts[$delim] = substr_count($header_line, $delim);
}
// Choose the delimiter with the highest count, default to comma if all are zero
$max_count = max($delimiter_counts);
$delimiter = array_search($max_count, $delimiter_counts, true);
if ($max_count === 0 || $delimiter === false) {
$delimiter = ',';
}
return $delimiter;
}
/**
* Detect available fields in CSV data for field mapping UI
*/
public function detectFields(string $data, ?string $delimiter = null): array
{
if ($delimiter === null) {
// Detect delimiter by counting occurrences in the first row (header)
$delimiters = [',', ';', "\t"];
$lines = explode("\n", $data, 2);
$header_line = $lines[0] ?? '';
$delimiter_counts = [];
foreach ($delimiters as $delim) {
$delimiter_counts[$delim] = substr_count($header_line, $delim);
}
// Choose the delimiter with the highest count, default to comma if all are zero
$max_count = max($delimiter_counts);
$delimiter = array_search($max_count, $delimiter_counts, true);
if ($max_count === 0 || $delimiter === false) {
$delimiter = ',';
}
$delimiter = $this->detectDelimiter($data);
}
// Handle potential BOM (Byte Order Mark) at the beginning
$data = preg_replace('/^\xEF\xBB\xBF/', '', $data);

View File

@@ -315,7 +315,14 @@ class GenericWebProvider implements InfoProviderInterface
//Remove any leading slashes
$url = ltrim($url, '/');
$url = 'https://'.$url;
//If the URL starts with https:/ or http:/, add the missing slash
//Traefik removes the double slash as secruity measure, so we want to be forgiving and add it back if needed
//See https://github.com/Part-DB/Part-DB-server/issues/1296
if (preg_match('/^https?:\/[^\/]/', $url)) {
$url = preg_replace('/^(https?:)\/([^\/])/', '$1//$2', $url);
} else {
$url = 'https://'.$url;
}
}
//If this is not a valid URL with host, domain and path, throw an exception

View File

@@ -217,8 +217,8 @@ final readonly class BarcodeScanResultHandler
* Resolve LCSC barcode -> Part.
* Strategy:
* 1) Try providerReference.provider_id == pc (LCSC "Cxxxxxx") if you store it there
* 2) Fallback to manufacturer_product_number == pm (MPN)
* Returns first match (consistent with EIGP114 logic)
* 2) Fallback to search across supplier part number (SPN)
*/
private function resolvePartFromLCSC(LCSCBarcodeScanResult $barcodeScan): ?Part
{
@@ -231,13 +231,8 @@ final readonly class BarcodeScanResultHandler
}
}
// Fallback to MPN (pm)
$pm = $barcodeScan->mpn; // e.g. RC0402FR-071ML
if (!$pm) {
return null;
}
return $this->em->getRepository(Part::class)->getPartByMPN($pm);
// fallback to search by SPN
return $this->em->getRepository(Part::class)->getPartBySPN($pc);
}

View File

@@ -40,11 +40,9 @@
<div class="tab-pane" id="eda">
{{ form_row(form.eda_info.reference_prefix) }}
<div class="row">
<div class="{{ col_input }} {{ offset_label }}">
{{ form_row(form.eda_info.visibility) }}
</div>
</div>
{{ form_row(form.eda_info.visibility) }}
<div class="row mb-2">
<div class="{{ col_input }} {{ offset_label }}">

View File

@@ -47,17 +47,17 @@
</td>
<td>
{{ detail.price | format_money(detail.currency) }} / {{ detail.PriceRelatedQuantity | format_amount(part.partUnit) }}
{% set tmp = pricedetail_helper.convertMoneyToCurrency(detail.price, detail.currency) %}
{% set tmp = pricedetail_helper.convertMoneyToCurrency(detail.price, detail.currency, app.user.currency ?? null) %}
{% if detail.currency != (app.user.currency ?? null) and tmp is not null and tmp.GreaterThan(0) %}
<span class="text-muted">({{ pricedetail_helper.convertMoneyToCurrency(detail.price, detail.currency, app.user.currency ?? null) | format_money(app.user.currency ?? null) }})</span>
<span class="text-muted">({{ tmp | format_money(app.user.currency ?? null) }})</span>
{% endif %}
<small class="text-muted">{{- helper.vat_text(detail.includesVAT) -}}</small>
</td>
<td>
{{ detail.PricePerUnit | format_money(detail.currency) }}
{% set tmp = pricedetail_helper.convertMoneyToCurrency(detail.PricePerUnit, detail.currency) %}
{% set tmp = pricedetail_helper.convertMoneyToCurrency(detail.PricePerUnit, detail.currency, app.user.currency ?? null) %}
{% if detail.currency != (app.user.currency ?? null) and tmp is not null and tmp.GreaterThan(0) %}
<span class="text-muted">({{ pricedetail_helper.convertMoneyToCurrency(detail.PricePerUnit, detail.currency, app.user.currency ?? null) | format_money(app.user.currency ?? null) }})</span>
<span class="text-muted">({{ tmp | format_money(app.user.currency ?? null) }})</span>
{% endif %}
<small class="text-muted">{{- helper.vat_text(detail.includesVAT) -}}</small>
</td>

View File

@@ -48,51 +48,59 @@
<div class="table-responsive">
<table class="table table-striped">
<thead>
<tr>
<th>{% trans %}project.bom_import.field_mapping.csv_field{% endtrans %}</th>
<th>{% trans %}project.bom_import.field_mapping.maps_to{% endtrans %}</th>
<th>{% trans %}project.bom_import.field_mapping.suggestion{% endtrans %}</th>
<th>{% trans %}project.bom_import.field_mapping.priority{% endtrans %}</th>
</tr>
<tr>
<th>{% trans %}project.bom_import.field_mapping.csv_field{% endtrans %}</th>
<th>{% trans %}project.bom_import.field_mapping.maps_to{% endtrans %}</th>
<th>{% trans %}project.bom_import.field_mapping.suggestion{% endtrans %}</th>
<th>{% trans %}project.bom_import.field_mapping.priority{% endtrans %}</th>
</tr>
</thead>
<tbody>
{% for field in detected_fields %}
<tr>
<td>
<code>{{ field }}</code>
</td>
<td>
{% for field in detected_fields %}
<tr>
<td>
<code>{{ field }}</code>
</td>
<td>
{# TODO: This is more a workaround than a proper fix. Ideally the controller should be fixed in a way, that we get the correct fields here #}
{% if field_name_mapping[field] is defined %}
{% set field_name = field_name_mapping[field] %}
{{ form_widget(form['mapping_' ~ field_name_mapping[field]], {
'attr': {
'class': 'form-select field-mapping-select',
'data-field': field
}
}) }}
</td>
<td>
{% if suggested_mapping[field] is defined %}
<span class="badge bg-success">
{% else %}
<b class="text-danger">
{% trans %}project.bom_import.field_mapping.error.check_delimiter{% endtrans %}
</b>
{% endif %}
</td>
<td>
{% if suggested_mapping[field] is defined %}
<span class="badge bg-success">
<i class="fa-solid fa-magic fa-fw"></i>
{{ suggested_mapping[field] }}
</span>
{% else %}
<span class="text-muted">
{% else %}
<span class="text-muted">
<i class="fa-solid fa-question fa-fw"></i>
{% trans %}project.bom_import.field_mapping.no_suggestion{% endtrans %}
</span>
{% endif %}
</td>
<td>
<input type="number"
class="form-control form-control-sm priority-input"
min="1"
value="10"
style="width: 80px;"
data-field="{{ field }}"
title="{% trans %}project.bom_import.field_mapping.priority_help{% endtrans %}">
</td>
</tr>
{% endfor %}
{% endif %}
</td>
<td>
<input type="number"
class="form-control form-control-sm priority-input"
min="1"
value="10"
style="width: 80px;"
data-field="{{ field }}"
title="{% trans %}project.bom_import.field_mapping.priority_help{% endtrans %}">
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>

View File

@@ -23,7 +23,7 @@
{% if saml_enabled %}
<div class="{{ offset_label }} {{ col_input }}">
<a class="btn btn-secondary" href="{{ path('saml_login') }}"><i class="fa-solid fa-house-user"></i> {% trans %}login.sso_saml_login{% endtrans %}</a>
<a class="btn btn-secondary" href="{{ path('saml_login') }}" data-turbo="false"><i class="fa-solid fa-house-user"></i> {% trans %}login.sso_saml_login{% endtrans %}</a>
<p class="text-muted">{% trans %}login.local_login_hint{% endtrans %}</p>
</div>

View File

@@ -115,8 +115,8 @@ final class BarcodeScanResultHandlerTest extends KernelTestCase
public function testLCSCBarcodeResolvePartOrNullReturnsNullWhenNotFound(): void
{
$scan = new LCSCBarcodeScanResult(
fields: ['pc' => 'C0000000', 'pm' => ''],
rawInput: '{pc:C0000000,pm:}'
fields: ['pc' => 'C0000000', 'pm' => 'NON_EXISTENT_MPN_12345'],
rawInput: '{pc:C0000000,pm:NON_EXISTENT_MPN_12345}'
);
$this->assertNull($this->service->resolvePart($scan));

View File

@@ -12945,5 +12945,11 @@ Buerklin-API-Authentication-Server:
<target>[Part_lot] aus Barcode erstellt: Bitte überprüfen Sie, ob die Daten korrekt und gewünscht sind.</target>
</segment>
</unit>
<unit id="F8pQuL9" name="project.bom_import.field_mapping.error.check_delimiter">
<segment state="translated">
<source>project.bom_import.field_mapping.error.check_delimiter</source>
<target>Zuordnungsfehler: Bitte prüfen Sie, ob Sie das richtige Trennzeichen ausgewählt haben!</target>
</segment>
</unit>
</file>
</xliff>

View File

@@ -12947,5 +12947,11 @@ Buerklin-API Authentication server:
<target>[Part_lot] created from barcode: Please check if the data is correct and desired.</target>
</segment>
</unit>
<unit id="F8pQuL9" name="project.bom_import.field_mapping.error.check_delimiter">
<segment state="translated">
<source>project.bom_import.field_mapping.error.check_delimiter</source>
<target>Mapping error: Check if you have selected the right delimiter!</target>
</segment>
</unit>
</file>
</xliff>

View File

@@ -247,5 +247,11 @@
<target>该类型在此语言下已存在翻译定义!</target>
</segment>
</unit>
<unit id="zT_j_oQ" name="validator.invalid_gtin">
<segment state="translated">
<source>validator.invalid_gtin</source>
<target>无效的GTIN / EAN 码。</target>
</segment>
</unit>
</file>
</xliff>
</xliff>

1404
yarn.lock

File diff suppressed because it is too large Load Diff