* Perform a full translation of Simplified Chinese.
Based on the latest *.en.xlf file.
Translated automatically using DeepSinkV4 based on the source code,
then manually reviewed and corrected line by line.
* Normalized formatting
---------
Co-authored-by: Jan Böhmer <mail@jan-boehmer.de>
* Add Quick Apply and Apply All buttons to bulk info provider import
Adds the ability to apply provider search results to parts directly
from the bulk import step 2 page without navigating to individual
part edit forms. Includes per-result Quick Apply buttons and an
Apply All button for batch operations.
* Add navigation buttons and completion banner to bulk import step2
Adds Back to Jobs / Back to Parts buttons at the top of the page
and a success banner when the job is completed, so users aren't
stuck on the page after applying all parts.
* Highlight top search result and remove skip reason prompt
- Highlight the recommended/top priority result row with table-success class
- Add "Top" badge to the recommended Quick Apply button
- Use outline style for non-top Quick Apply buttons to differentiate
- Remove the annoying "reason for skipping" prompt popup
* Fix 500 error when field mapping has null field or no search results
- Skip field mappings with null/empty field values in convertFieldMappingsToDto
- Return empty DTO instead of throwing when no search results found
- Remove unnecessary try/catch workaround in researchPart
* Fix PHPStan error: remove redundant null check on BulkSearchResponseDTO
* Improve bulk import UI: split active/history jobs, fix text visibility, add match highlighting
- Split manage page into Active Jobs and History sections
- Fix source keyword text color (remove text-muted for better visibility)
- Add exact match indicators: green check badge when name or MPN matches
- Add translation keys for new UI elements
* Fix spinning icon, text visibility, auto-priority, and SPN match highlighting
- Replace spinning icon with static icon on Active Jobs header
- Match highlighting now checks source keyword against name, MPN, AND provider ID (SPN)
- Show green "Match" badge in source field column when any field matches 100%
- Auto-increment priority when adding new field mapping rows
- Fix text-muted visibility issues on table-success background
* Fix broken images and improve match highlighting consistency
- Hide broken external provider images with onerror fallback
- Make source keyword text green when any match is detected
- All matched fields (name, MPN, SPN, or any source keyword) show green text
* Fix TypeError in LCSCProvider when keyword is numeric string
PHP auto-casts numeric string array keys to int. When a search keyword
is a pure number (e.g., a part number like "12345"), the foreach loop
passes an int to processSearchResponse() which expects string. Cast
keyword to string explicitly.
* Clean up stale pending jobs and add job ID to display
- Auto-delete pending jobs with 0 results (from failed searches/500 errors)
- Show job ID (#N) in manage page and step2 to distinguish identical jobs
- Move timestamp to subtitle line on manage page for cleaner layout
* Fix tests to match updated bulk search behavior (no more RuntimeException)
The bulk search service now returns empty response DTOs instead of
throwing RuntimeException when no results are found. Updated tests
to use assertFalse(hasAnyResults()) instead of catching exceptions.
* Add comprehensive test coverage for bulk import controller
Covers Quick Apply, Apply All, delete, stop, mark completed/skipped/pending,
manage page active/history split, stale job cleanup, research endpoints,
and various error paths. Increases patch coverage significantly.
* Fix duplicate test method names in bulk import tests
* Fix last duplicate test method name (testQuickApplyWithNoSearchResults)
* Fixed translation key in translation messages
* Moved table rendering logic into macro
* fixed visual glitch with button success outline
* Use native httpfoundation method to convert json to an array
* Show a more user friendly error message, when
* Allow to automatically create new manufacturers within quick apply
---------
Co-authored-by: Jan Böhmer <mail@jan-boehmer.de>
* Add Docker update support via Watchtower integration
Add web-based Docker container updates using Watchtower HTTP API.
When configured with WATCHTOWER_API_URL and WATCHTOWER_API_TOKEN
environment variables, administrators can trigger container updates
from the Update Manager page.
Features:
- WatchtowerClient service for Watchtower HTTP API communication
- Docker update progress page with animated Docker whale logo
- Real-time step tracking: Trigger, Pull, Stop, Restart, Health Check, Verify
- CSP-compatible progress bar using CSS classes
- Translated UI strings via Stimulus values
- Health endpoint polling to detect container restart
- Watchtower setup documentation for Docker installations
- WatchtowerClient made nullable for non-Docker installations
- Unit tests for WatchtowerClient
* Fixed translation message IDs
* Switch Watchtower docs to maintained nicholas-fedor fork
The original containrrr/watchtower is no longer maintained (last release
Nov 2023). Point users to the drop-in compatible active fork and add an
info note explaining why. No code changes — the HTTP API is identical,
so WatchtowerClient works against either image.
* Fixed exception when github is not reachable
* Only show version string in health endpoint, when user has permissions
* Do not expose watchtower API port in example docker-compose file
* Show if updates, backup restore and backup download are allowed in update manager page
* Report 'not authorized' for version in health endpoint if user lacks permission
---------
Co-authored-by: Jan Böhmer <mail@jan-boehmer.de>
* New translations messages.en.xlf (Danish)
* New translations validators.en.xlf (Danish)
* New translations messages.en.xlf (German)
* New translations messages.en.xlf (English)
* New translations messages.en.xlf (French)
* New translations validators.en.xlf (French)
* New translations messages.en.xlf (English)
* New translations messages.en.xlf (English)
* New translations messages.en.xlf (German)
* Add SI-prefix-aware sorting column for the parts table
Adds an optional "Name (SI)" column that parses numeric values with SI
prefixes (p, n, u/µ, m, k/K, M, G, T) from part names and sorts by the
resulting physical value. This is useful for electronic components where
alphabetical sorting produces wrong results — e.g. 100nF, 10pF, 1uF
should sort as 10pF < 100nF < 1uF.
Implementation:
- New SiValueSort DQL function with platform-specific SQL generation
for PostgreSQL (POSIX regex), MySQL/MariaDB (REGEXP_SUBSTR), and
SQLite (PHP callback registered via the existing middleware).
- The regex is start-anchored: only names beginning with a number are
matched. Part numbers like "MCP2515" or "Crystal 20MHz" are ignored.
- When SI sort is active, NATSORT is appended as a secondary sort so
that non-matching parts fall back to natural string ordering instead
of appearing in arbitrary order.
- The column is opt-in (not in default columns) and displays the parsed
float value, or an empty cell for non-matching names.
* Rename SI column from "Name (SI)" to "SI Value"
The column now shows the parsed numeric value rather than the part name,
so the label should reflect that.
* Support comma as decimal separator in SI value parsing
Part names using European decimal notation (e.g. "4,7 kΩ", "2,2uF")
were parsed incorrectly because the regex only recognized dots. Now
commas are normalized to dots before parsing, matching the existing
pattern used elsewhere in the codebase (PartNormalizer, price providers).
* Add unit price and extended price columns to project BOM table
Adds two optional columns to the project BOM datatable (hidden by
default, toggleable via column visibility):
- **Price**: unit price for the BOM entry in the base currency,
looked up via PricedetailHelper. For parts whose BOM quantity falls
below the minimum order amount the minimum order amount is used for
the price tier lookup so that a price is always returned.
- **Extended Price**: unit price multiplied by the BOM quantity.
Prices are rendered via MoneyFormatter (locale-aware, with currency
symbol). Both columns round up to 2 decimal places to avoid displaying
0.00 for very small prices.
* Add translation key for project.bom.ext_price
Adds the English translation "Extended Price" for the new BOM extended
price column. Other languages are marked needs-translation and will be
picked up by Crowdin.
* Add build price summary to project info tab
Displays the total BOM price for N builds on the project info page,
using the existing price-tier logic from PricedetailHelper. The user
can adjust the number of builds via a small form; the unit price is
also shown when N > 1.
New backend:
- ProjectBuildHelper gains calculateTotalBuildPrice(),
calculateUnitBuildPrice(), roundedTotalBuildPrice(), and
roundedUnitBuildPrice() — bulk-order quantities are factored in so
that price tiers apply correctly across N builds.
- ProjectController::info() now reads ?n= and passes number_of_builds
to the template.
Template (_info.html.twig):
- Adds price badge (hidden when no pricing data is available).
- Adds number-of-builds form that reloads the info page.
* Add tests for build price calculation in ProjectBuildHelper
Covers calculateTotalBuildPrice(), calculateUnitBuildPrice(),
roundedTotalBuildPrice(), and the private getBomEntryUnitPrice()
helper. Scenarios tested: empty project, no pricing data, non-part BOM
entries with manual prices, part entries with pricedetails, mixed
entries, rounding-up of sub-cent prices, and minimum order amount
floor for price tier lookup.
* Deduplicate BOM entry price logic into ProjectBuildHelper
The private getBomEntryUnitPrice() in ProjectBomEntriesDataTable was
identical to the one in ProjectBuildHelper. Replaced it with a new
public getEntryUnitPrice() on ProjectBuildHelper (returns BigDecimal,
never null) and delegate to it from the DataTable.
This eliminates the duplicate code and brings the DataTable lines under
the existing ProjectBuildHelper test coverage. Added three tests for
getEntryUnitPrice() covering the no-pricing, non-part, and part cases.
* Added type hint to service
---------
Co-authored-by: Jan Böhmer <mail@jan-boehmer.de>
* Add admin editor for KiCad autocomplete lists
* Add custom KiCad autocomplete list settings
* Ignore the footprints_custom.txt and symbols_custom.txt in git and create them on the fly if needed
Otherwise it breaks the update mechanism
* Added comments
* Include kicad custom files in config backup command
---------
Co-authored-by: Jan Böhmer <mail@jan-boehmer.de>
* Implement parsing of TME QR codes
They are present on parts purchased on tme.eu. It's based on the LCSC
parser. Some older codes I found are in upper-case so I handle those
too.
* Removed unused method
* Fixed translation message keys
* Try to find TME part via SPN
---------
Co-authored-by: Jan Böhmer <mail@jan-boehmer.de>
* New translations messages.en.xlf (English)
* New translations messages.en.xlf (English)
* New translations validators.en.xlf (German)
* New translations messages.en.xlf (German)
* Add manual backup creation and delete buttons to Update Manager
- Add "Create Backup" button in the backups tab for on-demand backups
- Add delete buttons (trash icons) for update logs and backups
- New controller routes with CSRF protection and permission checks
- Use data-turbo-confirm for CSP-safe confirmation dialogs
- Add deleteLog() method to UpdateExecutor with filename validation
* Add Docker backup support: download button, SQLite restore fix, decouple from auto-update
- Decouple backup creation/restore UI from can_auto_update so Docker
and other non-git installations can use backup features
- Add backup download endpoint for saving backups externally
- Fix SQLite restore to use configured DATABASE_URL path instead of
hardcoded var/app.db (affects Docker and custom SQLite paths)
- Show Docker-specific warning about var/backups/ not being persisted
- Pass is_docker flag to template via InstallationTypeDetector
* Add tests for backup/update manager improvements
- Controller tests: auth, CSRF validation, 404 for missing backups, restore disabled check
- UpdateExecutor: deleteLog validation, non-existent file, successful deletion
- BackupManager: deleteBackup validation for missing/non-zip files
* Fix test failures: add locale prefix to URLs, correct log directory path
* Fix auth test: expect 401 instead of redirect for HTTP Basic auth
* Improve test coverage for update manager controller
Add happy-path tests for backup creation, deletion, download,
and log deletion with valid CSRF tokens. Also test the locked
state blocking backup creation.
* Fix CSRF tests: initialize session before getting tokens
* Fix CSRF tests: extract tokens from rendered page HTML
* Harden backup security: password confirmation, CSRF, env toggle
Address security review feedback from jbtronics:
- Add IS_AUTHENTICATED_FULLY to all sensitive endpoints (create/delete
backup, delete log, download backup, start update, restore)
- Change backup download from GET to POST with CSRF token
- Require password confirmation before downloading backups (backups
contain sensitive data like password hashes and secrets)
- Add DISABLE_BACKUP_DOWNLOAD env var (default: disabled) to control
whether backup downloads are allowed
- Add password confirmation modal with security warning in template
- Add comprehensive tests: auth checks, env var blocking, POST-only
enforcement, status/progress endpoint auth
* Fix download modal: use per-backup modals for CSP/Turbo compatibility
- Replace shared modal + inline JS with per-backup modals that have
filename pre-set in hidden fields (no JavaScript needed)
- Add data-turbo="false" to download forms for native browser handling
- Add data-bs-dismiss="modal" to submit button to auto-close modal
- Add hidden username field for Chrome accessibility best practice
- Fix test: GET on POST-only route returns 404 not 405
* Fixed translation keys
* Fixed text justification in download modal
* Hardenened security of deleteLogEndpoint
* Show whether backup, restores and updates are allowed or disabled by sysadmin on update manager
* Added documentation for update manager related env variables
---------
Co-authored-by: Jan Böhmer <mail@jan-boehmer.de>
* New translations messages.en.xlf (Italian)
* New translations validators.en.xlf (Italian)
* 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 (English)
* New translations messages.en.xlf (German)
* New translations messages.en.xlf (English)