Compare commits

...

764 commits

Author SHA1 Message Date
d-buchmann
c44535990b
Fix typo and copy-paste error (#942)
Some checks failed
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.4, mysql) (push) Has been cancelled
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.1, postgres) (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.1, sqlite) (push) Has been cancelled
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.1, mysql) (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
2025-05-23 18:09:56 +02:00
Jan Böhmer
b8d5b83eee Bumped version 1.17.1
Some checks failed
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.4, postgres) (push) Has been cancelled
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.1, sqlite) (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
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.1, mysql) (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.1, postgres) (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
2025-05-18 22:54:26 +02:00
Jan Böhmer
00da2dedc3 Ignore phpstan issue 2025-05-18 22:54:03 +02:00
Jan Böhmer
4ce1de079e Updated dependencies 2025-05-18 22:41:05 +02:00
Jan Böhmer
6b9c125de4 Added console command to sanitize SVG files 2025-05-18 22:38:43 +02:00
Jan Böhmer
2c4f44e808 Sanatize SVG files when uploading 2025-05-18 21:00:19 +02:00
Jan Böhmer
2b694731ad Added content-security policy for SVG files in webserver config 2025-05-18 20:38:53 +02:00
Michael
7e34535e62
Added Datamatrix and C93 label twigs (#931)
Some checks failed
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.4, postgres) (push) Has been cancelled
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.1, sqlite) (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
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.1, mysql) (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.1, postgres) (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
* Added Datamatrix and C93 label twigs

* Added new barcode placeholders to ckeditor plugin

---------

Co-authored-by: Jan Böhmer <mail@jan-boehmer.de>
2025-05-11 00:46:38 +02:00
Jan Böhmer
0bb831fe88 Updated dependencies 2025-05-11 00:33:29 +02:00
Jan Böhmer
42a32ce142 Merge remote-tracking branch 'origin/l10n_master' 2025-05-11 00:32:34 +02:00
Jan Böhmer
23f58b7bf4 New translations security.en.xlf (French) 2025-05-02 08:23:16 +02:00
Jan Böhmer
4e9101fded New translations messages.en.xlf (Italian) 2025-03-30 19:01:21 +02:00
Jan Böhmer
9c700c77a8 New translations messages.en.xlf (English) 2025-03-30 17:21:15 +02:00
Jan Böhmer
cb1f674332 Removed now obsolete notice about requiring digikey v3 api in docs.
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.1, postgres) (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.1, sqlite) (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.1, mysql) (push) Has been cancelled
2025-03-30 16:24:33 +02:00
Jan Böhmer
6823d94ffb New translations messages.en.xlf (English) 2025-03-30 16:21:19 +02:00
Jan Böhmer
60ab992360 Bumped to version 1.17.0 2025-03-30 16:06:47 +02:00
Jan Böhmer
f9e769a6e3 Fixed phpstan issue 2025-03-30 15:01:28 +02:00
Jan Böhmer
f802c6c176 Exclude automigration-backup folder from clean attachments folder 2025-03-30 14:50:52 +02:00
Jan Böhmer
dedadf0c10 Merge remote-tracking branch 'origin/master' 2025-03-30 14:47:53 +02:00
Jan Böhmer
c8375def1a Added an database automigration feature to the docker image 2025-03-30 14:47:48 +02:00
Jan Böhmer
62ebcde2de
New Crowdin updates (#899)
* New translations messages.en.xlf (English)

* New translations messages.en.xlf (German)
2025-03-30 14:23:21 +02:00
Jan Böhmer
594a5779dc Specify that we mean a column in drop statement. This is more correct
Some checks are pending
Build assets artifact / Build assets artifact (push) Waiting to run
Docker Image Build / docker (push) Waiting to run
Docker Image Build (FrankenPHP) / docker (push) Waiting to run
Static analysis / Static analysis (push) Waiting to run
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.1, mysql) (push) Waiting to run
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.2, mysql) (push) Waiting to run
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.3, mysql) (push) Waiting to run
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.4, mysql) (push) Waiting to run
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.1, postgres) (push) Waiting to run
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.2, postgres) (push) Waiting to run
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.3, postgres) (push) Waiting to run
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.4, postgres) (push) Waiting to run
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.1, sqlite) (push) Waiting to run
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.2, sqlite) (push) Waiting to run
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.3, sqlite) (push) Waiting to run
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.4, sqlite) (push) Waiting to run
This should help with more strict sql servers like in issue #900
2025-03-29 20:57:58 +01:00
Jan Böhmer
c0ef64fb64 Use updated version of translation-editor-bundle 2025-03-29 16:24:32 +01:00
Jan Böhmer
48c70c3bb4 Added way to batch edit the location of parts with a single stock 2025-03-29 16:21:10 +01:00
Jan Böhmer
68124a340b Updated dependencies
Some checks are pending
Build assets artifact / Build assets artifact (push) Waiting to run
Docker Image Build / docker (push) Waiting to run
Docker Image Build (FrankenPHP) / docker (push) Waiting to run
Static analysis / Static analysis (push) Waiting to run
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.4, sqlite) (push) Waiting to run
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.1, mysql) (push) Waiting to run
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.2, mysql) (push) Waiting to run
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.3, mysql) (push) Waiting to run
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.4, mysql) (push) Waiting to run
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.1, postgres) (push) Waiting to run
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.2, postgres) (push) Waiting to run
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.3, postgres) (push) Waiting to run
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.4, postgres) (push) Waiting to run
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.1, sqlite) (push) Waiting to run
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.2, sqlite) (push) Waiting to run
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.3, sqlite) (push) Waiting to run
2025-03-29 13:45:53 +01:00
Jan Böhmer
0b5003fcf6 We are in development of 1.17 2025-03-29 13:41:30 +01:00
Jan Böhmer
956ece60af Added documentation for attachments download command 2025-03-29 13:35:29 +01:00
Jan Böhmer
53da45d7d7 Added command to download all external-only attachments to the local file system 2025-03-29 13:33:35 +01:00
Jan Böhmer
57f0432a87 Fixed typo in attachmentrepository 2025-03-29 12:52:43 +01:00
Jan Böhmer
fb535ec6f7 Added tests for latex formatted units 2025-03-29 12:37:17 +01:00
Jan Böhmer
4e1b1a4ffa Render units of parameters in upstanding latex
Fixes issue #856
2025-03-29 12:33:18 +01:00
Jan Böhmer
5b111d80f1 Invalidate kicad category cache, when parts get changed, as this might affect the visibility of categories too
Related to #885
2025-03-29 12:01:26 +01:00
Jan Böhmer
03e1105a8e Fixed phpstan issues
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.1, mysql) (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.1, postgres) (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.1, sqlite) (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
2025-03-27 23:11:49 +01:00
Jan Böhmer
059a9683db Fixed problem that global_theme setting was not respected
This fixes issue #880
2025-03-27 21:47:52 +01:00
Jan Böhmer
1daf6f01f4 Fixed error 500 if internal attachment path was not resolvable to an URL
This fixes issue #898
2025-03-27 21:40:51 +01:00
Daniel Carrasco
d3b225771c
Modified the DigiKey Provider to works with the V4 API (#875)
* Modified the DigiKey Provider to works with the V4 API

* Correclty apply the MarketPlaceFilter option to digikey v4 API

* Show the packe type (Tape&Reel, Box, etc.) as footprint in digikey provider search

---------

Co-authored-by: Jan Böhmer <mail@jan-boehmer.de>
2025-03-27 21:26:18 +01:00
Jan Böhmer
7275db27e7 Manually filter mouser search results to fix the edgecase, that the API returned multiple results for an exact part number
This fixes issue #888 and issue #616
2025-03-27 21:06:50 +01:00
Jan Böhmer
49ee9131d0 Use composer/ca-bundle instead of system CA for element14 provider
This is a workaround for debian systems, where the required root CA is missing as trusted CA in the system CAs. This fixes issue #891 and #866
2025-03-27 20:59:22 +01:00
Jan Böhmer
e75e0c4c0b Add a link to the category part info as category description in KiCAD.
This also fixes issue #878
2025-03-27 20:34:32 +01:00
Jan Böhmer
e94d4a7752 Merge remote-tracking branch 'origin/l10n_master'
Some checks failed
Static analysis / Static analysis (push) Has been cancelled
PHPUnit Tests / PHPUnit and coverage Test (PHP 8.1, mysql) (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.1, postgres) (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.1, sqlite) (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
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
2025-03-23 19:52:02 +01:00
Jan Böhmer
95206f427d We are in development of 1.16.2-dev now 2025-03-23 19:51:58 +01:00
Jan Böhmer
2d7f88522a Improved attachment download compatibility
Added more headers to make it appear more like a browser request, and try to use TLS1.3, if we get a 403 (which is useful for digikey).

Commit cherry picked from @Treeed
2025-03-23 19:51:21 +01:00
Jan Böhmer
f5c17bc7c8 Fixed Pollin provider exception, if product top features panel does not exist 2025-03-23 19:43:28 +01:00
Jan Böhmer
63e222ed40 Upgraded dependencies 2025-03-23 19:41:40 +01:00
Jan Böhmer
6963ee3b8d New translations messages.en.xlf (Spanish) 2025-03-11 14:02:14 +01:00
Jan Böhmer
bb5e42bf63 New translations security.en.xlf (Spanish) 2025-03-11 14:02:10 +01:00
Jan Böhmer
c48f778648
Update console_commands.md 2025-03-07 11:30:50 +01:00
Jan Böhmer
616aad6403
Added hint to docker install docs, that you need to run sudo with -E command
That should prevent isssues like in #882 and #871
2025-03-07 11:29:58 +01:00
Jan Böhmer
bcc7547d6f
New Crowdin updates (#874)
* New translations messages.en.xlf (Italian)

* New translations messages.en.xlf (English)
2025-03-02 21:14:42 +01:00
Jan Böhmer
5a1a6e9217
Bumped version 1.16.1 2025-02-26 12:28:07 +01:00
Jan Böhmer
eae1fcecab
New translations security.en.xlf (Chinese Simplified) (#870) 2025-02-26 12:27:11 +01:00
Marc
b53989bb9d
Update LCSCProvider.php: fix error in query string (#873)
Fix typo in query string 'prodctCode' -> 'productCode' introduced in Commit 80527e3
2025-02-25 13:32:36 +01:00
Jan Böhmer
467d50bd31 Use slightly different migration method for attachment system migration
This maybe help with issue #871
2025-02-25 00:32:04 +01:00
Jan Böhmer
1935258978 Fixed phpstan issue 2025-02-23 22:55:59 +01:00
Jan Böhmer
2b5030c69f Bumped version to 1.16.0 2025-02-23 22:40:02 +01:00
Jan Böhmer
6537502696
New Crowdin updates (#867)
* New translations messages.en.xlf (English)

* New translations messages.en.xlf (German)
2025-02-23 17:30:33 +01:00
Jan Böhmer
0ba352ab0b Updated composer dependencies 2025-02-23 17:28:39 +01:00
Jan Böhmer
5d3f861728 Use newer version of farnell/element14 api to get the correct links to product pages. Also we can now retrieve a more detailed description, which will be put into the notes field 2025-02-22 23:29:57 +01:00
Jan Böhmer
319b69f6c7 Added an workaround for issue #862 2025-02-22 22:59:55 +01:00
Jan Böhmer
c4ba28e3a0 Heavily refactored the property metadata attribute logic
The new method is much more universal and fixes issue #862
2025-02-22 22:19:38 +01:00
Jan Böhmer
b38ef8ecea Revert "Fixed type error introduced with api-platform upgrade"
This reverts commit a54c2db9b9.
2025-02-22 21:12:58 +01:00
Jan Böhmer
cb0817666d Revert "Use the modular api-platform packages instead of the monolitic api-platform/core package"
This reverts commit 17caf476bf.
2025-02-22 21:12:54 +01:00
Jan Böhmer
a54c2db9b9 Fixed type error introduced with api-platform upgrade 2025-02-22 19:59:12 +01:00
Jan Böhmer
17caf476bf Use the modular api-platform packages instead of the monolitic api-platform/core package 2025-02-22 19:48:36 +01:00
Jan Böhmer
42cb590c75 Fixed deprecations with api platform 2025-02-22 19:35:49 +01:00
Jan Böhmer
6fd05e1456 Fixed migration 2025-02-22 19:23:28 +01:00
Jan Böhmer
bec45d60e5 Fixed migration for postgresql 2025-02-22 18:03:03 +01:00
Jan Böhmer
019e67a676 Migrate legacy attachment discriminator class values to modern format, so that we can make the discriminator map unique and fix a deprecation with doctrine 2025-02-22 17:58:20 +01:00
Jan Böhmer
f146d88aa5 Added additional filters to attachment datatable 2025-02-22 17:48:26 +01:00
Jan Böhmer
48be9a8098 Made attachment datatable sortable by internal filename and external url 2025-02-22 17:41:41 +01:00
Treeed
29f92d9bd3
Split attachment paths (#848)
* fixed attachment statistics for sqlite

* Split attachment path into internal and external path, so the external source URL can be retained after a file is downloaded

* Make internal and external path for attachments nullable, to make clear that they have no internal or external path

* Added migrations for nullable columns for postgres and mysql

* Added migration for nullable internal and external pathes for sqlite

* Added translations

* Fixed upload error

* Restrict length of filename badge in attachment edit view

* Improved margins with badges in attachment edit

* Added a link to view external version from attachment edit

* Let media_url  stay in API attachments responses for backward compatibility

---------

Co-authored-by: jona <a@b.c>
Co-authored-by: Jan Böhmer <mail@jan-boehmer.de>
2025-02-22 17:29:14 +01:00
Jan Böhmer
ebb977e99f Updated dependencies 2025-02-20 22:10:57 +01:00
Jan Böhmer
94bcd3d2d3 Fixed static analysis issue 2025-02-20 20:35:00 +01:00
Jan Böhmer
a9bd4c5606 Use better parameter value parsing for pollin and reichelt parameters 2025-02-20 19:45:05 +01:00
Jan Böhmer
8d9dde0032 Show the desired part, when searching for the pollin part number 2025-02-20 19:39:35 +01:00
Jan Böhmer
b2d4333fff Merge branch 'pollin_provider' 2025-02-20 19:36:36 +01:00
Jan Böhmer
afd5e2b95b Added documentation for pollin info provider 2025-02-20 19:36:31 +01:00
Jan Böhmer
085adf8d71 Throw an exception message, when trying to use an info provider which is not active 2025-02-20 19:35:16 +01:00
Jan Böhmer
9b35b60d61 Use correct price for one unit if there are multiple prices availble
We can still not parse the bulk prices correctly completly
2025-02-20 19:32:31 +01:00
Jan Böhmer
742e57cc5c Added basic provider for pollin 2025-02-20 19:20:14 +01:00
Jan Böhmer
a5961668fe Disable info provider result caching when in debug mode 2025-02-20 16:59:16 +01:00
Jan Böhmer
e7394c165a Undo change to cache expiration 2025-02-20 16:57:16 +01:00
Jan Böhmer
7be966122f Added missing info hint how to enable reichelt provider 2025-02-20 16:56:21 +01:00
Jan Böhmer
d176b68fd2 Merge branch 'reichelt_provider' 2025-02-20 16:46:58 +01:00
Jan Böhmer
1e80be1376 Added documentation for reichelt info provider 2025-02-20 16:46:47 +01:00
Jan Böhmer
3585b08d4b Pass reichelt env through docker container 2025-02-20 16:38:07 +01:00
Jan Böhmer
c51e0eb68f Allow to get prices in non-EUR currencies from reichelt 2025-02-20 16:37:13 +01:00
Jan Böhmer
d05c0579a2 Fixed problem that first batch price was not included 2025-02-20 16:33:37 +01:00
Jan Böhmer
5e40519bc5 Allow to select if VAT should be included or not 2025-02-20 16:29:37 +01:00
Jan Böhmer
d13752114c Allow to configure the reichelt info provider via env vars 2025-02-20 16:06:10 +01:00
Jan Böhmer
90e1b809fe Allow to change language and country 2025-02-20 15:59:35 +01:00
Jan Böhmer
32b4e6812d Undo change to cache expiration 2025-02-20 15:40:26 +01:00
Jan Böhmer
a798aa9c24 Allow to extract MPN from reichelt provider 2025-02-20 15:39:35 +01:00
Jan Böhmer
f1c28b9f46 Allow to parse batch prices 2025-02-20 15:14:59 +01:00
Jan Böhmer
39bc400376 Added basic price info retrieval from reichelt 2025-02-20 00:32:03 +01:00
Jan Böhmer
e287918121 Extract category from reichelt provider 2025-02-20 00:24:46 +01:00
Jan Böhmer
e0bf8e5fbc Allow reichelt provider to parse parameters 2025-02-20 00:18:05 +01:00
Jan Böhmer
376c7e7a6f Allow to parse ranges for ParameterDTO which just contain two dots 2025-02-20 00:17:53 +01:00
Jan Böhmer
5612a790fb Added basic way to retrieve simple part infos and datasheet 2025-02-19 23:55:58 +01:00
Jan Böhmer
80527e35c3 Added basic reichelt search capabilities 2025-02-19 00:44:49 +01:00
Jan Böhmer
f592ab6395 Updated KiCAD library lists to latest KICAD lib 2025-02-16 21:48:30 +01:00
Jan Böhmer
d7c741c652 Disable create option for input selects if an entity with this name already exists 2025-02-16 21:14:57 +01:00
Jan Böhmer
9502f30e1b Add cllear button to entity select type 2025-02-16 20:36:46 +01:00
Jan Böhmer
7286c4bbef Fixed bug in autoselect_typed plugin 2025-02-16 20:24:13 +01:00
Jan Böhmer
a976f97dbb Apply click_to_edit plugin where reasonable 2025-02-16 20:24:01 +01:00
Jan Böhmer
2c9b8c7dea Merge remote-tracking branch 'origin/l10n_master' 2025-02-16 19:48:57 +01:00
Jan Böhmer
787decf4e2 Updated dependencies 2025-02-16 19:48:51 +01:00
Treeed
2fc70b8bdd
Highlightable attachment paths (#849)
* made autocomplete controller allow selecting text and autocommit typed text on blur

* moved click_to_edit and autoselect_typed into separate plugins

---------

Co-authored-by: jona <a@b.c>
2025-02-16 19:46:29 +01:00
Jan Böhmer
64491a9772 New translations security.en.xlf (Dutch) 2025-02-10 17:11:09 +01:00
Jan Böhmer
b724b05de6 Fixed "implicitly marking parameter as nullable" deprecations in PHP 8.4 fixed 2025-02-08 00:19:20 +01:00
Marc
d94c4af1be
Document that only Digikey API v3 is supported (#858) 2025-02-04 21:41:03 +01:00
Nico Felbinger
8f0f5a5eb4
Fix postgresl unix socket example (#852)
* Fix postgresl unix socket example

* Fix user defaulting to root
2025-02-02 21:09:10 +01:00
Treeed
edf50a71d1
fixed attachment statistics for sqlite (#847)
Co-authored-by: jona <a@b.c>
2025-02-02 21:05:47 +01:00
Jan Böhmer
d0937218b9 Bumped version to 1.15.2 2025-02-01 23:47:14 +01:00
Jan Böhmer
3247a97217 Removed "All" page length option for log tables, as this easily causes an out of memory situation on the server
You can easily have thousands of log entries, making it impossible to view them all at once.

This fixes #835
2025-02-01 23:44:07 +01:00
Jan Böhmer
edd254ee06 Merge remote-tracking branch 'origin/l10n_master' 2025-02-01 23:14:50 +01:00
Jan Böhmer
42ecb83155 Rename duplicate parameters and attachments when importing from an info provider
This fixes issue #840
2025-02-01 23:14:42 +01:00
Jan Böhmer
56f801c058 New translations messages.en.xlf (English) 2025-02-01 21:30:23 +01:00
Marc
2d3d05e956
Added character symbols for degree and registered in keybindings.md (#845) 2025-02-01 21:02:02 +01:00
Marc
4321e51bf5
Update messages.de.xlf (#841)
Removed "es" in german translation of string tfa_trustedDevices.explanation
2025-02-01 20:58:55 +01:00
Jan Böhmer
be04730906
New Crowdin updates (#837)
* New translations security.en.xlf (Russian)

* New translations validators.en.xlf (Russian)

* New translations messages.en.xlf (Russian)

* New translations messages.en.xlf (English)

* New translations messages.en.xlf (Italian)
2025-02-01 20:58:35 +01:00
Jan Böhmer
aa06e1df04 Fixed exception when trying to export an empty entity list
Fixes issue #836
2025-02-01 20:57:27 +01:00
Jan Böhmer
fd7a0156bc Disable GET_GROSS_PRICES option for TME info provider when using private key. Otherwise we receive an error.
This fixes issue #838
2025-02-01 20:20:33 +01:00
Jan Böhmer
1e19ff24ba Updated dependencies 2025-02-01 20:01:33 +01:00
Jan Böhmer
0f4238291f Bumped version to 1.15.1 2025-01-07 21:56:13 +01:00
Jan Böhmer
03a2a10efd Updated dependencies 2025-01-07 16:51:34 +01:00
Jan Böhmer
04310aa2f8 Removed WebpackAutoPathSubscriber, as it seems it not necessary anymore with encore 5 2025-01-07 16:39:51 +01:00
Jan Böhmer
e8ca11a5cf Do not use a slash prefix for .setPublicPath() in webpack config. Webpack encore 5 seemed to have changed something, so that it does not get overriden anymore
We just get a warning, which we can ignore.
2025-01-07 16:14:21 +01:00
Jan Böhmer
24137b30a5 Added tests for RedirectController that simulates the situation of a reverse proxy and subdirectory 2025-01-07 15:52:28 +01:00
Jan Böhmer
4421917333 Revert "Removed baarcode scanner inbox, as we now have enough performance to apply the decoder to the full image"
This reverts commit de0832bece.
2025-01-06 00:49:16 +01:00
Jan Böhmer
25c8660c2e Bumped version to 1.15.0 2025-01-06 00:31:19 +01:00
Jan Böhmer
190e87390d
New Crowdin updates (#804)
* New translations security.en.xlf (Italian)

* New translations messages.en.xlf (German)

* New translations security.en.xlf (German)
2025-01-06 00:29:40 +01:00
Jan Böhmer
c9aefdd862 Start with an empty selection of category when a new part is created, so that the user has to manually select it 2025-01-06 00:29:26 +01:00
Jan Böhmer
3ad088663f Fixed phpstan issue 2025-01-06 00:21:04 +01:00
Jan Böhmer
a29e87e5ac Fixed phpunit tests 2025-01-06 00:19:31 +01:00
Jan Böhmer
de0832bece Removed baarcode scanner inbox, as we now have enough performance to apply the decoder to the full image 2025-01-06 00:08:42 +01:00
Jan Böhmer
614697ba84 Use zxing-wasm polyfill even if native barcode detector API is available as the polyfill is sometimes better than the native on
See discussion #808 for more infos
2025-01-05 23:43:17 +01:00
Jan Böhmer
6bdf3d891a Include the JSON encoded response, when throwing an unknown response format in mouser provider
Should help to debug issue #820
2025-01-05 22:15:12 +01:00
Jan Böhmer
f75704f77c Allow users to save a new label profiles directly from the label generator dialog
This fixes issue #806
2025-01-05 22:00:07 +01:00
Jan Böhmer
9d09543eb9 Added a button to quickly go to all label profiles editor
Related to issue #806
2025-01-05 17:50:15 +01:00
Jan Böhmer
a6116398a8 Only run PartDenormalizer when importing files, otherwise it causes problems with API platform
This fixes issue #800
2025-01-05 17:37:02 +01:00
Jan Böhmer
39763b84d5 Updated dependencies 2025-01-05 15:37:21 +01:00
Jan Böhmer
8502df08fa Added test for autodetection of EIGP114 barcodes 2025-01-04 18:43:50 +01:00
Jan Böhmer
bf2a776403 Do the EIGP114 detection after userdefined barcode detection, so that users can override it on their partLots 2025-01-04 18:41:27 +01:00
Jan Böhmer
052190c69b Do not trim user_barcode for partLots 2025-01-04 18:40:18 +01:00
Jan Böhmer
8826ba6729 Fixed CSP rules to allow the WASM loading for the barcode scanner 2025-01-04 18:23:57 +01:00
Jan Böhmer
39b5240934 We are in development of version 1.15.0 2025-01-04 18:14:15 +01:00
Jan Böhmer
ddc1c286d9 Merge branch 'detector-api-polyfill' 2025-01-04 18:10:36 +01:00
Jan Böhmer
22fba37d28 Pause the camera and scanner, when navigating away from the scanner page, so that the camera feed is closed 2025-01-04 18:10:26 +01:00
Jan Böhmer
0c627a5636 Use forked version of html5-qrcode to avoid including zxing-js which will never be used then 2025-01-04 18:09:56 +01:00
Jan Böhmer
53dcd24216 Improved scanning FPS to 10 2025-01-04 16:57:41 +01:00
Jan Böhmer
4b09a321ad Polyfill BarcodeDetector API for improved performance of Html5QRcodeScanner 2025-01-04 16:49:17 +01:00
Treeed
9e85b70c17
Added capability to scan Digikey barcodes and open the local part part page based on the result (#811)
* added capability to scan digikey barcodes and open the local part page based on the digikey part number or manufacturer part number

* had replaced one too many doublequotes

* Generalized interpretation of format06 barcodes, added ids for mouser

* Renamed vendor_barcode to user_barcode in entities

* Added a own class to parse EIGP114 barcodes

* Added tests to EIGP114Barcode parser

* Refactored code

* Changed BarcodeRedirector to support the new Barcode EIGP114BarcodeScanResult class

* Added possibility to just show all information contained in a barcode

* Dont require trailer for EIGP114 barcodes, as digikey does not seem to put them onto their  barcodes

* Fixed inspection issues

---------

Co-authored-by: jona <a@b.c>
Co-authored-by: Jan Böhmer <mail@jan-boehmer.de>
2025-01-04 01:20:51 +01:00
Jan Böhmer
9c99217dee Fixed test errors 2025-01-03 20:21:17 +01:00
Jan Böhmer
afc1dbdd4b Updated recipe for symfony flex 2025-01-03 17:45:13 +01:00
Jan Böhmer
20f58fc07d Updated symfony cli recipe
This adds an error message if no composer dependencies are installed
2025-01-03 17:42:49 +01:00
Jan Böhmer
e6b78dd213 Updated dependencies 2025-01-03 17:41:37 +01:00
Jan Böhmer
63893ffabe Allow to automatically map categories from info providers to local categories using the "alternative names" system
This partially addresses issues discussed in discussion #808
2024-12-31 18:31:20 +01:00
Jan Böhmer
c9e519d0b5 Show a warning flash, when creating a part from an info provider that has no category autoprovided
This partially fixes the problems described in discussion #808
2024-12-31 18:25:28 +01:00
Jan Böhmer
273bde90f2 Use the providerID as keyword when searching infos for a part with already existing providerreference and preselect the info provider if possible 2024-12-31 18:13:15 +01:00
Treeed
92e4976396
Show when parts from info provider already exist (#810)
* added button to show existing part with same manufacturer and mpn in provider list

* added button to edit existing part in provider list

* added docstring and comments

* replaced unnecessary double quotes

* Introduced a new twig variable localPart to split up the result

* Highlight a row, if the part is already existing

* Made buttons translatable

* Improved styling of the buttons and added a badge to show a hint

* Extracted database queries for part matching into its own service and optimized the query reducing the required queries by factor 2

* Allow to find existing parts via the stored providerReference

This should allow the database to more quickly find entries

* Allow to use part name and manufacturer alternative names for mapping

* Added a button to update a local part from the info provider and moved some buttons into dropdown menu

---------

Co-authored-by: jona <a@b.c>
Co-authored-by: Jan Böhmer <mail@jan-boehmer.de>
2024-12-31 18:03:36 +01:00
Jan Böhmer
e9efbff912 Upgraded typescript version 2024-12-29 20:15:05 +01:00
Jan Böhmer
41089c08f8 Upgraded exports-loader and webpack-cli 2024-12-29 20:08:59 +01:00
Jan Böhmer
9e23e606f8 Updated marked and compression-webpack plugin 2024-12-29 19:59:31 +01:00
Jan Böhmer
b3f0fd368a Updated webpack encore to 5.0.0 2024-12-29 19:50:02 +01:00
Jan Böhmer
12bd5472e2 Fixed sizing of text in label editor input 2024-12-29 19:47:19 +01:00
Jan Böhmer
ef64779759 Updated CKeditor5 to v41 2024-12-29 19:31:04 +01:00
Jan Böhmer
b3d8076ddf Fixed fixture loading process 2024-12-29 19:06:58 +01:00
Jan Böhmer
f775203608 Use new syntax for getReference() in data fixtures 2024-12-29 13:46:22 +01:00
Jan Böhmer
a6083688e4 Upgraded frontend dependencies 2024-12-29 13:43:32 +01:00
Jan Böhmer
50689cd4e6 Updated datatables-bundle 2024-12-29 13:41:30 +01:00
Jan Böhmer
255fcbac1c Removed direct dependency to phpstan-phpdoc-parser, so that it can get removed when updating the webauthn bundle 2024-12-29 13:38:35 +01:00
Jan Böhmer
7f8ffa56e5 Removed (hopefully) unused and unnecessary dependencies 2024-12-29 13:34:10 +01:00
Jan Böhmer
9a2a5f30a3 Updated doctrine fixtures bundle 2024-12-29 13:20:12 +01:00
Jan Böhmer
a9f444cbb4 Added return types to ExponentialNumberTypes for futureproofing the implementation 2024-12-29 13:14:26 +01:00
Jan Böhmer
164efb0551 Fixed phpstan error with NodesListBuilder 2024-12-29 13:14:00 +01:00
Jan Böhmer
a37b8cbb15 Fixed introduced bug in node flattening 2024-12-28 23:19:55 +01:00
Jan Böhmer
946032a101 Fixed phpstan analysis issues and bad code that showed up with phpstan 2.0 2024-12-28 23:08:08 +01:00
Jan Böhmer
a273acbecd Updated PHPstan configuration 2024-12-28 15:12:18 +01:00
Jan Böhmer
0ceee1582e Updated phpstan to 2.0 2024-12-28 14:56:44 +01:00
Jan Böhmer
04a0369d56 Added proxmox LXC installation method to docs 2024-12-25 19:21:30 +01:00
Jan Böhmer
31a288b44d Added recommendation on installation methods 2024-12-25 19:13:28 +01:00
Jan Böhmer
502dc3aa1c Added kubernetes as available installation method. 2024-12-25 19:12:09 +01:00
Jan Böhmer
6874d7ca55 Upgraded dependencies 2024-12-23 20:34:42 +01:00
Jan Böhmer
da8f669aed Test for PHP 8.4 2024-12-23 20:26:31 +01:00
Vedran Vekic
0f92a69b03
Rewrite LCSC datasheet URL (#795) 2024-12-10 14:32:23 +01:00
Bryce Nagaj
8faa3251c4
Update verbiage (#788) 2024-12-10 14:30:47 +01:00
Marc
56fc14003c
Update information_provider_system.md (#791)
Fixed minor typo in Octopart variable: PROVIDER_OCOTPART_COUNTRY
2024-12-10 14:30:16 +01:00
Jan Böhmer
b3499e4ea5
Fixed (wrongly) failing test on IPAnonymizer 2024-12-02 11:01:39 +01:00
Jan Böhmer
07b1ff9bf5 Bumped version to 1.14.5 2024-12-02 01:00:35 +01:00
Jan Böhmer
5bbf24c92e
New translations security.en.xlf (English) (#786) 2024-12-02 00:22:45 +01:00
Jan Böhmer
eea8b3e679 Merge remote-tracking branch 'origin/master' 2024-12-02 00:22:20 +01:00
Jan Böhmer
e223078af9 Added a custom function to make PostgresSQL searches case insensitive
This is required only for postgres as every other database is case invariant by default. But to achieve a portable way, we implement it via a custom DQL function.

This fixes issue #784
2024-12-02 00:17:54 +01:00
dependabot[bot]
b554d0d851
Bump codecov/codecov-action from 4 to 5 (#774)
Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 4 to 5.
- [Release notes](https://github.com/codecov/codecov-action/releases)
- [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/codecov/codecov-action/compare/v4...v5)

---
updated-dependencies:
- dependency-name: codecov/codecov-action
  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>
2024-12-01 23:16:37 +01:00
Jan Böhmer
b1ba26e0b9 Allow usernames to contain @-signs as long as it is not at the begininng
This allows to use email addresses as usernames and fixes issue #772
2024-12-01 23:05:27 +01:00
Jan Böhmer
ca8ad760d7 Allow SAML users to access the API
This fixes issue #765.
2024-12-01 22:54:22 +01:00
Jan Böhmer
80129c0a88 Use PHP 8.3 as docker image, and allow for longer error log lines
This fixes issue #781
2024-12-01 22:34:05 +01:00
Jan Böhmer
7530e62dfa Do not format error messages as JSON, this makes log files easier to read and reduces line length which can makes problems on FPM
See issue #781
2024-12-01 22:33:32 +01:00
Jan Böhmer
baf8977578 Correctly handle IP addresses containing RFC 4007 scoping 2024-12-01 19:19:04 +01:00
Jan Böhmer
c7bf843312 Updated dependencies 2024-12-01 18:48:22 +01:00
Jan Böhmer
ce6fee1682 Merge remote-tracking branch 'origin/dependabot/composer/symfony/http-client-6.4.15' 2024-11-18 15:43:25 +01:00
Jan Böhmer
2653fad488 Merge remote-tracking branch 'origin/dependabot/composer/symfony/security-http-6.4.15' 2024-11-18 15:43:16 +01:00
Jan Böhmer
dd54c46a29 Merge remote-tracking branch 'origin/l10n_master' 2024-11-18 15:43:10 +01:00
dependabot[bot]
724a0e21d3
Bump symfony/security-http from 6.4.14 to 6.4.15
Bumps [symfony/security-http](https://github.com/symfony/security-http) from 6.4.14 to 6.4.15.
- [Release notes](https://github.com/symfony/security-http/releases)
- [Changelog](https://github.com/symfony/security-http/blob/7.1/CHANGELOG.md)
- [Commits](https://github.com/symfony/security-http/compare/v6.4.14...v6.4.15)

---
updated-dependencies:
- dependency-name: symfony/security-http
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-11-13 18:39:42 +00:00
dependabot[bot]
578277d11f
Bump symfony/http-client from 6.4.14 to 6.4.15
Bumps [symfony/http-client](https://github.com/symfony/http-client) from 6.4.14 to 6.4.15.
- [Release notes](https://github.com/symfony/http-client/releases)
- [Changelog](https://github.com/symfony/http-client/blob/7.1/CHANGELOG.md)
- [Commits](https://github.com/symfony/http-client/compare/v6.4.14...v6.4.15)

---
updated-dependencies:
- dependency-name: symfony/http-client
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-11-13 16:49:40 +00:00
Jan Böhmer
22258e3183 New translations validators.en.xlf (Croatian) 2024-11-10 14:30:20 +01:00
Jan Böhmer
0234463b68 Bumped version to 1.14.4 2024-11-08 23:32:34 +01:00
Jan Böhmer
ef412eef92 Fixed tests 2024-11-08 23:32:14 +01:00
Marc
76ebd22eab
Fixed Typos and mistranslations in GDPR mode (DSGVO Modus) (#757)
Fixed Typo enviroment

Co-authored-by: Marc Kreidler <kreidler@nedo.com>
2024-11-08 23:22:18 +01:00
Jan Böhmer
5b0ca8e346 Updated dependencies 2024-11-08 23:15:40 +01:00
Jan Böhmer
0b6b10c27b Bumped version to 1.14.3 2024-11-05 00:11:39 +01:00
Jan Böhmer
6225d2c9b3 Implemented an easy to use APIFilter for tags
This makes the process of filters more easily and intuitive. This fixes issue #750
2024-11-05 00:07:25 +01:00
Jan Böhmer
01fc6524a4 Added a aggregate function for storelocation sorting to avoid exceptions on Postgres
Actually this was not good on other DB types too, but they just ignored the problems.

This fixes issue #734
2024-11-04 23:46:45 +01:00
Jan Böhmer
2575e6a160 Improved size and position of back to top button to avoid overlapping with buttons, etc.
This should fix issue #737
2024-11-03 23:58:06 +01:00
Jan Böhmer
484ba5ebd7 If user password set command is run in non-interactive mode, show a warning message if no password is inputted
Related to issue #748
2024-11-03 23:39:04 +01:00
Jan Böhmer
b42d98e9f8 Increase font-weight of the <dl> element in part info page to match its look to the <h5> element 2024-11-03 23:21:58 +01:00
Sam Edwards
65b2f045ac
Responsive tweaks (#755)
* Change datatables markup to be responsive with BS5

* Responsive tweaks to single part info
2024-11-03 23:14:52 +01:00
Jan Böhmer
5e76451d46 Try to guess the character encodings and convert it to UTF-8 on importing
This should fix issue #749
2024-11-03 22:27:24 +01:00
Jan Böhmer
a873ad3316 Replace all unicode characters with ASCII chars in FilenameSanatizer to make filenames more sanatized 2024-11-03 22:06:42 +01:00
Jan Böhmer
b1e03f49ee Pass the docker envs for oemsecrets to Part-DB
This fixes issue #742
2024-11-03 21:46:53 +01:00
Jan Böhmer
011e23f8e6 Added polish to language selector 2024-11-03 20:04:43 +01:00
Jan Böhmer
646cd8cf22 Merge remote-tracking branch 'origin/l10n_master' 2024-11-03 20:03:28 +01:00
Jan Böhmer
52ac8a70d5 Updated dependencies 2024-11-03 20:03:24 +01:00
Jan Böhmer
e020334b73 New translations messages.en.xlf (Polish) 2024-10-19 22:40:21 +02:00
Jan Böhmer
7698e83f0b New translations messages.en.xlf (Polish) 2024-10-19 21:40:19 +02:00
Jan Böhmer
dd56f5e0c8 New translations messages.en.xlf (Polish) 2024-10-19 19:30:24 +02:00
Jan Böhmer
92c32eef74
New Crowdin updates (#738)
* New translations validators.en.xlf (Polish)

* New translations messages.en.xlf (Polish)
2024-10-19 19:24:55 +02:00
Jan Böhmer
08770c7dc5 Bumped version to 1.14.2 2024-10-17 00:20:48 +02:00
Priit Laes
808a94e4df
Document APP_SECRET and PostgreSQL specific bits in configuration variables (#727)
* docs: Mention APP_SECRET

* docs: Add PostgreSQL specific bits to DATABASE_URL description
2024-10-16 23:59:53 +02:00
Jan Böhmer
490086d531 Use the same translation for the panel with enabled search options, like in the checkbox options in navbar 2024-10-16 23:59:23 +02:00
Jan Böhmer
2ef3fbb81b Merge remote-tracking branch 'origin/l10n_master' 2024-10-16 23:57:07 +02:00
Jan Böhmer
7d834ac8d7 Include the query part of the request, when generating the url for the datatables via a custom twig function.
This fixes issue #735, as without this the query gets not passed to the datatable
2024-10-16 23:57:02 +02:00
Jan Böhmer
15ad0ec9c0 Updated dependencies 2024-10-16 23:40:48 +02:00
Jan Böhmer
f0b78e8b2c New translations validators.en.xlf (Italian) 2024-10-16 13:50:37 +02:00
Jan Böhmer
e616faa76f New translations messages.en.xlf (Italian) 2024-10-16 13:50:36 +02:00
Jan Böhmer
8159f4d8ee Bumped version to 1.14.1 2024-10-13 23:43:55 +02:00
Jan Böhmer
021c576468 Exclude the translation dumper fix files, to avoid phpstan issues, which we cannot control 2024-10-13 23:23:48 +02:00
Jan Böhmer
1b2339a82c Merge remote-tracking branch 'origin/l10n_master' 2024-10-13 23:22:24 +02:00
Jan Böhmer
2b6bb3f773 New translations messages.en.xlf (German) 2024-10-13 23:20:14 +02:00
Jan Böhmer
abc5c61a06 Fixed problem, that search field and search options did not close when clicking outside
This fixes issue #701. For the search field this was caused by algolia/autocomplete lib, which do not support multiple autocomplete fields on a single page. If initailly loaded on the homepage, which features a second autocomplete, this one "steals" the input listening, and the one in the navbar do not close anymore when clicking outside.
Custom code which triggers the closing of the autocomplete manually when clicking outside, was added as a workaround.
2024-10-13 23:19:03 +02:00
Jan Böhmer
7145bce605 Construct the correct current path, when serving from a subdirectory
This fixes issue #274
2024-10-13 22:49:42 +02:00
Jan Böhmer
bb92e5e9ee New translations validators.en.xlf (German) 2024-10-13 21:40:20 +02:00
Jan Böhmer
0c47aa226c Fixed imports of parameters on parts
It was missing the required serialization group. This fixes issue #718
2024-10-13 21:35:31 +02:00
Jan Böhmer
76e945bbbd Fixed issue that the document could not be scrolled anymore, when redirected from a modal
This fixes issue #696
2024-10-13 21:23:57 +02:00
Jan Böhmer
4a6ec2581d Removed wrongly used controller for merge modal 2024-10-13 20:59:28 +02:00
Jan Böhmer
3d75bf5f9f Added translation for the confirmation code field in the authenticator app 2FA setup section 2024-10-13 20:46:12 +02:00
Jan Böhmer
c27648b89b New translations validators.en.xlf (English) 2024-10-13 20:40:16 +02:00
Jan Böhmer
ccf67c0662 Added translation if authentication confirmation code is wrong 2024-10-13 20:35:56 +02:00
Jan Böhmer
ca116cae91 Keeep the segment annotations in the translation files, when editing them from inside the application 2024-10-13 20:30:56 +02:00
Jan Böhmer
a29d933f99 Fixed 2FA TOTP for non-admins, while also retaining validation of auth code
This fixes issue #717
2024-10-13 20:29:22 +02:00
Jan Böhmer
49acf3e0cf Fixed problem preventing non-admins to add TOTP 2FA to their account
This was caused by the no-lockout constraint, which was accidentially triggered here
2024-10-13 20:13:03 +02:00
Jan Böhmer
234b5abb96 Merge remote-tracking branch 'origin/master' 2024-10-13 19:56:29 +02:00
Jan Böhmer
839bcf91d6 Updated dependencies. 2024-10-13 19:56:21 +02:00
Jan Böhmer
58ed57fab7
New translations messages.en.xlf (English) (#703) 2024-09-12 21:52:34 +02:00
Jan Böhmer
fa42997733 Bumped version to 1.14.0 2024-09-09 21:42:29 +02:00
Jan Böhmer
ac416141d0 Merge remote-tracking branch 'origin/master' 2024-09-09 21:42:15 +02:00
Jan Böhmer
c629a85b14 Updated dependencies 2024-09-09 21:42:03 +02:00
Jan Böhmer
7ccfea208f
New Crowdin updates (#695)
* New translations messages.en.xlf (English)

* New translations validators.en.xlf (German)

* New translations messages.en.xlf (German)

* New translations messages.en.xlf (Italian)
2024-09-09 21:38:07 +02:00
Jan Böhmer
f3c802bcff Made parameter type fields wider to fit more digits 2024-09-09 21:36:05 +02:00
Jan Böhmer
574583bd6a Do not round values of parameters, we can now use the full double precision
This fixes issue #681
2024-09-09 21:33:28 +02:00
Jan Böhmer
84c54d0b25 Removed NumberType fixes, as these is now part of the upstream symfony 2024-09-09 21:13:44 +02:00
Jan Böhmer
86d3f87694 [Digikey provider] Do not try to interpret certain parameters (like packages) as numbers
This fixes issue #682
2024-09-09 20:44:09 +02:00
André Lademann
ddd7252051
Increase image size in list view #688 (#689) 2024-09-09 20:29:25 +02:00
Jan Böhmer
b4e8136618 Fixed problem with undeleting elements containing an embedded and propertly restore the infos of the embed
This fixes issue #685
2024-09-09 20:26:26 +02:00
Jan Böhmer
c2638991f2 Added documentation for OEMSecrets info provider 2024-09-09 17:02:45 +02:00
Jan Böhmer
8554be9abd Show number of results for info provider search and show a notice, if no results were found 2024-09-09 16:41:19 +02:00
Jan Böhmer
87a518703f Escape spaces in unnwrapped urls to avoid invalid URLs 2024-09-09 16:23:12 +02:00
Jan Böhmer
dd03ca943d Fixed phpstan issues 2024-09-09 14:52:18 +02:00
Jan Böhmer
6997861811 [OEMSecrets provider] Extract real URLs and remove tracking parts 2024-09-09 14:52:09 +02:00
Pasquale D'Orsi
1cc1530b20
OEMSecrets provider interface v.1.0 (#679)
* OEMSecrets provider interface v.1.0

New class for interacting with the OEMSecrets (https://www.oemsecrets.com) API version 3.0.1.

* Refactored info provider to be stateless and independent from session, optimized Part-DB API usage, and fixed PHPStan issues.

Refactored info provider to be stateless and independent from session, now use Psr\Cache, fixed issues identified by PHPStan, additional minor enhancements and bug fixes.

* Prefix cache keys with oemsecrets_ to avoid key collissions

* Use uniqid with more entropy to reduce probability of collisions

* Made $resultData local as it is only used inside searchByKeyword

* Use the parameter name $id from interface declaration for getDetails to avoid problems with named arguments

* Use unicode modifier for preg_match to avoid problems when parameters contain non-unicode strings

* Various small code quality improvements

* Try to retrieve the part from the API in getDetails, if the DTO was not cached before

* Improved code formatting

* Channged OEMSecret default country to DE to be consistent with other default values

* Do not call gc_collect_cycles in the loop to process the results, but only after all processBatch calls

---------

Co-authored-by: Jan Böhmer <mail@jan-boehmer.de>
2024-09-09 00:59:44 +02:00
Jan Böhmer
98597fb3aa Use new repository pathes (Part-DB-server) instead of the Part-DB-symfony ones 2024-09-08 20:05:06 +02:00
Jan Böhmer
283a445198 Use jbtronics/translation-editor bundle instead of php-translation/symfony-bundle for profiler translation editing
This new bundle has less dependencies and less overhead
2024-09-08 20:03:33 +02:00
Jan Böhmer
7db44f0ec5 Upgraded dependencies 2024-09-08 19:54:31 +02:00
Jan Böhmer
abb5395cae Use "log-bin-trust-function-creators" option for mysql in recommended docker-compose file
This avoids errors, while creating the MySQL functions for the natural sort: "1419 You do not have the SUPER privilege an
  d binary logging is enabled"
2024-09-08 19:46:55 +02:00
Jan Böhmer
8c8b44baef Use debian bookworm, PHP 8.2 and node 20 for the docker image by default 2024-09-08 19:40:43 +02:00
Jan Böhmer
7366a33fe5 Apply the PHP_VERSION arg also to the partdb-entrypoint during build, to make it really version independent 2024-09-08 19:40:19 +02:00
Jan Böhmer
ad02d7e525
New Crowdin updates (#692)
* New translations messages.en.xlf (English)

* New translations validators.en.xlf (English)

* New translations security.en.xlf (English)

* New translations validators.en.xlf (Italian)
2024-09-08 19:14:02 +02:00
David Girón
b5a0189f29
feat(docker): Refactor Dockerfile (#683)
* reorder nodejs/yarn install, separate packages per line

* reduce run actions and reorganize commands

* simplify file creation, copy in one layer only

* fix lint LegacyKeyValueFormat

* arg php_version to run different version

* reorder copy from generated config

* update dockerfile-frankenphp
2024-09-08 19:13:13 +02:00
Jan Böhmer
756152dd68 Bumped to version 1.13.3 2024-08-24 15:58:46 +02:00
Jan Böhmer
173a8ee680 Improved assymmetric padding in datatables footer 2024-08-24 15:55:45 +02:00
Jan Böhmer
b99777cde1 Return a 404 message, instead of creating an 500 Runtime exception, when a file associated with an attachment is not existing.
This fails more gracefully, and do not pollute log files.
2024-08-24 15:49:45 +02:00
Jan Böhmer
8193e7a68e Allow to show attachment IDs in attachment table 2024-08-24 15:48:50 +02:00
Jan Böhmer
f18c024daa Remove -> prefix if no element is selected yet 2024-08-24 15:35:30 +02:00
Jan Böhmer
f6577a8f33 Allow to create sub elements for existing elements, by typing "->"
This fixes issue #666 and #560
2024-08-24 15:31:44 +02:00
Jan Böhmer
7fc3153dde Fixed filter logic for exclusion of entities. Before parts with null values as property value were wrongly not shown
This fixes  issue #658
2024-08-23 22:58:04 +02:00
Jan Böhmer
5231dbd6e7 Remove project path in twig label error messages to prevent information leakage 2024-08-23 22:28:29 +02:00
Jan Böhmer
77671550a7 Fail gracefully, when an exception occurs during rendering of the example labels for label profiles
This fixes issue #671
2024-08-23 22:15:29 +02:00
Jan Böhmer
e231404128 Load HTMLExtension in SandboxedTwig, so that the data_uri filter can be used in twig labels
This fixes issue #665
2024-08-23 22:06:37 +02:00
Jan Böhmer
6650e2da3d Updated dependencies 2024-08-23 21:57:37 +02:00
frank-f
fd521acaa4
Update LCSCProvider field for real datasheet URL (#670) 2024-08-21 17:35:55 +02:00
Jan Böhmer
a169623866 Bump version to 1.13.2 2024-07-28 23:20:47 +02:00
Jan Böhmer
21c3c45150 Introduced a custom ExponentialNumberType for parameter values
This type shows small values in exponential notation instead of rounding it to zero.
2024-07-28 23:18:36 +02:00
Jan Böhmer
1aee0a91c0 Workaround symfonys issue with NumberType and negative exponential e-notation number
This fixes issue #649
2024-07-28 22:52:44 +02:00
Jan Böhmer
27a28d4adc Fixed the NatSortKey function where regex characters were improperly escaped in the old migration
This caused a "range out of order in character class" error and propably affected the functionality of the sort function
2024-07-28 17:08:55 +02:00
Jan Böhmer
d6ff22fc44 Show in server info page which natural sorting method is used
This should ease debugging
2024-07-28 14:13:34 +02:00
Jan Böhmer
5ede61118c Use paragonie/sodium_compat v1 as v2 do not support 32-bit PHP anymore 2024-07-28 13:31:27 +02:00
Jan Böhmer
228549ff51 Include pgsql extensions and client in docker images 2024-07-28 13:12:42 +02:00
Jan Böhmer
1ec5cbc301 Merge remote-tracking branch 'origin/l10n_master' 2024-07-28 13:02:58 +02:00
Jan Böhmer
3011cb8fae Updated dependencies 2024-07-28 13:02:39 +02:00
Jan Böhmer
ff78c3c9a7 New translations security.en.xlf (Vietnamese) 2024-07-10 03:32:31 +02:00
Jan Böhmer
d5980b7620 New translations messages.en.xlf (Spanish) 2024-07-05 11:30:31 +02:00
Jan Böhmer
a8e1171108 Bumped to version 1.13.1 2024-06-23 21:14:00 +02:00
Jan Böhmer
19e5d302f4 Fixed detection on mariadb natsort capabilities on distributions which use the 5.5.5- prefix for MariaDB version 2024-06-23 21:13:37 +02:00
Jan Böhmer
22e2480feb Bumped version to 1.13.0 2024-06-23 19:06:29 +02:00
Jan Böhmer
88ef1788ac Add small time differences to the datafixtures log entries, to get a defined order 2024-06-23 18:03:54 +02:00
Jan Böhmer
a54ce939ca Merge branch 'timetravel-tests' 2024-06-23 17:45:17 +02:00
Jan Böhmer
528d0c7a26 Added tests for TimeTravel service and fixed applyEntry function for embeddded fields 2024-06-23 17:43:10 +02:00
Jan Böhmer
c68a647e75 Added missing tests for LogEntryRepository 2024-06-23 16:07:42 +02:00
Jan Böhmer
e0e4b74b6f Fixed getElementExistedAtTimestamp function() 2024-06-23 15:46:10 +02:00
Jan Böhmer
204178740c Started adding basic tests for LogEntryRepository 2024-06-23 15:41:57 +02:00
Jan Böhmer
8fdf37261d Fixed phpstan issues 2024-06-23 00:42:49 +02:00
Jan Böhmer
06c8e584a4 Allow to import attachments and parameters via entity import
This fixes issue #363
2024-06-23 00:41:25 +02:00
Jan Böhmer
bbf7222a6a Improved EntityExporter to handle recursive exports 2024-06-23 00:11:38 +02:00
Jan Böhmer
f6e955b487 Hide mouser parts with an invalid product ID to avoid the issue described in #616 2024-06-22 23:37:50 +02:00
Jan Böhmer
32a72bfd23 Defocus show/hide sidbar button after clicking to close tooltip
Fixes issue #628
2024-06-22 23:08:51 +02:00
Jan Böhmer
25e0c22de9 Merge branch 'added-scan-button-to-navbar' 2024-06-22 23:04:06 +02:00
Jan Böhmer
2dd1843aac Merge branch 'master' into added-scan-button-to-navbar 2024-06-22 23:03:10 +02:00
Jan Böhmer
f3bf4ca838 New translations validators.en.xlf (English) 2024-06-22 23:02:49 +02:00
Jan Böhmer
b88e5e27d8 Fixed tests 2024-06-22 23:01:40 +02:00
Jan Böhmer
6f91ff1f28 Fixed --overwrite option of the backup command not working
This fixes issue #635
2024-06-22 22:59:16 +02:00
Jan Böhmer
b7b941e3a1 Fixed error handling of structural data import
This was the reason for the exception in #632
2024-06-22 22:55:15 +02:00
Jan Böhmer
64414fe105 Added missing validator.invalid_range translation 2024-06-22 20:00:16 +02:00
Jan Böhmer
701713e298 Fixed symfony UX translations when using a locale with subregion (e.g. en_US)
Fixes issue described in #563
2024-06-22 19:57:49 +02:00
Jan Böhmer
445229976f Allow locales like de_DE in removeLocaleFromPath function
Related to issue #563
2024-06-22 19:48:11 +02:00
Jan Böhmer
eb02404d49 Fixed typing of TextConstraint 2024-06-22 19:06:07 +02:00
Jan Böhmer
c780c0bd92 Fixed "__partLot already defined" error when using a between filter for amountSum on postgres 2024-06-22 19:03:30 +02:00
Jan Böhmer
8f631cae63 Split up NumberConstraint and DateTimeConstraint for better type enforcement 2024-06-22 18:53:26 +02:00
Jan Böhmer
07afff8db5 Updated yarn dependencies 2024-06-22 18:02:42 +02:00
Jan Böhmer
a4f440656a Fixed timetravel feature on postgresql 2024-06-22 17:55:54 +02:00
Jan Böhmer
235d572f8c Use DatetimeImmutable instead of DateTime wherever possible 2024-06-22 17:36:54 +02:00
Jan Böhmer
eebc373734 Merge branch 'rector' 2024-06-22 16:54:09 +02:00
Jan Böhmer
002d29a53e Fixed PHPstan issues 2024-06-22 16:53:59 +02:00
Jan Böhmer
5074e2beac Fixed phpunit tests 2024-06-22 00:44:59 +02:00
Jan Böhmer
d898ca736c Applied rector to remaining test files 2024-06-22 00:37:47 +02:00
Jan Böhmer
af325612aa Dont replace our test 'GET' strings with a class constant 2024-06-22 00:36:30 +02:00
Jan Böhmer
590c2c3b0a Excluded a few more rector rules 2024-06-22 00:34:49 +02:00
Jan Böhmer
20f32c7f12 Applied rector suggestions 2024-06-22 00:31:43 +02:00
Jan Böhmer
4106bcef5f Do not rename tableAction controller 2024-06-22 00:06:48 +02:00
Jan Böhmer
0e3b8a2a28 Do not replace our !== null checks with instanceof 2024-06-22 00:03:52 +02:00
Jan Böhmer
272608b4ec Ignore symfony generated files for rector 2024-06-22 00:00:59 +02:00
Jan Böhmer
7a389469b9 Updated rector 2024-06-21 23:51:44 +02:00
Jan Böhmer
9650969c94 Merge branch 'master' of https://github.com/Part-DB/Part-DB-symfony 2024-06-21 23:41:57 +02:00
Jan Böhmer
6821e668e4 Do not inject ObjectNormalizer into StructuralElementDenormalizer directly 2024-06-21 23:41:52 +02:00
Jan Böhmer
43a68b96ae Moved deprecated doctrine subscribers to doctrine event listeners 2024-06-21 23:41:22 +02:00
Jan Böhmer
1f6e3db09e Document natural sorting and the DATABASE_EMULATE_NATURAL_SORT option 2024-06-21 12:31:25 +02:00
Jan Böhmer
2fabcabcc0 Added documentation about the different DATABASE_URL formats for the database types 2024-06-21 11:58:09 +02:00
Jan Böhmer
22855b077d Improved "Choosing database" documentation page 2024-06-21 11:44:24 +02:00
Jan Böhmer
2cad7a67ea Updated requirements in README file and mention PostgreSQL support in features 2024-06-21 10:39:44 +02:00
Jan Böhmer
8ce93a028a Removed deprecated interface from SkippableItemNormalizer 2024-06-19 23:58:15 +02:00
Jan Böhmer
028307b63c Added some return typehints to functions who missed them 2024-06-19 23:56:08 +02:00
Jan Böhmer
7bd6cd7cec Merge remote-tracking branch 'origin/master' 2024-06-19 23:47:46 +02:00
Jan Böhmer
8c45a40f9e Explicitly configure some deprecated configuration options 2024-06-19 23:47:38 +02:00
dependabot[bot]
70c62dab77
Bump docker/build-push-action from 5 to 6 (#631)
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 5 to 6.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/v5...v6)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  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>
2024-06-19 23:33:43 +02:00
Jan Böhmer
b4d8d31c2d partUnit column in part datatable now shows the correct data
This fixes issue #630
2024-06-19 23:28:53 +02:00
Jan Böhmer
bc15135f6b We are in development of 1.13 now 2024-06-18 23:44:28 +02:00
Jan Böhmer
16baccc2cb Upgraded rector to latest version 2024-06-18 23:33:53 +02:00
Jan Böhmer
bb2559edc1 Fixed PHPstan issue 2024-06-18 23:31:24 +02:00
Jan Böhmer
f6f736a91f Added amphp/http-client to support HTTP/2 connections, even if libcurl is not enabled 2024-06-18 23:25:40 +02:00
Jan Böhmer
9f477676e2 Removed psalm, as we only use phpstan 2024-06-18 23:24:54 +02:00
Jan Böhmer
6cba6ba52e Updated dependencies 2024-06-18 23:21:45 +02:00
Jan Böhmer
d29dbc9385 Merge branch 'postgres' 2024-06-18 23:17:27 +02:00
Jan Böhmer
cb01302ada Test the backup tool in github actions
This ensures that the tool works for all database types
2024-06-18 23:04:44 +02:00
Jan Böhmer
e3dfbf0e95 Support postgres in the backup command 2024-06-18 23:02:33 +02:00
Jan Böhmer
3f471d0c73 Natsort MPN column in part datatables 2024-06-18 22:34:29 +02:00
Jan Böhmer
4a706ab707 Do not natsort description fields as these can become very long 2024-06-18 22:34:13 +02:00
Jan Böhmer
4946a9ab0d Fixed SQL declaration of NatSortKey function
We do not need the delimiter declarations
2024-06-18 22:32:07 +02:00
Jan Böhmer
123372d93f Allow to emulate natural sort on mysql platforms 2024-06-18 21:42:00 +02:00
Jan Böhmer
272fe0516b Allow to emulate natural sorting on SQLite databases 2024-06-18 00:09:44 +02:00
Jan Böhmer
289c9126d0 Use Natural_SORT_KEY for natural sorting on MariaDB database which support that
This resolves issue #243 and #402
2024-06-17 23:29:38 +02:00
Jan Böhmer
0a482da93e Use postgres native array_position function instead of our FIELD function and pass it as array literal instead of variadic function
Otherwise we will run into errors, that we can not give more than 100 arguments to a function
2024-06-17 23:13:04 +02:00
Jan Böhmer
8bb8118d9f Use natural sorting for trees and others repository functions 2024-06-17 22:33:40 +02:00
Jan Böhmer
9db822eabd Use natural sorting for string datatables columns when using postgres
The natural sorting solution is quite portable, so this should be possible for other database types too later
2024-06-17 21:38:16 +02:00
Jan Böhmer
8a42dfa154 Use the FIELD function on postgres for order by field value 2024-06-17 21:20:23 +02:00
Jan Böhmer
d7a7e22e5a Fixed lessThanDesired Constraint for postgresql 2024-06-17 21:16:46 +02:00
Jan Böhmer
4f75e2641b Define a custom FIELD function to sort tables by list of ids without the emulation via string operations 2024-06-16 23:46:40 +02:00
Jan Böhmer
d3dcefb645 Fixed total amount and less than desired filter on postgresql 2024-06-16 23:26:57 +02:00
Jan Böhmer
6d1553e8d8 Fixed problem with datatable column sorting on postgresql 2024-06-16 22:52:15 +02:00
Jan Böhmer
740985d68f New translations security.en.xlf (Croatian) 2024-06-14 23:40:19 +02:00
Jan Böhmer
7ad2fab53d Fixed exception related that Datetimeimmutables were used were doctrine expected mutable ones
this prevented the saving of parts from info providers
2024-06-13 23:41:35 +02:00
Jan Böhmer
6e9b337b49 Fixed regex function for postgres 2024-06-13 23:18:25 +02:00
Jan Böhmer
c58ff5861d Replaced the non standard IFNULL function which postgres does not know with the COALSCE function 2024-06-13 23:01:53 +02:00
Jan Böhmer
33a5e70b70 Fixed phpunit tests for postgres 2024-06-13 22:19:17 +02:00
Jan Böhmer
07f1ce5822 Configure the postgres server to accept local connections without password 2024-06-13 00:00:51 +02:00
Jan Böhmer
d41996b365 Added SSH connection into test container for debugging 2024-06-12 23:33:05 +02:00
Jan Böhmer
d3c9b7eae1 Configure postgres to accept all connections without password for testing 2024-06-12 23:30:42 +02:00
Jan Böhmer
373a1ab0f4 Change the password of the postgres user 2024-06-12 23:24:37 +02:00
Jan Böhmer
58dd56a89f Supply a password for the postgres database connection 2024-06-12 23:16:24 +02:00
Jan Böhmer
d7eadd9294 Use the builtin postgres user already defined in the github image
It hopefully requires no password
2024-06-12 23:13:20 +02:00
Jan Böhmer
853e29dd83 Removed sqlite database creation
This is not possible anymore for the sqlite driver and is unnesecarry as it is automatically created on migration
2024-06-10 23:47:28 +02:00
Jan Böhmer
0c1c46c045 Fixed MySQL version number
The 8.0 was to short to be detected as newer than 8.0.0. We need to specify the bugfix release to get proper results
2024-06-10 23:46:33 +02:00
Jan Böhmer
be97ea08a2 Specify a version number on the MySQL database URL, so that doctrine does not need to start a connection while cache clearing 2024-06-10 23:35:13 +02:00
Jan Böhmer
1c8b81ca2c Run a SSH session in the github actions container for better debugging 2024-06-10 23:05:16 +02:00
Jan Böhmer
8266f230d7 For debugging disable fast failing of phpunit tests 2024-06-10 22:58:54 +02:00
Jan Böhmer
0b53542716 Added postgres to github tests actions 2024-06-10 22:52:11 +02:00
Jan Böhmer
eab1c7096c Use the postgres migration code generated by the new doctrine orm versions
This now uses IDENTITY columns for ID columns, which makes their behavior more similar to the behavior of MySQL and SQLite
2024-06-10 22:38:46 +02:00
Jan Böhmer
8ee3aaf4f4 Added Sqlite migrations required by new doctrine/orm version and fixed migration duplication for sqlite 2024-06-10 21:54:15 +02:00
Jan Böhmer
427b8659c9 Added MySQL migrations required by the doctrine upgrades
The new ORM versions, do not have anymore column comments, so these got removed
2024-06-10 21:43:25 +02:00
Jan Böhmer
3c3af824cf Merge branch 'doctrine-upgrade' into postgres 2024-06-10 21:26:00 +02:00
Jan Böhmer
d40ce470d3 Fixed some invalid class constant use in ResetAutoIncrementORMPurger 2024-06-10 21:25:51 +02:00
Jan Böhmer
07c7f07c35 Removed usage of partial flush which is not supported with the recent doctrine ORM version 2024-06-10 21:25:23 +02:00
Jan Böhmer
fe732ecf45 Fixed minor inspection issue 2024-06-10 21:16:46 +02:00
Jan Böhmer
971bb92a8c Fixed error caused by ArrayType fields which is required by the webauthn bundle but was removed in doctrine/orm 4.0
We simple forward port the ArrayType class from orm 3.8 to fix this error
2024-06-10 21:11:11 +02:00
Jan Böhmer
777f6ba738 Fixed error caused by immutable datetime passed to mutable datetime doctrine type 2024-06-10 20:47:06 +02:00
Jan Böhmer
4d927c5870 Use a better exception format for UTCDateTimeType 2024-06-10 20:17:57 +02:00
Jan Böhmer
1830e9da3d Fixed errors caused by change on how setParameters on query builder works
We replaced them by individual setParameter calls as this seems to be the easiest way to fix this
2024-06-10 00:08:53 +02:00
Jan Böhmer
5eb29746af Revert "Fixed errors that query builder setParameters now expects an ArrayCollection instead of an array"
This reverts commit 78671b0bfe.
2024-06-10 00:04:22 +02:00
Jan Böhmer
afb816cc41 Use the getReference function in TimeTravel service instead of the removed getPartialReference()
This is probably the better choice anyway
2024-06-09 23:58:03 +02:00
Jan Böhmer
bd640c19a4 Fixed type of token object is now a property instead of array value in Field2 2024-06-09 23:55:12 +02:00
Jan Böhmer
0d445b6a21 Fixed some minor inspection issues caused by the doctrine upgrades 2024-06-09 23:51:41 +02:00
Jan Böhmer
78671b0bfe Fixed errors that query builder setParameters now expects an ArrayCollection instead of an array 2024-06-09 23:51:11 +02:00
Jan Böhmer
60325e797d Fixed the use of the removed ClassMetadataInfo constants 2024-06-09 23:45:22 +02:00
Jan Böhmer
7d9be5ae76 Fixed wrong casing of SQLitePlatform 2024-06-09 23:36:00 +02:00
Jan Böhmer
777bfed813 Fixed doctrine middlewares
We now look directly onto the driver arguments instead of retrieving a database platform, for which we would need the database version.

As we modify driver specific options there, this might be the better choice anyway
2024-06-09 23:28:46 +02:00
Jan Böhmer
43ca543651 Fixed wrong signature of UTCDateTimeType 2024-06-09 23:15:14 +02:00
Jan Böhmer
205d5f8f58 Updated doctrine dbal and orm to next major version 2024-06-09 23:11:08 +02:00
RaptorDE
ee37852a72
added scan button navbar in mobile view 2024-06-09 13:02:49 +02:00
Jan Böhmer
dc14b58d73 Fixed DBInfoHelper compatibility with postgres 2024-06-09 00:46:23 +02:00
Jan Böhmer
a88a2e04cf Added the required initial users and groups for the database migration 2024-06-09 00:11:58 +02:00
Jan Böhmer
c620beb965 Merge branch 'master' into postgres 2024-06-08 19:49:07 +02:00
Jan Böhmer
92cb9f70a1 Bumped version to 1.12.1 2024-06-08 19:23:22 +02:00
Jan Böhmer
b2059b6910 Use outline-secondary style for the sidebar toggle button
This makes the button a bit more subtle and fixes issue #620 that the button were not visible in darkmode
2024-06-07 23:28:59 +02:00
Jan Böhmer
0b21effb13
New Crowdin updates (#606)
* New translations security.en.xlf (Dutch)

* New translations messages.en.xlf (English)

* New translations messages.en.xlf (English)
2024-06-07 22:49:18 +02:00
Jan Böhmer
02acafc348 Added postgres to the AbstractMultiPlatformMigration class 2024-06-06 23:11:11 +02:00
Jan Böhmer
d202ecf06f Added support of the custom TinyInt type for postgres 2024-06-06 22:38:33 +02:00
Jan Böhmer
5402d7bedb Increased phpunit memory limit to 1G
This hopefully fixed the failing github action
2024-06-06 20:04:50 +02:00
Jan Böhmer
39247f1ece Updated dompdf to 3.0 2024-06-06 19:44:26 +02:00
Jan Böhmer
55b824d777 Updated dependencies 2024-06-06 19:40:49 +02:00
SapuSeven
4eb223c401
Update LCSC API URL (#612) 2024-05-12 18:21:23 +02:00
Jan Böhmer
4a99a5e68f Bumped version to 1.12.0 2024-04-29 00:11:47 +02:00
Jan Böhmer
a96c10a13e Made KiCAD bom import independent from the language of the header rows
This fixes issue #604
2024-04-29 00:09:10 +02:00
Jan Böhmer
b3b2782f45 Fixed wrong url to KiCad API in user settings if using a prefixed reverse proxy
This fixes issue #587
2024-04-28 23:54:52 +02:00
Jan Böhmer
1bf9f25ded Fixed problem with kicad footprint autcomplete when using a reverse proxy in a prefixed path
This fixes issue #587
2024-04-28 23:27:15 +02:00
Jan Böhmer
75df0198fc Fixed tests 2024-04-28 23:12:10 +02:00
Jan Böhmer
b70d74ae4b Perform the duplicate check of parameter names already on initial creation
This fixes issue #568
2024-04-28 19:38:39 +02:00
Jan Böhmer
dfe4568991 Use a better translation for the "Is not" filter when children should also be excluded 2024-04-28 18:19:47 +02:00
Jan Böhmer
3fff354833 Fixed type conversion error in ProjectBuildType
This seemed only to occur, if the form field was disabled. This fixes issue #601
2024-04-28 18:09:17 +02:00
Jan Böhmer
db72dac243 Save the date when a webauthn key was used last time for 2 factor authentication and show it in user settings 2024-04-28 17:50:19 +02:00
Jan Böhmer
b886c0aeae Removed a now unecessary workaround in the WebatuthnKey entity 2024-04-28 00:43:36 +02:00
Jan Böhmer
91b7f2752f Added the database fields required by the new webauthn bundle versions 2024-04-28 00:31:38 +02:00
Jan Böhmer
f4a67c0224 Merge remote-tracking branch 'origin/l10n_master' 2024-04-27 23:57:44 +02:00
Jan Böhmer
c6ac0302ed Updated dependencies 2024-04-27 23:57:31 +02:00
Jan Böhmer
39f1960135 New translations messages.en.xlf (Chinese Simplified) 2024-04-27 21:30:19 +02:00
Jan Böhmer
ffb659b228 New translations validators.en.xlf (Chinese Simplified) 2024-04-27 20:30:18 +02:00
Jan Böhmer
e93148304e New translations messages.en.xlf (English) 2024-04-26 17:22:47 +02:00
Jan Böhmer
34940dd950
New translations messages.en.xlf (Russian) (#602) 2024-04-22 16:06:13 +02:00
Morgan Diepart
eda0e2fe26
Update Measurement Unit concept (#596) 2024-04-16 12:15:45 +02:00
Jan Böhmer
4aecfaf4e0 Fixed typo in DATABASE_URL env in debian installation guide
Fixes issue #592
2024-04-15 23:42:44 +02:00
Jan Böhmer
767de1dd65 Updated dependencies 2024-04-15 23:42:08 +02:00
frank-f
7a6b045030
Improve parameter parsing (#583)
* DigiKey: Skip empty values

* Move improved range detection from LCSCProvider to ParameterDTO class
Improve numeric value detection by moving extra info to value_text

* ParameterDTO: Add micro unit prefix

* Bring $value_text2 to a defined state

* ParameterDTO: Don't overwrite $unit if it's not empty

* ParameterDTO: Don't overwrite $unit if it's not empty

* Correct some inaccuacies in comments

* Added tests and fixed certain edge cases in parsing parameters

* Added more tests for parameter parsing

---------

Co-authored-by: Jan Böhmer <mail@jan-boehmer.de>
2024-04-15 22:33:27 +02:00
Jan Böhmer
fdf64f9e9a
New Crowdin updates (#570)
* New translations security.en.xlf (Polish)

* New translations validators.en.xlf (Polish)

* New translations messages.en.xlf (English)

* New translations messages.en.xlf (Russian)

* New translations validators.en.xlf (Russian)

* New translations messages.en.xlf (Italian)
2024-04-15 21:33:58 +02:00
Henning Kleen
835b954140
fix import of parts containing shopping information (#594) 2024-04-15 21:32:04 +02:00
frank-f
9770ffa46b
LCSC: Follow first 'pdfUrl' link to get real datasheet URL (#582)
* Follow first 'pdfUrl' link to get real datasheet URL

* Fix @param

* Fix @param

* Remove User-Agent header
It's not needed - LCSC was just having some server troubles over the weekend

* Added comment explaining the json_decode in getRealDatasheetUrl

---------

Co-authored-by: Jan Böhmer <mail@jan-boehmer.de>
2024-04-03 12:38:20 +02:00
Jan Böhmer
da75cca97c Fixed missing/wrong group attributes on Parameters
This fixes issue #584
2024-04-02 22:41:30 +02:00
Jan Böhmer
d767e7472d Updated dependencies 2024-04-02 22:19:58 +02:00
Jan Böhmer
9b8d4c518a Updated dependencies 2024-03-23 20:45:09 +01:00
Jan Böhmer
96f5b2beab Bumped version to 1.11.3 2024-03-16 18:55:21 +01:00
Jan Böhmer
b9dc349d9a Merge remote-tracking branch 'origin/l10n_master' 2024-03-16 18:50:49 +01:00
Jan Böhmer
07d6e5c1d6 Updated dependencies 2024-03-16 18:45:06 +01:00
Jan Böhmer
488c8c5526 KiCAD API: Inherit the reference prefix from category if it was defined 2024-03-16 18:31:35 +01:00
Jan Böhmer
fb0abf3c1a New translations messages.en.xlf (English) 2024-03-16 01:20:29 +01:00
Jan Böhmer
a954712197
New Crowdin updates (#567)
* New translations messages.en.xlf (Czech)

* New translations validators.en.xlf (Czech)
2024-03-14 15:08:17 +01:00
au-ee
7c258d231b
install sudo to be able to do db migrations from the container's console (#566) 2024-03-12 11:03:33 +01:00
Jan Böhmer
c4bc1a4c51 Merge branch 'pr-564' 2024-03-11 22:24:26 +01:00
Jan Böhmer
0d9c86fcd3 Added brackets around if body 2024-03-11 22:24:21 +01:00
Frank Fenor
5454bb5b07
Avoid throwing an exception if Content-Disposition header doesn't exist or contains illegal things 2024-03-11 19:16:01 +01:00
Jan Böhmer
04d5cd741b Merge remote-tracking branch 'origin/frankenphp' 2024-03-11 11:04:45 +01:00
Jan Böhmer
3191028f74 Added an github action to build the frankenPHP docker image 2024-03-10 23:44:34 +01:00
Jan Böhmer
49f82127aa Do not copy the content of public/media to docker image 2024-03-10 20:49:33 +01:00
Jan Böhmer
28d86c8885 Show info about kernel runtime parameters on server info page 2024-03-10 20:32:43 +01:00
Jan Böhmer
1548b9f8c8 FrankenPHP dockerfile is now working 2024-03-10 20:22:47 +01:00
Jan Böhmer
7271c8c6f1 Restructured frankenphp structure 2024-03-10 19:50:21 +01:00
Jan Böhmer
aa0ec15e67 Allow to override the root user CLI check with COMPOSER_ALLOW_SUPERUSER 2024-03-10 19:30:14 +01:00
Jan Böhmer
7f78822a12 Added frankenphp runtime for symfony 2024-03-10 18:49:54 +01:00
Jan Böhmer
f8e92f98d0 Updated the dockerignore from the values of frankenphp 2024-03-10 18:09:56 +01:00
Jan Böhmer
8d816ab1ee Updated recipes to update docker related files 2024-03-10 18:08:22 +01:00
Jan Böhmer
19967bd42e Added files from frankenphp symfony skeleton 2024-03-10 18:05:21 +01:00
Jan Böhmer
d3a819613f Bumped version to 1.11.2 2024-03-10 01:40:04 +01:00
Jan Böhmer
e33f6a20bb Merge remote-tracking branch 'origin/l10n_master' 2024-03-10 01:39:21 +01:00
Jan Böhmer
02b736c92f New translations messages.en.xlf (German) 2024-03-10 01:31:46 +01:00
Jan Böhmer
e339c79c5a New translations messages.en.xlf (English) 2024-03-10 01:20:25 +01:00
Jan Böhmer
945fb9384e Remove preview image attachment during if the attachment got deleted during cloning
This fixes issue #559
2024-03-10 01:19:52 +01:00
Jan Böhmer
a792a140f7 Show a success flash message, after mass creation submit 2024-03-10 00:55:22 +01:00
Jan Böhmer
ed4728fdb1 Correcty handle already existing elements in mass creation
This fixes issue #543
2024-03-10 00:51:37 +01:00
Jan Böhmer
92a8107b9d Bumped to 1.11.2-dev 2024-03-10 00:20:05 +01:00
Jan Böhmer
1af8558cf4 Use position: fixed for footer in error pages to get better positioning in the popup details fram 2024-03-10 00:19:47 +01:00
Jan Böhmer
b781150ee9 Show the error page in a pop up in prod environment too 2024-03-10 00:12:54 +01:00
Jan Böhmer
59c4248efe Strip HTML tags from more LCSC fields
This should hopefully fix issue #553
2024-03-09 23:09:49 +01:00
Jan Böhmer
a5b101a0ea Fixed error, when retrieving prices in USD from LCSC
This fixes issue #552. It seems that LCSC changed their currency symbol for US-Dollar
2024-03-09 22:54:12 +01:00
Jan Böhmer
03854aa207 Updated dependencies 2024-03-09 21:42:43 +01:00
Jan Böhmer
c989be2719 Retrieve the part mass from mouser API if available 2024-03-09 21:34:05 +01:00
Jan Böhmer
d22e3ddcd7 New translations validators.en.xlf (German) 2024-03-09 21:20:19 +01:00
Jan Böhmer
040168b3d4 New translations validators.en.xlf (Italian) 2024-03-09 08:20:18 +01:00
Jan Böhmer
ac5c5555d5 New translations validators.en.xlf (English) 2024-03-09 00:30:36 +01:00
Jan Böhmer
1e6065f732 Show 64-bit recommendation in check requirements CLI and server info page 2024-03-09 00:23:18 +01:00
Jan Böhmer
cb7be460d7 Add 64-bit recommendation to installation docs 2024-03-09 00:13:40 +01:00
Jan Böhmer
206bcebdb7 Forbid users to select dates after 2038 on 32-bit systems to prevent errors caused by Year2038 bug
See discussion #548 and #549
2024-03-09 00:11:00 +01:00
Jan Böhmer
18c697f472 Document the available Part-DB specific filters and functions in twig mode 2024-03-07 13:23:58 +01:00
Jan Böhmer
4adb9a5266 Document available fields in twig mode
Related to #546
2024-03-07 13:11:17 +01:00
Jan Böhmer
a72a7ed1fc Explain the advantages of the twig mode 2024-03-07 12:46:30 +01:00
Jan Böhmer
838997b959 Updated the list of allowed object methods in twig label mode 2024-03-06 21:39:49 +01:00
Jan Böhmer
5736816b2b Document on how to use the placeholder function and placeholder twig filter in label twig mode
Related with #546
2024-03-06 21:22:47 +01:00
Jan Böhmer
38b5a84c4f Added some more useful variables to the twig label generator 2024-03-06 21:11:31 +01:00
Jan Böhmer
dff1ef04bf Added placeholders filter to utilize the placeholders in twig mode
Fixes #546
2024-03-06 21:00:49 +01:00
Jan Böhmer
757201cafa Allow access of twig sandbox to a few more extensions and functions 2024-03-06 20:21:07 +01:00
Jan Böhmer
1da3225e1d Renamed SandboxedTwigProvider to SandboxedTwig Factory 2024-03-06 20:08:35 +01:00
Jan Böhmer
a2cd5652d2 Updated the list of tags, filters and functions which are allowed inside the sandboxed twig 2024-03-06 20:03:12 +01:00
Jan Böhmer
dc7c13479c Add proper length constraint validations to all string mapped ORM fields, so they show a nice validation error, instead of a 500 error
Fixes issue #544
2024-03-06 19:46:11 +01:00
Jan Böhmer
113e5b3bcd Escape not only the pathes of FileDTO objects returned by info providers but the preview image url too.
This fixes the second issue in #521
2024-03-05 22:52:27 +01:00
Jan Böhmer
925f5c0ce0 Fixed phpstan bug 2024-03-04 22:42:24 +01:00
Jan Böhmer
0c53f5e186 Bumped to version 1.11.1 2024-03-04 22:38:43 +01:00
Jan Böhmer
2bcbe1d0be Made mouser price info parsing more flexible
Austrian mouser returned some other formatted string, which caused problems on the old method. This fixes issue #540
2024-03-04 22:38:15 +01:00
Jan Böhmer
0e68f0783f Assume that a mouser part is active, if mouser has parts instock even if it is marked as "new part"
Related to #540
2024-03-04 22:18:35 +01:00
Jan Böhmer
91e8711fdf Fixed problems with dynamically adding structural entities, when the arrows had spaces around them
Related to #538
2024-03-04 22:10:28 +01:00
Jan Böhmer
cf39e1f259 Do not split up pasted input on structrual entity selectors. This caused a part of the string to get split/lost
Fixes issue #538
2024-03-04 21:51:26 +01:00
Jan Böhmer
0cd631774b Fixed compatibility error with webauthn library which prevented 2FA via webauthn 2024-03-04 21:20:57 +01:00
Jan Böhmer
df53cf2540 Pass LCSC related env from the docker container to Part-DB
This fixes issue #539
2024-03-04 20:44:49 +01:00
Jan Böhmer
b734fc09f3 Release of version 1.11.0 2024-03-03 23:16:52 +01:00
Jan Böhmer
1fe5c56d02 Merge remote-tracking branch 'origin/l10n_master' 2024-03-03 23:08:10 +01:00
Jan Böhmer
af98842090 Added tests for the remaining API endpoints 2024-03-03 23:07:55 +01:00
Jan Böhmer
3d67ad870a Added tests for all API endpoints of Structural elements 2024-03-03 21:52:26 +01:00
Jan Böhmer
7b5ae70de3 Added tests for the Attachments API endpoint 2024-03-03 21:02:15 +01:00
Jan Böhmer
18c80f6b64 Use the route attribute from the correct namespace 2024-03-03 20:37:33 +01:00
Jan Böhmer
d49bb1f4b5 Removed unused import statements 2024-03-03 20:34:36 +01:00
Jan Böhmer
87533b6031 Fixed further inspection issues 2024-03-03 20:33:24 +01:00
Jan Böhmer
33e36f3d2b Fixed issue with EntityImported that was caused by the changes to PartNormalizer
We now have a possibility to skip API Platforms serializer subsystem
2024-03-03 20:24:24 +01:00
Jan Böhmer
42e604245c Fixed some inspection issues 2024-03-03 19:57:31 +01:00
Jan Böhmer
33475dca66 Updated dependencies 2024-03-03 19:51:47 +01:00
Jan Böhmer
7a90d3f281 Rewrote PartNormalizer so that it does not use ObjectNormalizer directly 2024-03-03 19:28:44 +01:00
Jan Böhmer
e53da5ad06 Added documentation on how to upload files and download URLs through the API on attachments 2024-03-03 19:04:25 +01:00
Jan Böhmer
f5bbb8bdd6 Merge branch 'upload_overhaul' 2024-03-03 18:55:58 +01:00
Jan Böhmer
d5b07bbaa3 Added additional type hints 2024-03-03 18:55:50 +01:00
Jan Böhmer
3585b8a56a Adapter attachment upload forms to the new system 2024-03-03 18:52:06 +01:00
Jan Böhmer
0c33059c4e Allow to upload files to attachments by passing a base64 encoded file 2024-03-03 18:40:35 +01:00
Jan Böhmer
0824e11570 Fixed infinite loop during deserialization on attachment PATCH operations 2024-03-03 17:58:25 +01:00
Jan Böhmer
0c4f5bcb3a New translations messages.en.xlf (German) 2024-03-03 16:50:19 +01:00
Jan Böhmer
aad8dcbadf New translations messages.en.xlf (Italian) 2024-03-03 11:03:22 +01:00
Jan Böhmer
193d5c8663 New translations messages.en.xlf (Czech) 2024-03-03 10:03:25 +01:00
Jan Böhmer
3734541743 Describe the new way to create attachments and parameters via API 2024-03-03 00:49:44 +01:00
Jan Böhmer
f3bea68011 Automatically detect the discriminator type of attachments and parameters based on the chosen element IRI
Related to issue #502
2024-03-02 23:15:00 +01:00
Jan Böhmer
e843286ea7 Allow to create parameters via the API 2024-03-02 21:49:16 +01:00
Jan Böhmer
e3d2012809 Use a own discriminator map for the Attachment API Platform discriminator 2024-03-02 21:45:16 +01:00
Jan Böhmer
ce768764cc Allow to create Attachments for all entity types using the API
This fixes issue #502
2024-03-02 21:39:30 +01:00
Jan Böhmer
16b3d58242 Implemented basic discriminator map for Attachment API access. Now we can properly create part attachments using a POST operation 2024-03-02 21:21:16 +01:00
Jan Böhmer
fad8f26eaa Added additional projects related filters to part table views 2024-03-02 19:18:55 +01:00
Jan Böhmer
04d1e84596 Added a filter to filter for parts which are used in a specific project
Related to issue #516
2024-03-02 19:00:30 +01:00
Jan Böhmer
934acca934 Added an column to part table view to show which projects a part uses.
Fixes issue #516
2024-03-02 18:48:31 +01:00
Jan Böhmer
639c98237a New translations messages.en.xlf (English) 2024-03-02 18:40:50 +01:00
Jan Böhmer
a6db67ab33 Fixed margins of the upload files button 2024-03-02 18:33:20 +01:00
Jan Böhmer
b92553f480 Added button to create attachments by uploading multiple files
This fixes issue #481
2024-03-02 18:26:50 +01:00
Jan Böhmer
f5d53dc305 Make the checkboxes of datatables look like regular bootstrap checkboxes 2024-03-02 01:28:15 +01:00
Jan Böhmer
b7ce91e2d8 Use the new system of datatables-select 2.0 where checkboxes are true checkbox fields 2024-03-02 01:04:28 +01:00
Jan Böhmer
4295141fb6 Updated dependencies 2024-03-01 21:42:42 +01:00
Jan Böhmer
973709c2f4 Updated dependencies 2024-02-29 23:46:39 +01:00
Jan Böhmer
a72a61091a Only add the amountSum select for part tables if it is really required 2024-02-29 23:35:05 +01:00
Jan Böhmer
c635637c00 Fixed problem that tables could not be sorted by manufacturers, categories, etc. 2024-02-29 23:13:17 +01:00
Jan Böhmer
77a5cadf51 Merge branch 'quicksearch' 2024-02-29 23:04:42 +01:00
Jan Böhmer
e0ef376cf0 Fixed various problems with the quicksearch 2024-02-29 23:00:21 +01:00
Jan Böhmer
04aeab7ea6 Renamed the quicksearch controller 2024-02-29 22:50:26 +01:00
Jan Böhmer
0dea26f67d Do not allow search if query is empty 2024-02-29 22:48:07 +01:00
Jan Böhmer
1815162907 Added a search bar to homepage 2024-02-29 22:46:19 +01:00
Jan Böhmer
e00988047c Added highlighting to search results 2024-02-29 22:20:30 +01:00
Jan Böhmer
faadd8e9a4 Improved layout for autocomplete dropdown 2024-02-29 21:53:28 +01:00
Jan Böhmer
409dcce3c7 Use correct translations for livesearch field in navbar 2024-02-29 20:39:27 +01:00
Jan Böhmer
746ba398a9 Fixed missing dropdown after some link navigations 2024-02-28 22:08:32 +01:00
Jan Böhmer
faa3bea3ab Allow to navigate to dropdown entries by keyboard 2024-02-28 22:06:54 +01:00
Jan Böhmer
f70f6c39ce Fixed error that algolia autocomplete input appeared multiple times after a link was clicked 2024-02-28 22:00:12 +01:00
Jan Böhmer
25a8642749 Make algolia autocomplete headers blue in bootstrap theme 2024-02-28 21:41:45 +01:00
Jan Böhmer
41e45599d4 Use a modified theme for algolia/autocomplete, which plays better with bootstrap 2024-02-28 21:38:11 +01:00
Jan Böhmer
293afc3998
New Crowdin updates (#532)
* New translations messages.en.xlf (Chinese Simplified)

* New translations messages.en.xlf (Chinese Simplified)
2024-02-28 13:00:59 +01:00
Jan Böhmer
c662dcfcd9 Started to make the autocomplete theme more bootstrap like 2024-02-27 23:39:49 +01:00
Jan Böhmer
e16aa31ddf Fixed z-index of autocomplete dropdown 2024-02-27 23:05:24 +01:00
Jan Böhmer
c87f809d12 Added header to part livesearch dropdown part results 2024-02-27 23:02:05 +01:00
Jan Böhmer
a3dcd1a0a8 Added recent searches to search 2024-02-27 00:39:38 +01:00
Jan Böhmer
4398b8698c Set proper darkmode attribute for algolia autocomplete 2024-02-27 00:33:48 +01:00
Jan Böhmer
18eb0467ee Integrated algolia autocomplete search into navbar 2024-02-27 00:28:17 +01:00
Jan Böhmer
60942c8254 Added very basic livesearch feauture using algolia autocomplete 2024-02-27 00:08:21 +01:00
Jan Böhmer
c7fac06b65 Updated dependencies 2024-02-25 19:44:34 +01:00
Jan Böhmer
2e5b2c8b7d Removed amountSum subquery from the detail query, as its result is not used anywhere 2024-02-25 01:46:35 +01:00
Jan Böhmer
fbd095ab50 Only add the joins to the parts table filter query if they are really required
This should improve the performance of the queries slightly
2024-02-25 01:40:25 +01:00
Jan Böhmer
b176cb1ae1 Use a much faster query to retrieve the total number of rows in datatables
This should increase performance on part tables
2024-02-25 00:58:26 +01:00
Jan Böhmer
2b65926865 Cache the sidebar trees to save some database calls 2024-02-25 00:48:15 +01:00
Jan Böhmer
a5d184baef Use rawurlencode instead of urlencode to sanatize URL-unsafe characters returned by the info providers. 2024-02-24 23:58:27 +01:00
Jan Böhmer
12e9497ccf Sanatize remaining invalid URL characters somehow returned by InfoProviders
This fixes issue #521
2024-02-24 23:55:31 +01:00
Jan Böhmer
4b7d200aa2 Retrieve category info from LCSC 2024-02-24 23:32:50 +01:00
Jan Böhmer
e937432d1e Fixed phpstan issue 2024-02-24 23:23:46 +01:00
Jan Böhmer
e1f1d10833 Added test for change on ParamterDTO done by PR #530 2024-02-24 22:51:02 +01:00
Jan Böhmer
05ec7ab665 Merge branch 'master' of https://github.com/Part-DB/Part-DB-symfony 2024-02-24 22:49:05 +01:00
Jan Böhmer
dbd841a723 Updated dependencies 2024-02-24 22:48:52 +01:00
frank-f
e8bc93f67a
Fix RegEx to handle negative values and Ohms without prefix (#530)
* Fix RegEx to include negative values

* Update RegEx to handle Ω without prefix

* Update RegEx to include %

* Handle plus/minus values as range

* Fix copy&paste error

* Change minimum value to negative

* Escape decimal point and add slash to valid unit characters to be able to pick up for example "ppm/°C"

* Skip empty values
2024-02-24 22:48:38 +01:00
Jan Böhmer
0d6ab793ce Fixed typos in README.md 2024-02-23 14:59:28 +01:00
Jan Böhmer
eab4d6f600 Added documentation about LCSC provider 2024-02-23 14:55:56 +01:00
Jan Böhmer
861c0174df Fixed more typos and grammar issues in docs 2024-02-23 14:26:17 +01:00
Jan Böhmer
5d68922f2e Fixed some typos and grammar issues in documentation 2024-02-23 13:56:23 +01:00
Cody Jacob
20ee16e3c0
Update eda_integration.md (#528)
spelling mistakes.
--grammerly was used
2024-02-23 13:13:15 +01:00
Jan Böhmer
20be83c345 Allow to configure the currency to get prices in for the LCSCProvider 2024-02-22 23:57:57 +01:00
Jan Böhmer
015b69e601 Merge branch 'lcsc-master' 2024-02-22 23:33:46 +01:00
Jan Böhmer
95ef97fcc2 Added possibility to enable/disable the LCSC provider 2024-02-22 23:32:12 +01:00
Jan Böhmer
d600cb4b9a Improved parsing of parameters. Values with unit and ranges get now properly parsed into the Part-DB structures 2024-02-22 23:22:52 +01:00
Jan Böhmer
0bbfaf9893 Improved typing and formatting of LCSC provider slightly 2024-02-22 22:41:09 +01:00
Nexrem
e3e562a154 Add LCSC Info Provider using their public API 2024-02-22 15:32:33 +01:00
Jan Böhmer
49034fabf2 Added phpstan template annotations to Voters to fix phpstan issues 2024-02-19 00:01:16 +01:00
Jan Böhmer
e9d03a0c95 Fixed "Loading..." message on datatables with no content 2024-02-18 20:31:31 +01:00
Jan Böhmer
d7e68605c9 Fixed row coloring issue with the new datatables 2024-02-18 20:10:52 +01:00
Jan Böhmer
51900b4b62 Fixed visual bugs introduced by the datatables upgrade 2024-02-18 19:58:13 +01:00
Jan Böhmer
67a1d06f37 Updated datatables version 2024-02-18 19:32:54 +01:00
Jan Böhmer
395af17d96 Updated dependencies 2024-02-18 19:25:52 +01:00
Jan Böhmer
88f4feaa81 Revert "Updated dependencies"
This reverts commit 4d4570701b.
2024-02-15 11:41:21 +01:00
Jan Böhmer
b6b2e44231 Dont prefetch settings page in navbar with turbos instaclick behavior as this page might not be accessible without additional authentication 2024-02-14 22:48:36 +01:00
Jan Böhmer
4d4570701b Updated dependencies 2024-02-14 22:46:01 +01:00
Jan Böhmer
178a825e93
New Crowdin updates (#517)
* New translations messages.en.xlf (Russian)

* New translations validators.en.xlf (Russian)

* New translations security.en.xlf (Russian)
2024-02-12 18:37:42 +01:00
Jan Böhmer
f67ce2b0a3 Updated unifont to latest version 2024-02-08 22:48:50 +01:00
Jan Böhmer
10918ccb0d Merge branch 'turbo-upgrade' 2024-02-08 22:20:50 +01:00
Jan Böhmer
698fadc00c Upgraded markedjs package 2024-02-08 22:20:44 +01:00
Jan Böhmer
b16760988d Updated CKEDITOR to version 41 2024-02-08 22:17:00 +01:00
Jan Böhmer
7e3e1e2705 Use new turbo morph features 2024-02-08 22:05:57 +01:00
Jan Böhmer
e5e039a1ca Use hotwired/turbo 8 2024-02-08 22:01:05 +01:00
Jan Böhmer
43d8c3c208 Bumped version to 1.10.7 2024-02-06 22:50:08 +01:00
Jan Böhmer
3cc1fb40f0 Fixed problem that no datastructures with an parent element could be created/edited via API
This fixes issue #512.
The error was introduced when trying to allow the modification of attachments/parameters throught the parent element. We need a seperate write scope to the element, or we end up with an infinite loop.
2024-02-06 22:42:25 +01:00
Jan Böhmer
fea8109789 Fixed permission denied error, when accessing a user info page 2024-02-06 22:21:43 +01:00
Jan Böhmer
ff2aafabbd Fixed permission denied error on log details page for BOMEntries 2024-02-06 22:18:09 +01:00
Jan Böhmer
e27b15691a Fixed permission denied error, when trying to access the log details page of a LabelProfile 2024-02-06 22:09:02 +01:00
Jan Böhmer
47ddcca065 Fixed exception on label profile admin, if the label profile had an preview attachment 2024-02-06 21:59:53 +01:00
Jan Böhmer
0a7a7c979c Fixed problem with navbar height if search button has two words text 2024-02-06 21:53:13 +01:00
Jan Böhmer
b37ae97673 Added chinese to navbar language picker 2024-02-06 21:50:07 +01:00
Jan Böhmer
fa9e571b41 Merge branch 'dependabot/github_actions/codecov/codecov-action-4' 2024-02-06 21:47:30 +01:00
Jan Böhmer
f0fd3d8c1d Updated dependencies 2024-02-06 21:47:18 +01:00
dependabot[bot]
a1bdfab80f
Bump codecov/codecov-action from 3 to 4 (#509)
Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 3 to 4.
- [Release notes](https://github.com/codecov/codecov-action/releases)
- [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/codecov/codecov-action/compare/v3...v4)

---
updated-dependencies:
- dependency-name: codecov/codecov-action
  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>
2024-02-06 21:44:36 +01:00
Jan Böhmer
0d5b7a0711
New translations messages.en.xlf (Chinese Simplified) (#511) 2024-02-06 21:42:33 +01:00
Jan Böhmer
852107f7f6
New Crowdin updates (#510)
* New translations messages.en.xlf (Chinese Simplified)

* New translations validators.en.xlf (Chinese Simplified)

* New translations security.en.xlf (Chinese Simplified)

* New translations messages.en.xlf (Chinese Simplified)

* New translations security.en.xlf (Chinese Simplified)
2024-02-06 09:41:15 +01:00
dependabot[bot]
77b017381a
Bump codecov/codecov-action from 3 to 4
Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 3 to 4.
- [Release notes](https://github.com/codecov/codecov-action/releases)
- [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/codecov/codecov-action/compare/v3...v4)

---
updated-dependencies:
- dependency-name: codecov/codecov-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-05 17:15:54 +00:00
Jan Böhmer
75ce9c4370 Fixed problem with multi escaping in title tag
This should fix issue #505
2024-02-03 00:50:38 +01:00
Jan Böhmer
a8d12c9c4c Updated dependencies 2024-02-03 00:40:37 +01:00
Jan Böhmer
3294ba5964 Mention czech and danish translation in README 2024-02-02 23:44:06 +01:00
Jan Böhmer
2bd3a6a745 Updated bs-treeview to 1.0.6 where the issue that child nodes of already expanded nodes dont get expanded on an select all
This fixes issue #506
2024-02-02 23:42:36 +01:00
Jan Böhmer
0d3c670f9d Release version 1.10.6 2024-01-29 21:30:18 +01:00
Jan Böhmer
998b3ed075 Fixed typo in german translation 2024-01-29 21:29:14 +01:00
Jan Böhmer
a390b1e2a0 Upgraded dependencies 2024-01-29 21:28:21 +01:00
Jan Böhmer
fb493cc837 Fixed export of entities, if their name contained slash or other reserved charcters 2024-01-29 21:25:30 +01:00
Jan Böhmer
2f17d5f3f5 Fixed problem that trying to request nl language version of a page caused an exception
If the translation files dont contain any content, they are seen as invalid and cause this error. Therefore delete it.
2024-01-29 21:12:01 +01:00
Jan Böhmer
3a2f3ce1cc Fix problem with cache key generation if the username contained an @ sign or any other special character
This fixes issue #504
2024-01-29 21:08:25 +01:00
Jan Böhmer
1b5eea4750 Register the unselect handler on turbo:load instead of visit, to avoid problems that the newly clicked treeview node gets unselected too. 2024-01-28 21:57:42 +01:00
Jan Böhmer
cb9e90ddc9 Load the link again when clicking a already selected treeview node, instead of just unselecting it 2024-01-28 21:48:32 +01:00
Jan Böhmer
03c7a71311 Release version 1.10.5 2024-01-28 21:20:05 +01:00
Jan Böhmer
e5b9ce9c25 Describe the creation of parameters/attachments workaround in API docs
Related to issue #502
2024-01-28 20:59:13 +01:00
Jan Böhmer
c8cde94ee3 Fixed problem that attachment API responses, did not contain an @id and @context attribute 2024-01-28 20:26:03 +01:00
Jan Böhmer
aad62f2599 Disable POST operations for Attachment and AbstractParameter groups for now, as they can not work properly
As they work on abstract classes, they can not be initialized directly currently and you need to create them via a PATCH operation on their owning elements.
2024-01-28 19:53:33 +01:00
Jan Böhmer
7ae0fad356 Allow to create attachments and parameters via PATCH operations on their owning elemens as direct POST operations are not possible yet
This partly fixes issue #502
2024-01-28 19:50:59 +01:00
Jan Böhmer
3548f12deb Added info on how to execute commands inside docker container to docs 2024-01-28 18:30:16 +01:00
Jan Böhmer
a161e3a520 Load the link again when clicking a already selected treeview node, instead of just unselecting it
This fixes the somehow unintuitive behavior described in issue #458
2024-01-27 22:22:07 +01:00
Jan Böhmer
8018e8687b Unselect a treeview node, if the referenced page changes
Related to issue #458
2024-01-27 21:12:21 +01:00
Jan Böhmer
e6ae73db00 Merge remote-tracking branch 'origin/l10n_master' 2024-01-27 20:33:31 +01:00
Jan Böhmer
d720cde693 Upgraded dependencies 2024-01-27 20:33:27 +01:00
Jan Böhmer
d111905ba0 Added hint to docs, that the mouser API dont provide all infos availble
See issue #503
2024-01-27 20:31:12 +01:00
Jan Böhmer
4b41e932d2 New translations messages.en.xlf (Czech) 2024-01-26 09:44:31 +01:00
Jan Böhmer
ee3ad403fb Fixed exception if no content type or accept header are given 2024-01-26 00:36:14 +01:00
Jan Böhmer
2a7c131786 New translations messages.en.xlf (German) 2024-01-26 00:28:58 +01:00
Jan Böhmer
2861f4fdb8 New translations messages.en.xlf (English) 2024-01-26 00:16:07 +01:00
Jan Böhmer
6f24e7f077 Fixed phpunit tests caused by typo in Autowire attribute
This caused the whole thing to behave very very weirdly
2024-01-26 00:12:37 +01:00
Jan Böhmer
08e7e3f2bf Fixed phpstan issue 2024-01-25 23:41:43 +01:00
Jan Böhmer
f0519ae0b3 Return a 401 message with an JSON encoded body, if no authentication header is passed for an API request.
Also for browser requests, a flash message is shown in that case, prompting the user to authenticate.

This follows a suggestion from issue #494
2024-01-25 23:35:42 +01:00
Jan Böhmer
631c364179 Added option to redirect https requests to http via Part-DB
This is especially useful for the heroku demo instance, where the webserver can not do the automatic redirect
2024-01-25 22:58:52 +01:00
Jan Böhmer
e8d670971e Merge remote-tracking branch 'origin/dependabot/github_actions/actions/cache-4' 2024-01-25 22:19:32 +01:00
Jan Böhmer
fa43ae91cb Merge remote-tracking branch 'origin/l10n_master' 2024-01-25 22:19:26 +01:00
Jan Böhmer
e8eb102feb Updated dependencies 2024-01-25 22:19:06 +01:00
Jan Böhmer
e4634ecc2c Fixed wrong header in API authentication docs
This fix issue #494
2024-01-25 13:22:01 +01:00
Jan Böhmer
0307a50890 New translations messages.en.xlf (Czech) 2024-01-24 20:01:38 +01:00
Jan Böhmer
af1852bb3f
We are in development of 1.10.5 now 2024-01-24 11:57:17 +01:00
Jan Böhmer
046803b9c4
Added danish to prefered languages 2024-01-24 11:56:56 +01:00
Jan Böhmer
daabb9f55e
New Crowdin updates (#491)
* New translations messages.en.xlf (Danish)

* New translations messages.en.xlf (Danish)

* New translations security.en.xlf (Danish)

* New translations messages.en.xlf (Danish)

* New translations messages.en.xlf (Danish)
2024-01-24 11:53:55 +01:00
dependabot[bot]
b177db82f5
Bump actions/cache from 3 to 4
Bumps [actions/cache](https://github.com/actions/cache) from 3 to 4.
- [Release notes](https://github.com/actions/cache/releases)
- [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md)
- [Commits](https://github.com/actions/cache/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/cache
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-22 17:15:29 +00:00
Jan Böhmer
6b2ebd2434
New Crowdin updates (#485)
* New translations messages.en.xlf (Czech)

* New translations messages.en.xlf (Czech)

* New translations messages.en.xlf (Danish)

* New translations messages.en.xlf (Danish)

* New translations messages.en.xlf (Danish)

* New translations messages.en.xlf (Danish)

* New translations messages.en.xlf (Danish)

* New translations messages.en.xlf (Danish)

* New translations messages.en.xlf (Czech)

* New translations messages.en.xlf (Danish)

* New translations messages.en.xlf (Danish)
2024-01-22 11:52:37 +01:00
Jan Böhmer
ef6dd0febc Bumped version to 1.10.4 2024-01-16 23:06:20 +01:00
Jan Böhmer
2cb8cf72ba Merge remote-tracking branch 'origin/l10n_master' 2024-01-16 23:05:53 +01:00
Jan Böhmer
7430ecd7a6 Invalidate part related cache tags properly, if a part is created, changed or removed
This fixes the issue with KiCAD integration described in issue #483
2024-01-16 22:49:01 +01:00
Jan Böhmer
dcf85f9d5e Add hint about bad unicode treatment in sqlite to dabase choosing guide
Related to issue #465
2024-01-16 22:10:29 +01:00
Jan Böhmer
427a31f1b6 New translations messages.en.xlf (Czech) 2024-01-15 23:30:23 +01:00
Jan Böhmer
be4268c6cd New translations messages.en.xlf (Czech) 2024-01-15 22:32:00 +01:00
Jan Böhmer
a1660cd888 Bumped version to 1.10.3 2024-01-15 20:46:07 +01:00
Jan Böhmer
4645227a40 Upgraded dependencies 2024-01-15 20:44:51 +01:00
Jan Böhmer
1da2b9eecb Fixed javascript error caused by CKEDITOR
This was not really a problem, just annoying. But now it is fixed.
Fixes issue #457
2024-01-15 20:39:27 +01:00
Jan Böhmer
f83d4103a6 Use a own marked instance for the MarkdownController instead of the global one
This prevents from configuring plugins multiple times which can lead to a heap overflow.
This fixes issue #478
2024-01-15 20:19:10 +01:00
Jan Böhmer
9e28d39095 Upgraded markedjs 2024-01-15 20:05:16 +01:00
Jan Böhmer
6d838c41ce Merge remote-tracking branch 'origin/l10n_master' 2024-01-15 20:00:29 +01:00
Jan Böhmer
af0931a86e New translations messages.en.xlf (Czech) 2024-01-15 11:40:38 +01:00
Jan Böhmer
a4117d024e New translations messages.en.xlf (Czech) 2024-01-15 10:41:53 +01:00
Jan Böhmer
6b122d6040 New translations messages.en.xlf (Czech) 2024-01-15 09:41:58 +01:00
Jan Böhmer
6e66a2bf7a New translations messages.en.xlf (Danish) 2024-01-14 22:41:43 +01:00
Jan Böhmer
37edb73b3e New translations messages.en.xlf (Danish) 2024-01-14 21:41:53 +01:00
Jan Böhmer
a3b5243ffc Install mysqldump in docker, so the builtin backup solution can be used
Fixes issue #479
2024-01-14 21:31:37 +01:00
Jan Böhmer
b12a2c6aab Added czech to language picker in navbar 2024-01-14 20:55:51 +01:00
Jan Böhmer
1379f896c9 Merge remote-tracking branch 'origin/l10n_master' 2024-01-14 20:54:52 +01:00
Jan Böhmer
0a31714717 Upgraded dependencies 2024-01-14 20:54:35 +01:00
Jan Böhmer
5f8d822e8a New translations messages.en.xlf (Czech) 2024-01-14 20:40:18 +01:00
Jan Böhmer
ff6624b7b3 New translations messages.en.xlf (Czech) 2024-01-14 17:30:21 +01:00
Jan Böhmer
645837dd67 New translations validators.en.xlf (Czech) 2024-01-14 16:30:19 +01:00
Jan Böhmer
eac8f4cd37 New translations messages.en.xlf (Czech) 2024-01-14 16:30:18 +01:00
Jan Böhmer
7e4e9138d3 New translations messages.en.xlf (Czech) 2024-01-14 15:30:21 +01:00
Jan Böhmer
ede7fa3149 New translations messages.en.xlf (Czech) 2024-01-14 12:30:17 +01:00
Jan Böhmer
aa1405a64b New translations messages.en.xlf (Czech) 2024-01-14 11:31:54 +01:00
Jan Böhmer
507c2640a9 New translations messages.en.xlf (Danish) 2024-01-14 01:40:19 +01:00
Jan Böhmer
f6e403d552 New translations messages.en.xlf (Danish) 2024-01-14 00:40:19 +01:00
Jan Böhmer
c1fe3b9d97 New translations messages.en.xlf (Danish) 2024-01-13 20:10:21 +01:00
Jan Böhmer
c85882a0b1 New translations messages.en.xlf (Danish) 2024-01-13 19:10:17 +01:00
Jan Böhmer
21203fc527 New translations messages.en.xlf (Danish) 2024-01-13 18:10:18 +01:00
Jan Böhmer
69cfe51db0 New translations messages.en.xlf (Danish) 2024-01-13 17:10:17 +01:00
Jan Böhmer
9a2133d176 New translations messages.en.xlf (Danish) 2024-01-13 14:21:52 +01:00
Jan Böhmer
f2861fbcf0 New translations messages.en.xlf (Danish) 2024-01-13 13:21:59 +01:00
Jan Böhmer
83d7de0a22
New Crowdin updates (#475)
* New translations messages.en.xlf (Czech)

* New translations messages.en.xlf (Czech)
2024-01-12 10:59:08 +01:00
Jan Böhmer
d80e9bab12
New Crowdin updates (#474)
* New translations messages.en.xlf (Danish)

* New translations validators.en.xlf (Danish)

* New translations security.en.xlf (Danish)

* New translations messages.en.xlf (Danish)

* New translations validators.en.xlf (Danish)

* New translations messages.en.xlf (Danish)

* New translations messages.en.xlf (Danish)

* New translations messages.en.xlf (Czech)

* New translations validators.en.xlf (Czech)

* New translations security.en.xlf (Czech)

* New translations messages.en.xlf (Danish)

* New translations messages.en.xlf (Czech)

* New translations validators.en.xlf (Czech)

* New translations security.en.xlf (Czech)

* New translations messages.en.xlf (Czech)

* New translations messages.en.xlf (Czech)

* New translations messages.en.xlf (Czech)

* New translations messages.en.xlf (Dutch)

* New translations messages.en.xlf (Dutch)
2024-01-12 10:01:44 +01:00
Jan Böhmer
d9f58b935a Fixed some issues when importing parameters from partkeepr
Before values were not properly imported, if there was not a normalized version yet and units were not correctly imported
2024-01-11 00:02:32 +01:00
Jan Böhmer
301ecf6c95 Do not import prices with zero price as pricedetails during partkeepr import
These are useless placeholders by partkeepr
2024-01-10 23:40:06 +01:00
Jan Böhmer
be1e17b3be Merge remote-tracking branch 'origin/l10n_master' 2024-01-10 23:19:29 +01:00
Jan Böhmer
86f19d6b25 Updated dependencies 2024-01-10 23:19:16 +01:00
Jan Böhmer
e2146332dc Fixed problems with invalid dates during PartKeepr import with MySQL
See issue #473
2024-01-10 23:18:02 +01:00
Jan Böhmer
e283e2db57 New translations messages.en.xlf (Danish) 2024-01-10 22:50:23 +01:00
Jan Böhmer
22377daa8d New translations messages.en.xlf (Danish) 2024-01-10 21:50:24 +01:00
Jan Böhmer
498e0ae2c7 New translations messages.en.xlf (Russian) 2024-01-10 19:10:49 +01:00
Jan Böhmer
12ea949739 New translations messages.en.xlf (Russian) 2024-01-10 18:10:29 +01:00
Jan Böhmer
436e73a2e9 New translations messages.en.xlf (Russian) 2024-01-10 15:05:35 +01:00
Jan Böhmer
1b65dcfcf1 New translations messages.en.xlf (Russian) 2024-01-10 14:01:39 +01:00
Jan Böhmer
8095f1b995 New translations security.en.xlf (Danish) 2024-01-10 00:12:25 +01:00
Jan Böhmer
a20a3e65fa New translations validators.en.xlf (Danish) 2024-01-10 00:12:25 +01:00
Jan Böhmer
e8a047a28f New translations messages.en.xlf (Danish) 2024-01-10 00:12:24 +01:00
Jan Böhmer
d9ba631173 New translations messages.en.xlf (Russian) 2024-01-09 20:44:32 +01:00
Jan Böhmer
8dc0e014ba New translations messages.en.xlf (Russian) 2024-01-09 19:41:53 +01:00
Jan Böhmer
530476f917 New translations messages.en.xlf (Russian) 2024-01-08 13:30:36 +01:00
Jan Böhmer
8634ff26a7 New translations messages.en.xlf (Russian) 2024-01-08 12:31:58 +01:00
Jan Böhmer
c8f3acaa9d New translations messages.en.xlf (Russian) 2024-01-07 23:00:19 +01:00
Jan Böhmer
74ec7d4c9c New translations messages.en.xlf (Russian) 2024-01-07 22:00:21 +01:00
Jan Böhmer
72c21313dc New translations messages.en.xlf (Russian) 2024-01-07 21:00:18 +01:00
Jan Böhmer
b7660bc778 New translations messages.en.xlf (Russian) 2024-01-07 13:30:27 +01:00
Jan Böhmer
22b197012b New translations messages.en.xlf (Russian) 2024-01-07 12:30:17 +01:00
Jan Böhmer
78bd858ebb Bumped version to 1.10.2 2024-01-06 15:57:59 +01:00
Jan Böhmer
19819454fa Dont split up links when extracting parameters from notes and description
This partly fixes issue #469
2024-01-06 15:14:07 +01:00
Jan Böhmer
26a4b57cfb Fixed tests related to PartNormalizer 2024-01-06 15:01:50 +01:00
Jan Böhmer
f3729ef9db Merge remote-tracking branch 'origin/l10n_master' 2024-01-06 01:07:20 +01:00
Jan Böhmer
ab09d319e9 Fixed wrong path for assets managed by webpack and loaded via twig asset() function.
This had also the effect that 2FA via webauthn were not working, as the request the invalid path resetted the webauthn request saved in session.
2024-01-06 01:06:56 +01:00
Jan Böhmer
df23ba07ba Fixed excpetion that no IRI could be generated if a new Part was created via POST operation via API
This was because the objectSerializer in PartNormalizer messed up the JSONLD IRI generation of the paramaters property. It tried to generate this IRI via the Part ressource class, which is not possible
2024-01-05 23:38:49 +01:00
Jan Böhmer
d20b668e87 Decorate error handler of API platform to show a better error message, if a user tries to cascade persist a new entity through an API operation 2024-01-05 23:10:46 +01:00
Jan Böhmer
f0646597fe Updated dependencies 2024-01-05 22:33:00 +01:00
Jan Böhmer
6d783fd581 New translations messages.en.xlf (Dutch) 2024-01-04 10:00:32 +01:00
Jan Böhmer
14fbf18733 New translations messages.en.xlf (Dutch) 2024-01-04 09:00:23 +01:00
Jan Böhmer
e35c7c496f New translations security.en.xlf (Dutch) 2024-01-03 16:00:42 +01:00
Jan Böhmer
a218b8fdd6 New translations validators.en.xlf (Dutch) 2024-01-03 16:00:41 +01:00
Jan Böhmer
1491672cf8 New translations messages.en.xlf (Dutch) 2024-01-03 16:00:40 +01:00
Jan Böhmer
f9894ffff7 New translations messages.en.xlf (Italian) 2023-12-30 19:00:21 +01:00
Jan Böhmer
7b565817d6 Disable update checking for tests 2023-12-24 15:50:42 +01:00
Jan Böhmer
a03b2ecf73 Use sqlite database for testing by default 2023-12-24 15:27:05 +01:00
Jan Böhmer
dd2f74e19e Merge branch 'master' of github.com:Part-DB/Part-DB-server 2023-12-24 15:21:04 +01:00
Jan Böhmer
c1dcaf926a Updated dependencies 2023-12-24 15:20:52 +01:00
dependabot[bot]
c116db9593
Bump actions/upload-artifact from 3 to 4 (#461)
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 3 to 4.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  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>
2023-12-24 15:03:39 +01:00
Jan Böhmer
1b92b9f171 Bump to 1.10.1 release 2023-12-12 22:42:53 +01:00
Jan Böhmer
17e79207f0 Suppress static analysis issue 2023-12-12 22:42:34 +01:00
Jan Böhmer
4d187741e0 Added the right copyright header to the foundation emails CSS asset 2023-12-12 22:39:44 +01:00
Jan Böhmer
85c3031fcd Upgraded dependencies 2023-12-12 22:30:45 +01:00
Jan Böhmer
a3e012d754 Added an event listener for console commands which shows a warning if the console is called as root or as wrong user
The idea is to prevent permission issues, by accidential calling the console wrong.
2023-12-12 22:23:19 +01:00
Jan Böhmer
60f8e754c2 Use the DEFAULT_URI setting for SAML base url instead of auto determining it.
This should fix issue #436
2023-12-10 22:52:59 +01:00
Jan Böhmer
3e13a0d9d9 Disable update checking in tests to prevent false-negatives in github actions caused by github api blocking 2023-12-10 22:52:01 +01:00
Jan Böhmer
cd91dc8b5a Fixed wrong path for event log datatables, when accessing via a prefixed reverse proxy 2023-12-10 21:40:49 +01:00
Jan Böhmer
bcaf96ed59 Use a svg file as default user avatar instead of SVG. Also changed path generation logic
This should also fix the path issue described in issue #446
2023-12-10 21:25:40 +01:00
Jan Böhmer
e2437d4c33 Updated dependencies 2023-12-10 00:40:39 +01:00
Jan Böhmer
3798217abc Use PDO constant instead of magic number in SetSQLModeMiddleware 2023-12-10 00:37:58 +01:00
Jan Böhmer
57423436ce Added options to use MySQL connection via SSL 2023-12-10 00:36:29 +01:00
Jan Böhmer
e824f6376a Mention update capability of part info providers in docs 2023-12-07 16:27:25 +01:00
709 changed files with 102572 additions and 19286 deletions

View file

@ -0,0 +1,55 @@
{
{$CADDY_GLOBAL_OPTIONS}
frankenphp {
{$FRANKENPHP_CONFIG}
}
# https://caddyserver.com/docs/caddyfile/directives#sorting-algorithm
order mercure after encode
order vulcain after reverse_proxy
order php_server before file_server
}
{$CADDY_EXTRA_CONFIG}
{$SERVER_NAME:localhost} {
log {
# Redact the authorization query parameter that can be set by Mercure
format filter {
wrap console
fields {
uri query {
replace authorization REDACTED
}
}
}
}
root * /app/public
encode zstd br gzip
mercure {
# Transport to use (default to Bolt)
transport_url {$MERCURE_TRANSPORT_URL:bolt:///data/mercure.db}
# Publisher JWT key
publisher_jwt {env.MERCURE_PUBLISHER_JWT_KEY} {env.MERCURE_PUBLISHER_JWT_ALG}
# Subscriber JWT key
subscriber_jwt {env.MERCURE_SUBSCRIBER_JWT_KEY} {env.MERCURE_SUBSCRIBER_JWT_ALG}
# Allow anonymous subscribers (double-check that it's what you want)
anonymous
# Enable the subscription API (double-check that it's what you want)
subscriptions
# Extra directives
{$MERCURE_EXTRA_DIRECTIVES}
}
vulcain
{$CADDY_SERVER_EXTRA_DIRECTIVES}
# Disable Topics tracking if not enabled explicitly: https://github.com/jkarlin/topics
header ?Permissions-Policy "browsing-topics=()"
php_server
}

View file

@ -0,0 +1,5 @@
; See https://docs.docker.com/desktop/networking/#i-want-to-connect-from-a-container-to-a-service-on-the-host
; See https://github.com/docker/for-linux/issues/264
; The `client_host` below may optionally be replaced with `discover_client_host=yes`
; Add `start_with_request=yes` to start debug session on each request
xdebug.client_host = host.docker.internal

View file

@ -0,0 +1,18 @@
expose_php = 0
date.timezone = UTC
apc.enable_cli = 1
session.use_strict_mode = 1
zend.detect_unicode = 0
; https://symfony.com/doc/current/performance.html
realpath_cache_size = 4096K
realpath_cache_ttl = 600
opcache.interned_strings_buffer = 16
opcache.max_accelerated_files = 20000
opcache.memory_consumption = 256
opcache.enable_file_override = 1
memory_limit = 256M
upload_max_filesize=256M
post_max_size=300M

View file

@ -0,0 +1,2 @@
opcache.preload_user = root
opcache.preload = /app/config/preload.php

View file

@ -0,0 +1,60 @@
#!/bin/sh
set -e
if [ "$1" = 'frankenphp' ] || [ "$1" = 'php' ] || [ "$1" = 'bin/console' ]; then
# Install the project the first time PHP is started
# After the installation, the following block can be deleted
if [ ! -f composer.json ]; then
rm -Rf tmp/
composer create-project "symfony/skeleton $SYMFONY_VERSION" tmp --stability="$STABILITY" --prefer-dist --no-progress --no-interaction --no-install
cd tmp
cp -Rp . ..
cd -
rm -Rf tmp/
composer require "php:>=$PHP_VERSION" runtime/frankenphp-symfony
composer config --json extra.symfony.docker 'true'
if grep -q ^DATABASE_URL= .env; then
echo "To finish the installation please press Ctrl+C to stop Docker Compose and run: docker compose up --build -d --wait"
sleep infinity
fi
fi
if [ -z "$(ls -A 'vendor/' 2>/dev/null)" ]; then
composer install --prefer-dist --no-progress --no-interaction
fi
if grep -q ^DATABASE_URL= .env; then
echo "Waiting for database to be ready..."
ATTEMPTS_LEFT_TO_REACH_DATABASE=60
until [ $ATTEMPTS_LEFT_TO_REACH_DATABASE -eq 0 ] || DATABASE_ERROR=$(php bin/console dbal:run-sql -q "SELECT 1" 2>&1); do
if [ $? -eq 255 ]; then
# If the Doctrine command exits with 255, an unrecoverable error occurred
ATTEMPTS_LEFT_TO_REACH_DATABASE=0
break
fi
sleep 1
ATTEMPTS_LEFT_TO_REACH_DATABASE=$((ATTEMPTS_LEFT_TO_REACH_DATABASE - 1))
echo "Still waiting for database to be ready... Or maybe the database is not reachable. $ATTEMPTS_LEFT_TO_REACH_DATABASE attempts left."
done
if [ $ATTEMPTS_LEFT_TO_REACH_DATABASE -eq 0 ]; then
echo "The database is not up or not reachable:"
echo "$DATABASE_ERROR"
exit 1
else
echo "The database is now ready and reachable"
fi
if [ "$( find ./migrations -iname '*.php' -print -quit )" ]; then
php bin/console doctrine:migrations:migrate --no-interaction
fi
fi
setfacl -R -m u:www-data:rwX -m u:"$(whoami)":rwX var
setfacl -dR -m u:www-data:rwX -m u:"$(whoami)":rwX var
fi
exec docker-php-entrypoint "$@"

View file

@ -0,0 +1,4 @@
worker {
file ./public/index.php
env APP_RUNTIME Runtime\FrankenPhpSymfony\Runtime
}

View file

@ -39,8 +39,50 @@ if [ -d /var/www/html/var/db ]; then
fi fi
fi fi
# Start PHP-FPM # Start PHP-FPM (the PHP_VERSION is replaced by the configured version in the Dockerfile)
service php8.1-fpm start service phpPHP_VERSION-fpm start
# Run migrations if automigration is enabled via env variable DB_AUTOMIGRATE
if [ "$DB_AUTOMIGRATE" = "true" ]; then
echo "Waiting for database to be ready..."
ATTEMPTS_LEFT_TO_REACH_DATABASE=60
until [ $ATTEMPTS_LEFT_TO_REACH_DATABASE -eq 0 ] || DATABASE_ERROR=$(sudo -E -u www-data php bin/console dbal:run-sql -q "SELECT 1" 2>&1); do
if [ $? -eq 255 ]; then
# If the Doctrine command exits with 255, an unrecoverable error occurred
ATTEMPTS_LEFT_TO_REACH_DATABASE=0
break
fi
sleep 1
ATTEMPTS_LEFT_TO_REACH_DATABASE=$((ATTEMPTS_LEFT_TO_REACH_DATABASE - 1))
echo "Still waiting for database to be ready... Or maybe the database is not reachable. $ATTEMPTS_LEFT_TO_REACH_DATABASE attempts left."
done
if [ $ATTEMPTS_LEFT_TO_REACH_DATABASE -eq 0 ]; then
echo "The database is not up or not reachable:"
echo "$DATABASE_ERROR"
exit 1
else
echo "The database is now ready and reachable"
fi
# Check if there are any available migrations to do, by executing doctrine:migrations:up-to-date
# and checking if the exit code is 0 (up to date) or 1 (not up to date)
if sudo -E -u www-data php bin/console doctrine:migrations:up-to-date --no-interaction; then
echo "Database is up to date, no migrations necessary."
else
echo "Migrations available..."
echo "Do backup of database..."
sudo -E -u www-data mkdir -p /var/www/html/uploads/.automigration-backup/
# Backup the database
sudo -E -u www-data php bin/console partdb:backup -n --database /var/www/html/uploads/.automigration-backup/backup-$(date +%Y-%m-%d_%H-%M-%S).zip
# Check if there are any migration files
sudo -E -u www-data php bin/console doctrine:migrations:migrate --no-interaction
fi
fi
# first arg is `-f` or `--some-option` (taken from https://github.com/docker-library/php/blob/master/8.2/bullseye/apache/docker-php-entrypoint) # first arg is `-f` or `--some-option` (taken from https://github.com/docker-library/php/blob/master/8.2/bullseye/apache/docker-php-entrypoint)
if [ "${1#-}" != "$1" ]; then if [ "${1#-}" != "$1" ]; then

View file

@ -25,9 +25,9 @@
CustomLog ${APACHE_LOG_DIR}/access.log combined CustomLog ${APACHE_LOG_DIR}/access.log combined
# Pass the configuration from the docker env to the PHP environment (here you should list all .env options) # Pass the configuration from the docker env to the PHP environment (here you should list all .env options)
PassEnv APP_ENV APP_DEBUG APP_SECRET PassEnv APP_ENV APP_DEBUG APP_SECRET REDIRECT_TO_HTTPS DISABLE_YEAR2038_BUG_CHECK
PassEnv TRUSTED_PROXIES TRUSTED_HOSTS LOCK_DSN PassEnv TRUSTED_PROXIES TRUSTED_HOSTS LOCK_DSN
PassEnv DATABASE_URL ENFORCE_CHANGE_COMMENTS_FOR PassEnv DATABASE_URL ENFORCE_CHANGE_COMMENTS_FOR DATABASE_MYSQL_USE_SSL_CA DATABASE_MYSQL_SSL_VERIFY_CERT
PassEnv DEFAULT_LANG DEFAULT_TIMEZONE BASE_CURRENCY INSTANCE_NAME ALLOW_ATTACHMENT_DOWNLOADS USE_GRAVATAR MAX_ATTACHMENT_FILE_SIZE DEFAULT_URI CHECK_FOR_UPDATES ATTACHMENT_DOWNLOAD_BY_DEFAULT PassEnv DEFAULT_LANG DEFAULT_TIMEZONE BASE_CURRENCY INSTANCE_NAME ALLOW_ATTACHMENT_DOWNLOADS USE_GRAVATAR MAX_ATTACHMENT_FILE_SIZE DEFAULT_URI CHECK_FOR_UPDATES ATTACHMENT_DOWNLOAD_BY_DEFAULT
PassEnv MAILER_DSN ALLOW_EMAIL_PW_RESET EMAIL_SENDER_EMAIL EMAIL_SENDER_NAME PassEnv MAILER_DSN ALLOW_EMAIL_PW_RESET EMAIL_SENDER_EMAIL EMAIL_SENDER_NAME
PassEnv HISTORY_SAVE_CHANGED_FIELDS HISTORY_SAVE_CHANGED_DATA HISTORY_SAVE_REMOVED_DATA HISTORY_SAVE_NEW_DATA PassEnv HISTORY_SAVE_CHANGED_FIELDS HISTORY_SAVE_CHANGED_DATA HISTORY_SAVE_REMOVED_DATA HISTORY_SAVE_NEW_DATA
@ -42,6 +42,10 @@
PassEnv PROVIDER_TME_KEY PROVIDER_TME_SECRET PROVIDER_TME_CURRENCY PROVIDER_TME_LANGUAGE PROVIDER_TME_COUNTRY PROVIDER_TME_GET_GROSS_PRICES PassEnv PROVIDER_TME_KEY PROVIDER_TME_SECRET PROVIDER_TME_CURRENCY PROVIDER_TME_LANGUAGE PROVIDER_TME_COUNTRY PROVIDER_TME_GET_GROSS_PRICES
PassEnv PROVIDER_OCTOPART_CLIENT_ID PROVIDER_OCTOPART_SECRET PROVIDER_OCTOPART_CURRENCY PROVIDER_OCTOPART_COUNTRY PROVIDER_OCTOPART_SEARCH_LIMIT PROVIDER_OCTOPART_ONLY_AUTHORIZED_SELLERS PassEnv PROVIDER_OCTOPART_CLIENT_ID PROVIDER_OCTOPART_SECRET PROVIDER_OCTOPART_CURRENCY PROVIDER_OCTOPART_COUNTRY PROVIDER_OCTOPART_SEARCH_LIMIT PROVIDER_OCTOPART_ONLY_AUTHORIZED_SELLERS
PassEnv PROVIDER_MOUSER_KEY PROVIDER_MOUSER_SEARCH_OPTION PROVIDER_MOUSER_SEARCH_LIMIT PROVIDER_MOUSER_SEARCH_WITH_SIGNUP_LANGUAGE PassEnv PROVIDER_MOUSER_KEY PROVIDER_MOUSER_SEARCH_OPTION PROVIDER_MOUSER_SEARCH_LIMIT PROVIDER_MOUSER_SEARCH_WITH_SIGNUP_LANGUAGE
PassEnv PROVIDER_LCSC_ENABLED PROVIDER_LCSC_CURRENCY
PassEnv PROVIDER_OEMSECRETS_KEY PROVIDER_OEMSECRETS_COUNTRY_CODE PROVIDER_OEMSECRETS_CURRENCY PROVIDER_OEMSECRETS_ZERO_PRICE PROVIDER_OEMSECRETS_SET_PARAM PROVIDER_OEMSECRETS_SORT_CRITERIA
PassEnv PROVIDER_REICHELT_ENABLED PROVIDER_REICHELT_CURRENCY PROVIDER_REICHELT_COUNTRY PROVIDER_REICHELT_LANGUAGE PROVIDER_REICHELT_INCLUDE_VAT
PassEnv PROVIDER_POLLIN_ENABLED
PassEnv EDA_KICAD_CATEGORY_DEPTH PassEnv EDA_KICAD_CATEGORY_DEPTH
# For most configuration files from conf-available/, which are # For most configuration files from conf-available/, which are

View file

@ -5,6 +5,8 @@ tests/
docs/ docs/
.git .git
/public/media/*
###> symfony/framework-bundle ### ###> symfony/framework-bundle ###
/.env.local /.env.local
/.env.local.php /.env.local.php
@ -42,3 +44,39 @@ yarn-error.log
/phpunit.xml /phpunit.xml
.phpunit.result.cache .phpunit.result.cache
###< phpunit/phpunit ### ###< phpunit/phpunit ###
### From frankenphp
**/*.log
**/*.php~
**/*.dist.php
**/*.dist
**/*.cache
**/._*
**/.dockerignore
**/.DS_Store
**/.git/
**/.gitattributes
**/.gitignore
**/.gitmodules
**/compose.*.yaml
**/compose.*.yml
**/compose.yaml
**/compose.yml
**/docker-compose.*.yaml
**/docker-compose.*.yml
**/docker-compose.yaml
**/docker-compose.yml
**/Dockerfile
**/Thumbs.db
.github/
public/bundles/
var/
vendor/
.editorconfig
.env.*.local
.env.local
.env.local.php
.env.test

88
.env
View file

@ -14,6 +14,19 @@ DATABASE_URL="sqlite:///%kernel.project_dir%/var/app.db"
# Uncomment this line (and comment the line above to use a MySQL database # Uncomment this line (and comment the line above to use a MySQL database
#DATABASE_URL=mysql://root:@127.0.0.1:3306/part-db?serverVersion=5.7 #DATABASE_URL=mysql://root:@127.0.0.1:3306/part-db?serverVersion=5.7
# Set this value to 1, if you want to use SSL to connect to the MySQL server. It will be tried to use the CA certificate
# otherwise a CA bundle shipped with PHP will be used.
# Leave it at 0, if you do not want to use SSL or if your server does not support it
DATABASE_MYSQL_USE_SSL_CA=0
# Set this value to 0, if you don't want to verify the CA certificate of the MySQL server
# Only do this, if you know what you are doing!
DATABASE_MYSQL_SSL_VERIFY_CERT=1
# Emulate natural sorting of strings even on databases that do not support it (like SQLite, MySQL or MariaDB < 10.7)
# This can be slow on big databases and might have some problems and quirks, so use it with caution
DATABASE_EMULATE_NATURAL_SORT=0
################################################################################### ###################################################################################
# General settings # General settings
################################################################################### ###################################################################################
@ -37,7 +50,7 @@ USE_GRAVATAR=0
# Please note that the php.ini setting upload_max_filesize also limits the maximum size of uploaded files # Please note that the php.ini setting upload_max_filesize also limits the maximum size of uploaded files
MAX_ATTACHMENT_FILE_SIZE="100M" MAX_ATTACHMENT_FILE_SIZE="100M"
# The public reachable URL of this Part-DB installation. This is used for generating links to the website in emails and so on # The public reachable URL of this Part-DB installation. This is used for generating links in SAML and email templates
# This must end with a slash! # This must end with a slash!
DEFAULT_URI="https://partdb.changeme.invalid/" DEFAULT_URI="https://partdb.changeme.invalid/"
@ -130,7 +143,8 @@ PROVIDER_TME_CURRENCY=EUR
PROVIDER_TME_LANGUAGE=en PROVIDER_TME_LANGUAGE=en
# The country to get results for # The country to get results for
PROVIDER_TME_COUNTRY=DE PROVIDER_TME_COUNTRY=DE
# Set this to 1 to get gross prices (including VAT) instead of net prices # [DEPRECATED] Set this to 1 to get gross prices (including VAT) instead of net prices
# With private API keys, this option cannot be used anymore is ignored by Part-DB. The VAT inclusion depends on your TME account settings.
PROVIDER_TME_GET_GROSS_PRICES=1 PROVIDER_TME_GET_GROSS_PRICES=1
# Octopart / Nexar Provider: # Octopart / Nexar Provider:
@ -159,6 +173,70 @@ PROVIDER_MOUSER_SEARCH_LIMIT=50
# Used when searching for keywords in the language specified when you signed up for Search API. # Used when searching for keywords in the language specified when you signed up for Search API.
PROVIDER_MOUSER_SEARCH_WITH_SIGNUP_LANGUAGE='true' PROVIDER_MOUSER_SEARCH_WITH_SIGNUP_LANGUAGE='true'
# LCSC Provider:
# LCSC does not provide an offical API, so this used the API LCSC uses to render their webshop.
# LCSC did not intended the use of this API and it could break any time, so use it at your own risk.
# We dont require an API key for LCSC, just set this to 1 to enable LCSC support
PROVIDER_LCSC_ENABLED=0
# The currency to get prices in (e.g. EUR, USD, etc.)
PROVIDER_LCSC_CURRENCY=EUR
# Oemsecrets Provider API 3.0.1:
# You can get your API key from https://www.oemsecrets.com/api
PROVIDER_OEMSECRETS_KEY=
# The country you want the output for
PROVIDER_OEMSECRETS_COUNTRY_CODE=DE
# Available country code are:
# AD, AE, AQ, AR, AT, AU, BE, BO, BR, BV, BY, CA, CH, CL, CN, CO, CZ, DE, DK, EC, EE, EH,
# ES, FI, FK, FO, FR, GB, GE, GF, GG, GI, GL, GR, GS, GY, HK, HM, HR, HU, IE, IM, IN, IS,
# IT, JM, JP, KP, KR, KZ, LI, LK, LT, LU, MC, MD, ME, MK, MT, NL, NO, NZ, PE, PH, PL, PT,
# PY, RO, RS, RU, SB, SD, SE, SG, SI, SJ, SK, SM, SO, SR, SY, SZ, TC, TF, TG, TH, TJ, TK,
# TM, TN, TO, TR, TT, TV, TW, TZ, UA, UG, UM, US, UY, UZ, VA, VE, VG, VI, VN, VU, WF, YE,
# ZA, ZM, ZW
#
# The currency you want the prices to be displayed in
PROVIDER_OEMSECRETS_CURRENCY=EUR
# Available currency are:AUD, CAD, CHF, CNY, DKK, EUR, GBP, HKD, ILS, INR, JPY, KRW, NOK,
# NZD, RUB, SEK, SGD, TWD, USD
#
# If PROVIDER_OEMSECRETS_ZERO_PRICE is set to 0, distributors with zero prices
# will be discarded from the creation of a new part (set to 1 otherwise)
PROVIDER_OEMSECRETS_ZERO_PRICE=0
#
# When PROVIDER_OEMSECRETS_SET_PARAM is set to 1 the parameters for the part are generated
# from the description transforming unstructured descriptions into structured parameters;
# each parameter in description should have the form: "...;name1:value1;name2:value2"
PROVIDER_OEMSECRETS_SET_PARAM=1
#
# This environment variable determines the sorting criteria for product results.
# The sorting process first arranges items based on the provided keyword.
# Then, if set to 'C', it further sorts by completeness (prioritizing items with the most
# detailed information). If set to 'M', it further sorts by manufacturer name.
#If unset or set to any other value, no sorting is performed.
PROVIDER_OEMSECRETS_SORT_CRITERIA=C
# Reichelt provider:
# Reichelt.com offers no official API, so this info provider webscrapes the website to extract info
# It could break at any time, use it at your own risk
# We dont require an API key for Reichelt, just set this to 1 to enable Reichelt support
PROVIDER_REICHELT_ENABLED=0
# The country to get prices for
PROVIDER_REICHELT_COUNTRY=DE
# The language to get results in (en, de, fr, nl, pl, it, es)
PROVIDER_REICHELT_LANGUAGE=en
# Include VAT in prices (set to 1 to include VAT, 0 to exclude VAT)
PROVIDER_REICHELT_INCLUDE_VAT=1
# The currency to get prices in (only for countries with countries other than EUR)
PROVIDER_REICHELT_CURRENCY=EUR
# Pollin provider:
# Pollin.de offers no official API, so this info provider webscrapes the website to extract info
# It could break at any time, use it at your own risk
# We dont require an API key for Pollin, just set this to 1 to enable Pollin support
PROVIDER_POLLIN_ENABLED=0
################################################################################## ##################################################################################
# EDA integration related settings # EDA integration related settings
################################################################################## ##################################################################################
@ -172,6 +250,7 @@ EDA_KICAD_CATEGORY_DEPTH=0
# SAML Single sign on-settings # SAML Single sign on-settings
################################################################################### ###################################################################################
# Set this to 1 to enable SAML single sign on # Set this to 1 to enable SAML single sign on
# Be also sure to set the correct values for DEFAULT_URI
SAML_ENABLED=0 SAML_ENABLED=0
# Set to 1, if your Part-DB installation is behind a reverse proxy and you want to use SAML # Set to 1, if your Part-DB installation is behind a reverse proxy and you want to use SAML
@ -216,6 +295,9 @@ DEMO_MODE=0
# In that case all URL contains the index.php front controller in URL # In that case all URL contains the index.php front controller in URL
NO_URL_REWRITE_AVAILABLE=0 NO_URL_REWRITE_AVAILABLE=0
# Set to 1, if Part-DB should redirect all HTTP requests to HTTPS. You dont need to configure this, if your webserver already does this.
REDIRECT_TO_HTTPS=0
# If you want to use fixer.io for currency conversion, you have to set this to your API key # If you want to use fixer.io for currency conversion, you have to set this to your API key
FIXER_API_KEY=CHANGEME FIXER_API_KEY=CHANGEME
@ -226,6 +308,8 @@ BANNER=""
APP_ENV=prod APP_ENV=prod
APP_SECRET=a03498528f5a5fc089273ec9ae5b2849 APP_SECRET=a03498528f5a5fc089273ec9ae5b2849
# Set this to zero, if you want to disable the year 2038 bug check on 32-bit systems (it will cause errors with current 32-bit PHP versions)
DISABLE_YEAR2038_BUG_CHECK=0
# Set the trusted IPs here, when using an reverse proxy # Set the trusted IPs here, when using an reverse proxy
#TRUSTED_PROXIES=127.0.0.0/8,::1,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16 #TRUSTED_PROXIES=127.0.0.0/8,::1,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16

0
.env.dev Normal file
View file

View file

@ -5,5 +5,9 @@ SYMFONY_DEPRECATIONS_HELPER=999999
PANTHER_APP_ENV=panther PANTHER_APP_ENV=panther
PANTHER_ERROR_SCREENSHOT_DIR=./var/error-screenshots PANTHER_ERROR_SCREENSHOT_DIR=./var/error-screenshots
DATABASE_URL="sqlite:///%kernel.project_dir%/var/app_test.db"
# Doctrine automatically adds an _test suffix to database name in test env # Doctrine automatically adds an _test suffix to database name in test env
DATABASE_URL=mysql://root:@127.0.0.1:3306/part-db #DATABASE_URL=mysql://root:@127.0.0.1:3306/part-db
# Disable update checks, as tests would fail, when github is not reachable
CHECK_FOR_UPDATES=0

View file

@ -34,7 +34,7 @@ jobs:
run: | run: |
echo "::set-output name=dir::$(composer config cache-files-dir)" echo "::set-output name=dir::$(composer config cache-files-dir)"
- uses: actions/cache@v3 - uses: actions/cache@v4
with: with:
path: ${{ steps.composer-cache.outputs.dir }} path: ${{ steps.composer-cache.outputs.dir }}
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
@ -48,7 +48,7 @@ jobs:
id: yarn-cache-dir-path id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)" run: echo "::set-output name=dir::$(yarn cache dir)"
- uses: actions/cache@v3 - uses: actions/cache@v4
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`) id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
with: with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }} path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
@ -77,13 +77,13 @@ jobs:
run: zip -r /tmp/partdb_assets.zip public/build/ vendor/ run: zip -r /tmp/partdb_assets.zip public/build/ vendor/
- name: Upload assets artifact - name: Upload assets artifact
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
name: Only dependencies and built assets name: Only dependencies and built assets
path: /tmp/partdb_assets.zip path: /tmp/partdb_assets.zip
- name: Upload full artifact - name: Upload full artifact
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
name: Full Part-DB including dependencies and built assets name: Full Part-DB including dependencies and built assets
path: /tmp/partdb_with_assets.zip path: /tmp/partdb_with_assets.zip

View file

@ -65,7 +65,7 @@ jobs:
- -
name: Build and push name: Build and push
uses: docker/build-push-action@v5 uses: docker/build-push-action@v6
with: with:
context: . context: .
platforms: linux/amd64,linux/arm64,linux/arm/v7 platforms: linux/amd64,linux/arm64,linux/arm/v7

77
.github/workflows/docker_frankenphp.yml vendored Normal file
View file

@ -0,0 +1,77 @@
name: Docker Image Build (FrankenPHP)
on:
#schedule:
# - cron: '0 10 * * *' # everyday at 10am
push:
branches:
- '**'
- '!l10n_**'
tags:
- 'v*.*.*'
- 'v*.*.*-**'
jobs:
docker:
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v4
-
name: Docker meta
id: docker_meta
uses: docker/metadata-action@v5
with:
# list of Docker images to use as base name for tags
images: |
partdborg/part-db
# Mark the image build from master as latest (as we dont have really releases yet)
tags: |
type=edge,branch=master
type=ref,event=branch,
type=ref,event=tag,
type=schedule
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=ref,event=branch
type=ref,event=pr
labels: |
org.opencontainers.image.source=${{ github.event.repository.clone_url }}
org.opencontainers.image.revision=${{ github.sha }}
org.opencontainers.image.title=Part-DB
org.opencontainers.image.description=Part-DB is a web application for managing electronic components and your inventory.
org.opencontainers.image.url=https://github.com/Part-DB/Part-DB-server
org.opencontainers.image.source=https://github.com/Part-DB/Part-DB-server
org.opencontainers.image.authors=Jan Böhmer
org.opencontainers.licenses=AGPL-3.0-or-later
-
name: Set up QEMU
uses: docker/setup-qemu-action@v3
with:
platforms: 'arm64,arm'
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
-
name: Login to DockerHub
if: github.event_name != 'pull_request'
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
-
name: Build and push
uses: docker/build-push-action@v6
with:
context: .
file: Dockerfile-frankenphp
platforms: linux/amd64,linux/arm64,linux/arm/v7
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.docker_meta.outputs.tags }}
labels: ${{ steps.docker_meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max

View file

@ -31,7 +31,7 @@ jobs:
run: | run: |
echo "::set-output name=dir::$(composer config cache-files-dir)" echo "::set-output name=dir::$(composer config cache-files-dir)"
- uses: actions/cache@v3 - uses: actions/cache@v4
with: with:
path: ${{ steps.composer-cache.outputs.dir }} path: ${{ steps.composer-cache.outputs.dir }}
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}

View file

@ -16,9 +16,10 @@ jobs:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
strategy: strategy:
fail-fast: false
matrix: matrix:
php-versions: [ '8.1', '8.2', '8.3' ] php-versions: [ '8.1', '8.2', '8.3', '8.4' ]
db-type: [ 'mysql', 'sqlite' ] db-type: [ 'mysql', 'sqlite', 'postgres' ]
env: env:
# Note that we set DATABASE URL later based on our db-type matrix value # Note that we set DATABASE URL later based on our db-type matrix value
@ -26,16 +27,21 @@ jobs:
SYMFONY_DEPRECATIONS_HELPER: disabled SYMFONY_DEPRECATIONS_HELPER: disabled
PHP_VERSION: ${{ matrix.php-versions }} PHP_VERSION: ${{ matrix.php-versions }}
DB_TYPE: ${{ matrix.db-type }} DB_TYPE: ${{ matrix.db-type }}
CHECK_FOR_UPDATES: false # Disable update checks for tests
steps: steps:
- name: Set Database env for MySQL - name: Set Database env for MySQL
run: echo "DATABASE_URL=mysql://root:root@127.0.0.1:3306/test" >> $GITHUB_ENV run: echo "DATABASE_URL=mysql://root:root@127.0.0.1:3306/partdb?serverVersion=8.0.35" >> $GITHUB_ENV
if: matrix.db-type == 'mysql' if: matrix.db-type == 'mysql'
- name: Set Database env for SQLite - name: Set Database env for SQLite
run: echo "DATABASE_URL="sqlite:///%kernel.project_dir%/var/app_test.db"" >> $GITHUB_ENV run: echo "DATABASE_URL="sqlite:///%kernel.project_dir%/var/app_test.db"" >> $GITHUB_ENV
if: matrix.db-type == 'sqlite' if: matrix.db-type == 'sqlite'
- name: Set Database env for PostgreSQL
run: echo "DATABASE_URL=postgresql://postgres:postgres @127.0.0.1:5432/partdb?serverVersion=14&charset=utf8" >> $GITHUB_ENV
if: matrix.db-type == 'postgres'
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v4
@ -49,6 +55,15 @@ jobs:
- name: Start MySQL - name: Start MySQL
run: sudo systemctl start mysql.service run: sudo systemctl start mysql.service
if: matrix.db-type == 'mysql'
# Replace the scram-sha-256 with trust for host connections, to avoid password authentication
- name: Start PostgreSQL
run: |
sudo sed -i 's/^\(host.*all.*all.*\)scram-sha-256/\1trust/' /etc/postgresql/14/main/pg_hba.conf
sudo systemctl start postgresql.service
sudo -u postgres psql -c "ALTER USER postgres PASSWORD 'postgres';"
if: matrix.db-type == 'postgres'
#- name: Setup MySQL #- name: Setup MySQL
# uses: mirromutth/mysql-action@v1.1 # uses: mirromutth/mysql-action@v1.1
@ -63,7 +78,7 @@ jobs:
id: composer-cache id: composer-cache
run: | run: |
echo "::set-output name=dir::$(composer config cache-files-dir)" echo "::set-output name=dir::$(composer config cache-files-dir)"
- uses: actions/cache@v3 - uses: actions/cache@v4
with: with:
path: ${{ steps.composer-cache.outputs.dir }} path: ${{ steps.composer-cache.outputs.dir }}
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
@ -74,7 +89,7 @@ jobs:
id: yarn-cache-dir-path id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)" run: echo "::set-output name=dir::$(yarn cache dir)"
- uses: actions/cache@v3 - uses: actions/cache@v4
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`) id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
with: with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }} path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
@ -98,12 +113,7 @@ jobs:
- name: Create DB - name: Create DB
run: php bin/console --env test doctrine:database:create --if-not-exists -n run: php bin/console --env test doctrine:database:create --if-not-exists -n
if: matrix.db-type == 'mysql' if: matrix.db-type == 'mysql' || matrix.db-type == 'postgres'
# Checkinf for existance is not supported for sqlite, so do it without it
- name: Create DB
run: php bin/console --env test doctrine:database:create -n
if: matrix.db-type == 'sqlite'
- name: Do migrations - name: Do migrations
run: php bin/console --env test doctrine:migrations:migrate -n run: php bin/console --env test doctrine:migrations:migrate -n
@ -116,7 +126,7 @@ jobs:
run: ./bin/phpunit --coverage-clover=coverage.xml run: ./bin/phpunit --coverage-clover=coverage.xml
- name: Upload coverage - name: Upload coverage
uses: codecov/codecov-action@v3 uses: codecov/codecov-action@v5
with: with:
env_vars: PHP_VERSION,DB_TYPE env_vars: PHP_VERSION,DB_TYPE
token: ${{ secrets.CODECOV_TOKEN }} token: ${{ secrets.CODECOV_TOKEN }}
@ -134,11 +144,11 @@ jobs:
- name: Test check-requirements command - name: Test check-requirements command
run: php bin/console partdb:check-requirements -n run: php bin/console partdb:check-requirements -n
- name: Test partdb:backup command
run: php bin/console partdb:backup -n --full /tmp/test_backup.zip
- name: Test legacy Part-DB import - name: Test legacy Part-DB import
run: bash .github/assets/legacy_import/test_legacy_import.sh run: bash .github/assets/legacy_import/test_legacy_import.sh
if: matrix.db-type == 'mysql' && matrix.php-versions == '8.2' if: matrix.db-type == 'mysql' && matrix.php-versions == '8.2'
env: env:
DATABASE_URL: mysql://root:root@localhost:3306/legacy_db DATABASE_URL: mysql://root:root@localhost:3306/legacy_db

View file

@ -1,22 +1,64 @@
FROM debian:bullseye-slim ARG BASE_IMAGE=debian:bookworm-slim
ARG PHP_VERSION=8.3
FROM ${BASE_IMAGE} AS base
ARG PHP_VERSION
# Install needed dependencies for PHP build # Install needed dependencies for PHP build
#RUN apt-get update && apt-get install -y pkg-config curl libcurl4-openssl-dev libicu-dev \ #RUN apt-get update && apt-get install -y pkg-config curl libcurl4-openssl-dev libicu-dev \
# libpng-dev libjpeg-dev libfreetype6-dev gnupg zip libzip-dev libjpeg62-turbo-dev libonig-dev libxslt-dev libwebp-dev vim \ # libpng-dev libjpeg-dev libfreetype6-dev gnupg zip libzip-dev libjpeg62-turbo-dev libonig-dev libxslt-dev libwebp-dev vim \
# && apt-get -y autoremove && apt-get clean autoclean && rm -rf /var/lib/apt/lists/* # && apt-get -y autoremove && apt-get clean autoclean && rm -rf /var/lib/apt/lists/*
RUN apt-get update && apt-get -y install apt-transport-https lsb-release ca-certificates curl zip \ RUN apt-get update && apt-get -y install \
apt-transport-https \
lsb-release \
ca-certificates \
curl \
zip \
mariadb-client \
postgresql-client \
&& curl -sSLo /usr/share/keyrings/deb.sury.org-php.gpg https://packages.sury.org/php/apt.gpg \ && curl -sSLo /usr/share/keyrings/deb.sury.org-php.gpg https://packages.sury.org/php/apt.gpg \
&& sh -c 'echo "deb [signed-by=/usr/share/keyrings/deb.sury.org-php.gpg] https://packages.sury.org/php/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/php.list' \ && sh -c 'echo "deb [signed-by=/usr/share/keyrings/deb.sury.org-php.gpg] https://packages.sury.org/php/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/php.list' \
&& apt-get update && apt-get upgrade -y \ && apt-get update && apt-get upgrade -y \
&& apt-get install -y apache2 php8.1 php8.1-fpm php8.1-opcache php8.1-curl php8.1-gd php8.1-mbstring php8.1-xml php8.1-bcmath php8.1-intl php8.1-zip php8.1-xsl php8.1-sqlite3 php8.1-mysql gpg \ && apt-get install -y \
&& apt-get -y autoremove && apt-get clean autoclean && rm -rf /var/lib/apt/lists/*; apache2 \
php${PHP_VERSION} \
ENV APACHE_CONFDIR /etc/apache2 php${PHP_VERSION}-fpm \
ENV APACHE_ENVVARS $APACHE_CONFDIR/envvars php${PHP_VERSION}-opcache \
php${PHP_VERSION}-curl \
php${PHP_VERSION}-gd \
php${PHP_VERSION}-mbstring \
php${PHP_VERSION}-xml \
php${PHP_VERSION}-bcmath \
php${PHP_VERSION}-intl \
php${PHP_VERSION}-zip \
php${PHP_VERSION}-xsl \
php${PHP_VERSION}-sqlite3 \
php${PHP_VERSION}-mysql \
php${PHP_VERSION}-pgsql \
gpg \
sudo \
&& apt-get -y autoremove && apt-get clean autoclean && rm -rf /var/lib/apt/lists/* \
# Create workdir and set permissions if directory does not exists # Create workdir and set permissions if directory does not exists
RUN mkdir -p /var/www/html && chown -R www-data:www-data /var/www/html && mkdir -p /var/www/html \
&& chown -R www-data:www-data /var/www/html \
# delete the "index.html" that installing Apache drops in here
&& rm -rvf /var/www/html/*
# Install node and yarn
RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && \
echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list && \
curl -sL https://deb.nodesource.com/setup_20.x | bash - && \
apt-get update && apt-get install -y \
nodejs \
yarn \
&& apt-get -y autoremove && apt-get clean autoclean && rm -rf /var/lib/apt/lists/*
# Install composer
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
ENV APACHE_CONFDIR=/etc/apache2
ENV APACHE_ENVVARS=$APACHE_CONFDIR/envvars
# Configure apache 2 (taken from https://github.com/docker-library/php/blob/master/8.2/bullseye/apache/Dockerfile) # Configure apache 2 (taken from https://github.com/docker-library/php/blob/master/8.2/bullseye/apache/Dockerfile)
# generically convert lines like # generically convert lines like
@ -27,8 +69,6 @@ RUN mkdir -p /var/www/html && chown -R www-data:www-data /var/www/html
# so that they can be overridden at runtime ("-e APACHE_RUN_USER=...") # so that they can be overridden at runtime ("-e APACHE_RUN_USER=...")
RUN sed -ri 's/^export ([^=]+)=(.*)$/: ${\1:=\2}\nexport \1/' "$APACHE_ENVVARS"; \ RUN sed -ri 's/^export ([^=]+)=(.*)$/: ${\1:=\2}\nexport \1/' "$APACHE_ENVVARS"; \
set -eux; . "$APACHE_ENVVARS"; \ set -eux; . "$APACHE_ENVVARS"; \
# delete the "index.html" that installing Apache drops in here
rm -rvf /var/www/html/*; \
\ \
# logs should go to stdout / stderr # logs should go to stdout / stderr
ln -sfT /dev/stderr "$APACHE_LOG_DIR/error.log"; \ ln -sfT /dev/stderr "$APACHE_LOG_DIR/error.log"; \
@ -36,82 +76,87 @@ RUN sed -ri 's/^export ([^=]+)=(.*)$/: ${\1:=\2}\nexport \1/' "$APACHE_ENVVARS"
ln -sfT /dev/stdout "$APACHE_LOG_DIR/other_vhosts_access.log"; \ ln -sfT /dev/stdout "$APACHE_LOG_DIR/other_vhosts_access.log"; \
chown -R --no-dereference "$APACHE_RUN_USER:$APACHE_RUN_GROUP" "$APACHE_LOG_DIR"; chown -R --no-dereference "$APACHE_RUN_USER:$APACHE_RUN_GROUP" "$APACHE_LOG_DIR";
# Enable php-fpm # ---
RUN a2enmod proxy_fcgi setenvif && a2enconf php8.1-fpm
FROM scratch AS apache-config
ARG PHP_VERSION
# Configure php-fpm to log to stdout of the container (stdout of PID 1) # Configure php-fpm to log to stdout of the container (stdout of PID 1)
# We have to use /proc/1/fd/1 because /dev/stdout or /proc/self/fd/1 does not point to the container stdout (because we use apache as entrypoint) # We have to use /proc/1/fd/1 because /dev/stdout or /proc/self/fd/1 does not point to the container stdout (because we use apache as entrypoint)
# We also disable the clear_env option to allow the use of environment variables in php-fpm # We also disable the clear_env option to allow the use of environment variables in php-fpm
RUN { \ COPY <<EOF /etc/php/${PHP_VERSION}/fpm/pool.d/zz-docker.conf
echo '[global]'; \ [global]
echo 'error_log = /proc/1/fd/1'; \ error_log = /proc/1/fd/1
echo; \
echo '[www]'; \ [www]
echo 'access.log = /proc/1/fd/1'; \ access.log = /proc/1/fd/1
echo 'catch_workers_output = yes'; \ catch_workers_output = yes
echo 'decorate_workers_output = no'; \ decorate_workers_output = no
echo 'clear_env = no'; \ clear_env = no
} | tee "/etc/php/8.1/fpm/pool.d/zz-docker.conf" EOF
# PHP files should be handled by PHP, and should be preferred over any other file type # PHP files should be handled by PHP, and should be preferred over any other file type
RUN { \ COPY <<EOF /etc/apache2/conf-available/docker-php.conf
echo '<FilesMatch \.php$>'; \ <FilesMatch \\.php$>
echo '\tSetHandler application/x-httpd-php'; \ SetHandler application/x-httpd-php
echo '</FilesMatch>'; \ </FilesMatch>
echo; \
echo 'DirectoryIndex disabled'; \ DirectoryIndex disabled
echo 'DirectoryIndex index.php index.html'; \ DirectoryIndex index.php index.html
echo; \
echo '<Directory /var/www/>'; \ <Directory /var/www/>
echo '\tOptions -Indexes'; \ Options -Indexes
echo '\tAllowOverride All'; \ AllowOverride All
echo '</Directory>'; \ </Directory>
} | tee "$APACHE_CONFDIR/conf-available/docker-php.conf" \ EOF
&& a2enconf docker-php
# Enable opcache and configure it recommended for symfony (see https://symfony.com/doc/current/performance.html) # Enable opcache and configure it recommended for symfony (see https://symfony.com/doc/current/performance.html)
RUN \ COPY <<EOF /etc/php/${PHP_VERSION}/fpm/conf.d/symfony-recommended.ini
{ \ opcache.memory_consumption=256
echo 'opcache.memory_consumption=256'; \ opcache.max_accelerated_files=20000
echo 'opcache.max_accelerated_files=20000'; \ opcache.validate_timestamp=0
echo 'opcache.validate_timestamp=0'; \
# Configure Realpath cache for performance # Configure Realpath cache for performance
echo 'realpath_cache_size=4096K'; \ realpath_cache_size=4096K
echo 'realpath_cache_ttl=600'; \ realpath_cache_ttl=600
} > /etc/php/8.1/fpm/conf.d/symfony-recommended.ini EOF
# Increase upload limit and enable preloading # Increase upload limit and enable preloading
RUN \ COPY <<EOF /etc/php/${PHP_VERSION}/fpm/conf.d/partdb.ini
{ \ upload_max_filesize=256M
echo 'upload_max_filesize=256M'; \ post_max_size=300M
echo 'post_max_size=300M'; \ opcache.preload_user=www-data
echo 'opcache.preload_user=www-data'; \ opcache.preload=/var/www/html/config/preload.php
echo 'opcache.preload=/var/www/html/config/preload.php'; \ log_limit=8096
} > /etc/php/8.1/fpm/conf.d/partdb.ini EOF
# Install node and yarn COPY ./.docker/symfony.conf /etc/apache2/sites-available/symfony.conf
RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list
RUN curl -sL https://deb.nodesource.com/setup_18.x | bash - && apt-get update && apt-get install -y nodejs yarn && apt-get -y autoremove && apt-get clean autoclean && rm -rf /var/lib/apt/lists/*
# Install composer # ---
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
FROM base
ARG PHP_VERSION
# Set working dir # Set working dir
WORKDIR /var/www/html WORKDIR /var/www/html
COPY --from=apache-config / /
COPY --chown=www-data:www-data . . COPY --chown=www-data:www-data . .
# Setup apache2 # Setup apache2
RUN a2dissite 000-default.conf RUN a2dissite 000-default.conf && \
COPY ./.docker/symfony.conf /etc/apache2/sites-available/symfony.conf a2ensite symfony.conf && \
RUN a2ensite symfony.conf # Enable php-fpm
RUN a2enmod rewrite a2enmod proxy_fcgi setenvif && \
a2enconf php${PHP_VERSION}-fpm && \
a2enconf docker-php && \
a2enmod rewrite
# Install composer and yarn dependencies for Part-DB # Install composer and yarn dependencies for Part-DB
USER www-data USER www-data
RUN composer install -a --no-dev && composer clear-cache RUN composer install -a --no-dev && \
RUN yarn install --network-timeout 600000 && yarn build && yarn cache clean && rm -rf node_modules/ composer clear-cache
RUN yarn install --network-timeout 600000 && \
yarn build && \
yarn cache clean && \
rm -rf node_modules/
# Use docker env to output logs to stdout # Use docker env to output logs to stdout
ENV APP_ENV=docker ENV APP_ENV=docker
@ -119,10 +164,12 @@ ENV DATABASE_URL="sqlite:///%kernel.project_dir%/uploads/app.db"
USER root USER root
# Copy entrypoint to /usr/local/bin and make it executable # Replace the php version placeholder in the entry point, with our php version
RUN cp ./.docker/partdb-entrypoint.sh /usr/local/bin/partdb-entrypoint.sh && chmod +x /usr/local/bin/partdb-entrypoint.sh RUN sed -i "s/PHP_VERSION/${PHP_VERSION}/g" ./.docker/partdb-entrypoint.sh
# Copy apache2-foreground to /usr/local/bin and make it executable
RUN cp ./.docker/apache2-foreground /usr/local/bin/apache2-foreground && chmod +x /usr/local/bin/apache2-foreground # Copy entrypoint and apache2-foreground to /usr/local/bin and make it executable
RUN install ./.docker/partdb-entrypoint.sh /usr/local/bin && \
install ./.docker/apache2-foreground /usr/local/bin
ENTRYPOINT ["partdb-entrypoint.sh"] ENTRYPOINT ["partdb-entrypoint.sh"]
CMD ["apache2-foreground"] CMD ["apache2-foreground"]

101
Dockerfile-frankenphp Normal file
View file

@ -0,0 +1,101 @@
FROM dunglas/frankenphp:1-php8.3 AS frankenphp_upstream
RUN apt-get update && apt-get -y install \
curl \
ca-certificates \
mariadb-client \
postgresql-client \
file \
acl \
git \
gettext \
gnupg \
zip \
&& apt-get -y autoremove && apt-get clean autoclean && rm -rf /var/lib/apt/lists/*;
# Install node and yarn
RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && \
echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list && \
curl -sL https://deb.nodesource.com/setup_20.x | bash - && \
apt-get update && apt-get install -y \
nodejs yarn \
&& apt-get -y autoremove && apt-get clean autoclean && rm -rf /var/lib/apt/lists/*
# Install PHP
RUN set -eux; \
install-php-extensions \
@composer \
apcu \
intl \
opcache \
zip \
pdo_mysql \
pdo_sqlite \
pdo_pgsql \
gd \
bcmath \
xsl \
;
# Copy config files for php and caddy
COPY --link .docker/frankenphp/conf.d/app.ini $PHP_INI_DIR/conf.d/
COPY --chmod=755 .docker/frankenphp/docker-entrypoint.sh /usr/local/bin/docker-entrypoint
COPY --link .docker/frankenphp/Caddyfile /etc/caddy/Caddyfile
COPY --link .docker/frankenphp/conf.d/app.prod.ini $PHP_INI_DIR/conf.d/
COPY --link .docker/frankenphp/worker.Caddyfile /etc/caddy/worker.Caddyfile
ENV FRANKENPHP_CONFIG="import worker.Caddyfile"
RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini"
# Install composer
ENV COMPOSER_ALLOW_SUPERUSER=1
#COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
# Create workdir and set permissions if directory does not exists
WORKDIR /app
# prevent the reinstallation of vendors at every changes in the source code
COPY --link composer.* symfony.* ./
RUN set -eux; \
composer install --no-cache --prefer-dist --no-dev --no-autoloader --no-scripts --no-progress
# copy sources
COPY --link . ./
# Install composer and yarn dependencies for Part-DB
RUN set -eux; \
mkdir -p var/cache var/log; \
composer dump-autoload --classmap-authoritative --no-dev; \
composer dump-env prod; \
composer run-script --no-dev post-install-cmd; \
chmod +x bin/console; sync;
RUN yarn install --network-timeout 600000 && \
yarn build && \
yarn cache clean && \
rm -rf node_modules/
# Use docker env to output logs to stdout
ENV APP_ENV=docker
ENV DATABASE_URL="sqlite:///%kernel.project_dir%/uploads/app.db"
USER root
ENTRYPOINT ["docker-entrypoint"]
CMD ["frankenphp", "run", "--config", "/etc/caddy/Caddyfile"]
# https://httpd.apache.org/docs/2.4/stopping.html#gracefulstop
STOPSIGNAL SIGWINCH
VOLUME ["/var/www/html/uploads", "/var/www/html/public/media"]
HEALTHCHECK --start-period=60s CMD curl -f http://localhost:2019/metrics || exit 1
# See https://caddyserver.com/docs/conventions#file-locations for details
ENV XDG_CONFIG_HOME /config
ENV XDG_DATA_HOME /data
EXPOSE 80
EXPOSE 443
EXPOSE 443/udp
EXPOSE 2019

View file

@ -30,7 +30,7 @@ If you want to test Part-DB without installing it, you can use [this](https://de
You can log in with username: *user* and password: *user*. You can log in with username: *user* and password: *user*.
Every change to the master branch gets automatically deployed, so it represents the current development progress and is Every change to the master branch gets automatically deployed, so it represents the current development progress and is
maybe not completely stable. Please mind, that the free Heroku instance is used, so it can take some time when loading may not completely stable. Please mind, that the free Heroku instance is used, so it can take some time when loading
the page the page
for the first time. for the first time.
@ -39,10 +39,10 @@ for the first time.
## Features ## Features
* Inventory management of your electronic parts. Each part can be assigned to a category, footprint, manufacturer * Inventory management of your electronic parts. Each part can be assigned to a category, footprint, manufacturer,
and multiple store locations and price information. Parts can be grouped using tags. You can associate various files and multiple store locations and price information. Parts can be grouped using tags. You can associate various files
like datasheets or pictures with the parts. like datasheets or pictures with the parts.
* Multi-Language support (currently German, English, Russian, Japanese and French (experimental)) * Multi-language support (currently German, English, Russian, Japanese, French, Czech, Danish, and Chinese)
* Barcodes/Labels generator for parts and storage locations, scan barcodes via webcam using the builtin barcode scanner * Barcodes/Labels generator for parts and storage locations, scan barcodes via webcam using the builtin barcode scanner
* User system with groups and detailed (fine granular) permissions. * User system with groups and detailed (fine granular) permissions.
Two-factor authentication is supported (Google Authenticator and Webauthn/U2F keys) and can be enforced for groups. Two-factor authentication is supported (Google Authenticator and Webauthn/U2F keys) and can be enforced for groups.
@ -52,33 +52,33 @@ for the first time.
* Import/Export system for parts and data structure. BOM import for projects from KiCAD is supported. * Import/Export system for parts and data structure. BOM import for projects from KiCAD is supported.
* Project management: Create projects and assign parts to the bill of material (BOM), to show how often you could build * Project management: Create projects and assign parts to the bill of material (BOM), to show how often you could build
this project and directly withdraw all components needed from DB this project and directly withdraw all components needed from DB
* Event log: Track what changes happens to your inventory, track which user does what. Revert your parts to older * Event log: Track what changes happen to your inventory, track which user does what. Revert your parts to older
versions. versions.
* Responsive design: You can use Part-DB on your PC, your tablet and your smartphone using the same interface. * Responsive design: You can use Part-DB on your PC, your tablet, and your smartphone using the same interface.
* MySQL and SQLite supported as database backends * MySQL, SQLite and PostgreSQL are supported as database backends
* Support for rich text descriptions and comments in parts * Support for rich text descriptions and comments in parts
* Support for multiple currencies and automatic update of exchange rates supported * Support for multiple currencies and automatic update of exchange rates supported
* Powerful search and filter function, including parametric search (search for parts according to some specifications) * Powerful search and filter function, including parametric search (search for parts according to some specifications)
* Automatic thumbnail generation for pictures * Automatic thumbnail generation for pictures
* Use cloud providers (like Octopart, Digikey, farnell or TME) to automatically get part information, datasheets and * Use cloud providers (like Octopart, Digikey, Farnell, LCSC or TME) to automatically get part information, datasheets, and
prices for parts prices for parts
* API to access Part-DB from other applications/scripts * API to access Part-DB from other applications/scripts
* [Integration with KiCad](https://docs.part-db.de/usage/eda_integration.html): Use Part-DB as central datasource for your * [Integration with KiCad](https://docs.part-db.de/usage/eda_integration.html): Use Part-DB as the central datasource for your
KiCad and see available parts from Part-DB directly inside KiCad. KiCad and see available parts from Part-DB directly inside KiCad.
With these features Part-DB is useful to hobbyists, who want to keep track of their private electronic parts inventory, With these features, Part-DB is useful to hobbyists, who want to keep track of their private electronic parts inventory,
or makerspaces, where many users have should have (controlled) access to the shared inventory. or maker spaces, where many users should have (controlled) access to the shared inventory.
Part-DB is also used by small companies and universities for managing their inventory. Part-DB is also used by small companies and universities for managing their inventory.
## Requirements ## Requirements
* A **web server** (like Apache2 or nginx) that is capable of * A **web server** (like Apache2 or nginx) that is capable of
running [Symfony 5](https://symfony.com/doc/current/reference/requirements.html), running [Symfony 6](https://symfony.com/doc/current/reference/requirements.html),
this includes a minimum PHP version of **PHP 8.1** this includes a minimum PHP version of **PHP 8.1**
* A **MySQL** (at least 5.7) /**MariaDB** (at least 10.2.2) database server if you do not want to use SQLite. * A **MySQL** (at least 5.7) /**MariaDB** (at least 10.4) database server, or **PostgreSQL** 10+ if you do not want to use SQLite.
* Shell access to your server is highly suggested! * Shell access to your server is highly recommended!
* For building the client side assets **yarn** and **nodejs** (>= 18.0) is needed. * For building the client-side assets **yarn** and **nodejs** (>= 18.0) is needed.
## Installation ## Installation
@ -88,8 +88,8 @@ read [this](https://docs.part-db.de/upgrade_legacy.html) first.
*Hint:* A docker image is available under [jbtronics/part-db1](https://hub.docker.com/r/jbtronics/part-db1). How to set *Hint:* A docker image is available under [jbtronics/part-db1](https://hub.docker.com/r/jbtronics/part-db1). How to set
up Part-DB via docker is described [here](https://docs.part-db.de/installation/installation_docker.html). up Part-DB via docker is described [here](https://docs.part-db.de/installation/installation_docker.html).
**Below you find some very rough outline of the installation process, see [here](https://docs.part-db.de/installation/) **Below you find a very rough outline of the installation process, see [here](https://docs.part-db.de/installation/)
for a detailed guide how to install Part-DB.** for a detailed guide on how to install Part-DB.**
1. Copy or clone this repository into a folder on your server. 1. Copy or clone this repository into a folder on your server.
2. Configure your webserver to serve from the `public/` folder. 2. Configure your webserver to serve from the `public/` folder.
@ -107,12 +107,12 @@ for a detailed guide how to install Part-DB.**
6. _Optional_ (speeds up first load): Warmup cache: `php bin/console cache:warmup` 6. _Optional_ (speeds up first load): Warmup cache: `php bin/console cache:warmup`
7. Upgrade database to new scheme (or create it, when it was empty): `php bin/console doctrine:migrations:migrate` and 7. Upgrade database to new scheme (or create it, when it was empty): `php bin/console doctrine:migrations:migrate` and
follow the instructions given. During the process the password for the admin is user is shown. Copy it. **Caution**: follow the instructions given. During the process the password for the admin is user is shown. Copy it. **Caution**:
This steps tamper with your database and could potentially destroy it. So make sure to make a backup of your These steps tamper with your database and could potentially destroy it. So make sure to make a backup of your
database. database.
8. You can configure Part-DB via `config/parameters.yaml`. You should check if settings match your expectations, after 8. You can configure Part-DB via `config/parameters.yaml`. You should check if settings match your expectations after
you installed/upgraded Part-DB. Check if `partdb.default_currency` matches your mainly used currency (this can not be you installed/upgraded Part-DB. Check if `partdb.default_currency` matches your mainly used currency (this can not be
changed after creating price information). changed after creating price information).
Run `php bin/console cache:clear` when you changed something. Run `php bin/console cache:clear` when you change something.
9. Access Part-DB in your browser (under the URL you put it) and log in with user *admin*. Password is the one outputted 9. Access Part-DB in your browser (under the URL you put it) and log in with user *admin*. Password is the one outputted
during DB setup. during DB setup.
If you can not remember the password, set a new one with `php bin/console app:set-password admin`. You can create If you can not remember the password, set a new one with `php bin/console app:set-password admin`. You can create
@ -122,23 +122,23 @@ When you want to upgrade to a newer version, then just copy the new files into t
and repeat the steps 4. to 7. and repeat the steps 4. to 7.
Normally a random password is generated when the admin user is created during initial database creation, Normally a random password is generated when the admin user is created during initial database creation,
however you can set the initial admin password, by setting the `INITIAL_ADMIN_PW` env var. however, you can set the initial admin password, by setting the `INITIAL_ADMIN_PW` env var.
You can configure Part-DB to your needs by changing environment variables in the `.env.local` file. You can configure Part-DB to your needs by changing environment variables in the `.env.local` file.
See [here](https://docs.part-db.de/configuration.html) for more information. See [here](https://docs.part-db.de/configuration.html) for more information.
### Reverse proxy ### Reverse proxy
If you are using a reverse proxy, you have to ensure that the proxies sets the `X-Forwarded-*` headers correctly, or you If you are using a reverse proxy, you have to ensure that the proxies set the `X-Forwarded-*` headers correctly, or you
will get HTTP/HTTPS mixup and wrong hostnames. will get HTTP/HTTPS mixup and wrong hostnames.
If the reverse proxy is on a different server (or it cannot access Part-DB via localhost) you have to set If the reverse proxy is on a different server (or it cannot access Part-DB via localhost) you have to set
the `TRUSTED_PROXIES` env variable to match your reverse proxies IP-address (or IP block). You can do this in the `TRUSTED_PROXIES` env variable to match your reverse proxy's IP address (or IP block). You can do this in
your `.env.local` or (when using docker) in your `docker-compose.yml` file. your `.env.local` or (when using docker) in your `docker-compose.yml` file.
## Donate for development ## Donate for development
If you want to donate to the Part-DB developer, see the sponsor button in the top bar (next to the repo name). If you want to donate to the Part-DB developer, see the sponsor button in the top bar (next to the repo name).
There you will find various methods to support development on a monthly or a one time base. There you will find various methods to support development on a monthly or a one-time base.
## Built with ## Built with

View file

@ -1 +1 @@
1.10.0 1.17.1

View file

@ -128,6 +128,8 @@ const PLACEHOLDERS = [
['[[BARCODE_QR]]', 'QR code linking to this element'], ['[[BARCODE_QR]]', 'QR code linking to this element'],
['[[BARCODE_C128]]', 'Code 128 barcode linking to this element'], ['[[BARCODE_C128]]', 'Code 128 barcode linking to this element'],
['[[BARCODE_C39]]', 'Code 39 barcode linking to this element'], ['[[BARCODE_C39]]', 'Code 39 barcode linking to this element'],
['[[BARCODE_C93]]', 'Code 93 barcode linking to this element'],
['[[BARCODE_DATAMATRIX]]', 'Datamatrix code linking to this element'],
] ]
}, },
{ {

View file

@ -69,6 +69,8 @@ Object.assign( window.CKEDITOR_TRANSLATIONS[ 'de' ].dictionary, {
'QR code linking to this element': 'QR Code verknüpft mit diesem Element', 'QR code linking to this element': 'QR Code verknüpft mit diesem Element',
'Code 128 barcode linking to this element': 'Code 128 Barcode verknüpft mit diesem Element', 'Code 128 barcode linking to this element': 'Code 128 Barcode verknüpft mit diesem Element',
'Code 39 barcode linking to this element': 'Code 39 Barcode verknüpft mit diesem Element', 'Code 39 barcode linking to this element': 'Code 39 Barcode verknüpft mit diesem Element',
'Code 93 barcode linking to this element': 'Code 93 Barcode verknüpft mit diesem Element',
'Datamatrix code linking to this element': 'Datamatrix Code verknüpft mit diesem Element',
'Location ID': 'Lagerort ID', 'Location ID': 'Lagerort ID',
'Name': 'Name', 'Name': 'Name',

View file

@ -88,5 +88,8 @@ export default class extends Controller {
} else { } else {
this.hideSidebar(); this.hideSidebar();
} }
//Hide the tootip on the button
this._toggle_button.blur();
} }
} }

View file

@ -20,18 +20,26 @@
'use strict'; 'use strict';
import { Controller } from '@hotwired/stimulus'; import { Controller } from '@hotwired/stimulus';
import { marked } from "marked"; import { Marked } from "marked";
import { mangle } from "marked-mangle"; import { mangle } from "marked-mangle";
import { gfmHeadingId } from "marked-gfm-heading-id"; import { gfmHeadingId } from "marked-gfm-heading-id";
import DOMPurify from 'dompurify'; import DOMPurify from 'dompurify';
import "../../css/app/markdown.css"; import "../../css/app/markdown.css";
export default class extends Controller { export default class MarkdownController extends Controller {
static _marked = new Marked([
{
gfm: true,
},
gfmHeadingId(),
mangle(),
])
;
connect() connect()
{ {
this.configureMarked();
this.render(); this.render();
//Dispatch an event that we are now finished //Dispatch an event that we are now finished
@ -45,7 +53,7 @@ export default class extends Controller {
let raw = this.element.dataset['markdown']; let raw = this.element.dataset['markdown'];
//Apply purified parsed markdown //Apply purified parsed markdown
this.element.innerHTML = DOMPurify.sanitize(marked(this.unescapeHTML(raw))); this.element.innerHTML = DOMPurify.sanitize(MarkdownController._marked.parse(this.unescapeHTML(raw)));
for(let a of this.element.querySelectorAll('a')) { for(let a of this.element.querySelectorAll('a')) {
//Mark all links as external //Mark all links as external
@ -81,8 +89,17 @@ export default class extends Controller {
/** /**
* Configure the marked parser * Configure the marked parser
*/ */
configureMarked() /*static newMarked()
{ {
const marked = new Marked([
{
gfm: true,
},
gfmHeadingId(),
mangle(),
])
;
marked.use(mangle()); marked.use(mangle());
marked.use(gfmHeadingId({ marked.use(gfmHeadingId({
})); }));
@ -90,5 +107,5 @@ export default class extends Controller {
marked.setOptions({ marked.setOptions({
gfm: true, gfm: true,
}); });
} }*/
} }

View file

@ -23,6 +23,12 @@ import "tom-select/dist/css/tom-select.bootstrap5.css";
import '../../css/components/tom-select_extensions.css'; import '../../css/components/tom-select_extensions.css';
import TomSelect from "tom-select"; import TomSelect from "tom-select";
import TomSelect_click_to_edit from '../../tomselect/click_to_edit/click_to_edit'
import TomSelect_autoselect_typed from '../../tomselect/autoselect_typed/autoselect_typed'
TomSelect.define('click_to_edit', TomSelect_click_to_edit)
TomSelect.define('autoselect_typed', TomSelect_autoselect_typed)
export default class extends Controller { export default class extends Controller {
_tomSelect; _tomSelect;
@ -46,6 +52,12 @@ export default class extends Controller {
} }
return '<div>' + escape(data.label) + '</div>'; return '<div>' + escape(data.label) + '</div>';
} }
},
plugins: {
'autoselect_typed': {},
'click_to_edit': {},
'clear_button': {},
"restore_on_backspace": {}
} }
}; };

View file

@ -53,6 +53,7 @@ export default class extends Controller {
const config = { const config = {
language: language, language: language,
licenseKey: "GPL",
} }
const watchdog = new EditorWatchdog(); const watchdog = new EditorWatchdog();
@ -70,7 +71,9 @@ export default class extends Controller {
editor_div.classList.add(...new_classes.split(",")); editor_div.classList.add(...new_classes.split(","));
} }
console.log(editor); //This return is important! Otherwise we get mysterious errors in the console
//See: https://github.com/ckeditor/ckeditor5/issues/5897#issuecomment-628471302
return editor;
}) })
.catch(error => { .catch(error => {
console.error(error); console.error(error);

View file

@ -75,13 +75,49 @@ export default class extends Controller {
//Insert new html after the last child element //Insert new html after the last child element
//If the table has a tbody, insert it there //If the table has a tbody, insert it there
//Afterwards return the newly created row
if(targetTable.tBodies[0]) { if(targetTable.tBodies[0]) {
targetTable.tBodies[0].insertAdjacentHTML('beforeend', newElementStr); targetTable.tBodies[0].insertAdjacentHTML('beforeend', newElementStr);
return targetTable.tBodies[0].lastElementChild;
} else { //Otherwise just insert it } else { //Otherwise just insert it
targetTable.insertAdjacentHTML('beforeend', newElementStr); targetTable.insertAdjacentHTML('beforeend', newElementStr);
return targetTable.lastElementChild;
} }
} }
/**
* This action opens a file dialog to select multiple files and then creates a new element for each file, where
* the file is assigned to the input field.
* This should only be used for attachments collection types
* @param event
*/
uploadMultipleFiles(event) {
//Open a file dialog to select multiple files
const input = document.createElement('input');
input.type = 'file';
input.multiple = true;
input.click();
input.addEventListener('change', (event) => {
//Create a element for each file
for (let i = 0; i < input.files.length; i++) {
const file = input.files[i];
const newElement = this.createElement(event);
const rowInput = newElement.querySelector("input[type='file']");
//We can not directly assign the file to the input, so we have to create a new DataTransfer object
const dataTransfer = new DataTransfer();
dataTransfer.items.add(file);
rowInput.files = dataTransfer.files;
}
});
}
/** /**
* Similar to createEvent Pricedetails need some special handling to fill min amount * Similar to createEvent Pricedetails need some special handling to fill min amount
* @param event * @param event

View file

@ -24,18 +24,25 @@ import 'datatables.net-bs5/css/dataTables.bootstrap5.css'
import 'datatables.net-buttons-bs5/css/buttons.bootstrap5.css' import 'datatables.net-buttons-bs5/css/buttons.bootstrap5.css'
import 'datatables.net-fixedheader-bs5/css/fixedHeader.bootstrap5.css' import 'datatables.net-fixedheader-bs5/css/fixedHeader.bootstrap5.css'
import 'datatables.net-responsive-bs5/css/responsive.bootstrap5.css'; import 'datatables.net-responsive-bs5/css/responsive.bootstrap5.css';
import 'datatables.net-select-bs5/css/select.bootstrap5.css';
//Use our own styles for the select extension which fit the bootstrap theme better
//import 'datatables.net-select-bs5/css/select.bootstrap5.css';
import '../../../css/components/datatables_select_bs5.css';
//JS //JS
import 'datatables.net-bs5'; import 'datatables.net-bs5';
import 'datatables.net-buttons-bs5'; import 'datatables.net-buttons-bs5';
import 'datatables.net-buttons/js/buttons.colVis.js'; import 'datatables.net-buttons/js/buttons.colVis.js';
import 'datatables.net-fixedheader-bs5'; import 'datatables.net-fixedheader-bs5';
import 'datatables.net-select-bs5';
import 'datatables.net-colreorder-bs5'; import 'datatables.net-colreorder-bs5';
import 'datatables.net-responsive-bs5'; import 'datatables.net-responsive-bs5';
import '../../../js/lib/datatables'; import '../../../js/lib/datatables';
//import 'datatables.net-select-bs5';
//Use the local version containing the fix for the select extension
import '../../../js/lib/dataTables.select.mjs';
const EVENT_DT_LOADED = 'dt:loaded'; const EVENT_DT_LOADED = 'dt:loaded';
export default class extends Controller { export default class extends Controller {
@ -132,7 +139,7 @@ export default class extends Controller {
if(this.isSelectable()) { if(this.isSelectable()) {
options.select = { options.select = {
style: 'multi+shift', style: 'multi+shift',
selector: 'td.select-checkbox' selector: 'td.dt-select',
}; };
} }
@ -145,6 +152,12 @@ export default class extends Controller {
//Fix height of the length selector //Fix height of the length selector
promise.then((dt) => { promise.then((dt) => {
//Draw the rows to make sure the correct status text is displayed ("No matching records found" instead of "Loading...")
if (dt.data().length === 0) {
dt.rows().draw()
}
//Find all length selectors (select with name dt_length), which are inside a label //Find all length selectors (select with name dt_length), which are inside a label
const lengthSelectors = document.querySelectorAll('label select[name="dt_length"]'); const lengthSelectors = document.querySelectorAll('label select[name="dt_length"]');
//And remove the surrounding label, while keeping the select with all event handlers //And remove the surrounding label, while keeping the select with all event handlers
@ -180,27 +193,6 @@ export default class extends Controller {
dt.fixedHeader.headerOffset($("#navbar").outerHeight()); dt.fixedHeader.headerOffset($("#navbar").outerHeight());
}); });
//Register event handler to selectAllRows checkbox if available
if (this.isSelectable()) {
promise.then((dt) => {
const selectAllCheckbox = this.element.querySelector('thead th.select-checkbox');
selectAllCheckbox.addEventListener('click', () => {
if(selectAllCheckbox.parentElement.classList.contains('selected')) {
dt.rows().deselect();
selectAllCheckbox.parentElement.classList.remove('selected');
} else {
dt.rows().select();
selectAllCheckbox.parentElement.classList.add('selected');
}
});
//When any row is deselected, also deselect the selectAll checkbox
dt.on('deselect.dt', () => {
selectAllCheckbox.parentElement.classList.remove('selected');
});
});
}
//Allow to further configure the datatable //Allow to further configure the datatable
promise.then(this._afterLoaded.bind(this)); promise.then(this._afterLoaded.bind(this));

View file

@ -0,0 +1,200 @@
/*
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
*
* Copyright (C) 2019 - 2024 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/>.
*/
import { Controller } from "@hotwired/stimulus";
import { autocomplete } from '@algolia/autocomplete-js';
//import "@algolia/autocomplete-theme-classic/dist/theme.css";
import "../../css/components/autocomplete_bootstrap_theme.css";
import { createLocalStorageRecentSearchesPlugin } from '@algolia/autocomplete-plugin-recent-searches';
import {marked} from "marked";
import {
trans,
SEARCH_PLACEHOLDER,
SEARCH_SUBMIT,
STATISTICS_PARTS
} from '../../translator';
/**
* This controller is responsible for the search fields in the navbar and the homepage.
* It uses the Algolia Autocomplete library to provide a fast and responsive search.
*/
export default class extends Controller {
static targets = ["input"];
_autocomplete;
// Highlight the search query in the results
_highlight = (text, query) => {
if (!text) return text;
if (!query) return text;
const HIGHLIGHT_PRE_TAG = '__aa-highlight__'
const HIGHLIGHT_POST_TAG = '__/aa-highlight__'
const escaped = query.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&');
const regex = new RegExp(escaped, 'gi');
return text.replace(regex, (match) => `${HIGHLIGHT_PRE_TAG}${match}${HIGHLIGHT_POST_TAG}`);
}
initialize() {
// The endpoint for searching parts
const base_url = this.element.dataset.autocomplete;
// The URL template for the part detail pages
const part_detail_uri_template = this.element.dataset.detailUrl;
//The URL of the placeholder picture
const placeholder_image = this.element.dataset.placeholderImage;
//If the element is in navbar mode, or not
const navbar_mode = this.element.dataset.navbarMode === "true";
const that = this;
const recentSearchesPlugin = createLocalStorageRecentSearchesPlugin({
key: 'RECENT_SEARCH',
limit: 5,
});
this._autocomplete = autocomplete({
container: this.element,
//Place the panel in the navbar, if the element is in navbar mode
panelContainer: navbar_mode ? document.getElementById("navbar-search-form") : document.body,
panelPlacement: this.element.dataset.panelPlacement,
plugins: [recentSearchesPlugin],
openOnFocus: true,
placeholder: trans(SEARCH_PLACEHOLDER),
translations: {
submitButtonTitle: trans(SEARCH_SUBMIT)
},
// Use a navigator compatible with turbo:
navigator: {
navigate({ itemUrl }) {
window.Turbo.visit(itemUrl, { action: "advance" });
},
navigateNewTab({ itemUrl }) {
const windowReference = window.open(itemUrl, '_blank', 'noopener');
if (windowReference) {
windowReference.focus();
}
},
navigateNewWindow({ itemUrl }) {
window.open(itemUrl, '_blank', 'noopener');
},
},
// If the form is submitted, forward the term to the form
onSubmit({state, event, ...setters}) {
//Put the current text into each target input field
const input = that.inputTarget;
if (!input) {
return;
}
//Do not submit the form, if the input is empty
if (state.query === "") {
return;
}
input.value = state.query;
input.form.requestSubmit();
},
getSources({ query }) {
return [
// The parts source
{
sourceId: 'parts',
getItems() {
const url = base_url.replace('__QUERY__', encodeURIComponent(query));
const data = fetch(url)
.then((response) => response.json())
;
//Iterate over all fields besides the id and highlight them
const fields = ["name", "description", "category", "footprint"];
data.then((items) => {
items.forEach((item) => {
for (const field of fields) {
item[field] = that._highlight(item[field], query);
}
});
});
return data;
},
getItemUrl({ item }) {
return part_detail_uri_template.replace('__ID__', item.id);
},
templates: {
header({ html }) {
return html`<span class="aa-SourceHeaderTitle">${trans(STATISTICS_PARTS)}</span>
<div class="aa-SourceHeaderLine" />`;
},
item({item, components, html}) {
const details_url = part_detail_uri_template.replace('__ID__', item.id);
return html`
<a class="aa-ItemLink" href="${details_url}">
<div class="aa-ItemContent">
<div class="aa-ItemIcon aa-ItemIcon--picture aa-ItemIcon--alignTop">
<img src="${item.image !== "" ? item.image : placeholder_image}" alt="${item.name}" width="30" height="30"/>
</div>
<div class="aa-ItemContentBody">
<div class="aa-ItemContentTitle">
<b>
${components.Highlight({hit: item, attribute: 'name'})}
</b>
</div>
<div class="aa-ItemContentDescription">
${components.Highlight({hit: item, attribute: 'description'})}
${item.category ? html`<p class="m-0"><span class="fa-solid fa-tags fa-fw"></span>${components.Highlight({hit: item, attribute: 'category'})}</p>` : ""}
${item.footprint ? html`<p class="m-0"><span class="fa-solid fa-microchip fa-fw"></span>${components.Highlight({hit: item, attribute: 'footprint'})}</p>` : ""}
</div>
</div>
</div>
</a>
`;
},
},
},
];
},
});
//Try to find the input field and register a defocus handler. This is necessarry, as by default the autocomplete
//lib has problems when multiple inputs are present on the page. (see https://github.com/algolia/autocomplete/issues/1216)
const inputs = this.element.getElementsByClassName('aa-Input');
for (const input of inputs) {
input.addEventListener('blur', () => {
this._autocomplete.setIsOpen(false);
});
}
}
}

View file

@ -23,6 +23,12 @@ import "tom-select/dist/css/tom-select.bootstrap5.css";
import '../../css/components/tom-select_extensions.css'; import '../../css/components/tom-select_extensions.css';
import TomSelect from "tom-select"; import TomSelect from "tom-select";
import TomSelect_click_to_edit from '../../tomselect/click_to_edit/click_to_edit'
import TomSelect_autoselect_typed from '../../tomselect/autoselect_typed/autoselect_typed'
TomSelect.define('click_to_edit', TomSelect_click_to_edit)
TomSelect.define('autoselect_typed', TomSelect_autoselect_typed)
/** /**
* This is the frontend controller for StaticFileAutocompleteType form element. * This is the frontend controller for StaticFileAutocompleteType form element.
* Basically it loads a text file from the given url (via data-url) and uses it as a source for the autocomplete. * Basically it loads a text file from the given url (via data-url) and uses it as a source for the autocomplete.
@ -46,7 +52,13 @@ export default class extends Controller {
orderField: 'text', orderField: 'text',
//This a an ugly solution to disable the delimiter parsing of the TomSelect plugin //This a an ugly solution to disable the delimiter parsing of the TomSelect plugin
delimiter: 'VERY_L0NG_D€LIMITER_WHICH_WILL_NEVER_BE_ENCOUNTERED_IN_A_STRING' delimiter: 'VERY_L0NG_D€LIMITER_WHICH_WILL_NEVER_BE_ENCOUNTERED_IN_A_STRING',
plugins: {
'autoselect_typed': {},
'click_to_edit': {},
'clear_button': {},
'restore_on_backspace': {}
}
}; };
if (this.element.dataset.url) { if (this.element.dataset.url) {

View file

@ -24,6 +24,8 @@ import {Controller} from "@hotwired/stimulus";
import {trans, ENTITY_SELECT_GROUP_NEW_NOT_ADDED_TO_DB} from '../../translator.js' import {trans, ENTITY_SELECT_GROUP_NEW_NOT_ADDED_TO_DB} from '../../translator.js'
import TomSelect_autoselect_typed from '../../tomselect/autoselect_typed/autoselect_typed'
TomSelect.define('autoselect_typed', TomSelect_autoselect_typed)
export default class extends Controller { export default class extends Controller {
_tomSelect; _tomSelect;
@ -38,11 +40,20 @@ export default class extends Controller {
const allowAdd = this.element.getAttribute("data-allow-add") === "true"; const allowAdd = this.element.getAttribute("data-allow-add") === "true";
const addHint = this.element.getAttribute("data-add-hint") ?? ""; const addHint = this.element.getAttribute("data-add-hint") ?? "";
let settings = { let settings = {
allowEmptyOption: true, allowEmptyOption: true,
selectOnTab: true, selectOnTab: true,
maxOptions: null, maxOptions: null,
create: allowAdd ? this.createItem.bind(this) : false, create: allowAdd ? this.createItem.bind(this) : false,
createFilter: this.createFilter.bind(this),
// This three options allow us to paste element names with commas: (see issue #538)
maxItems: 1,
delimiter: "$$VERY_LONG_DELIMITER_THAT_SHOULD_NEVER_APPEAR$$",
splitOn: null,
searchField: [ searchField: [
{field: "text", weight : 2}, {field: "text", weight : 2},
@ -53,7 +64,21 @@ export default class extends Controller {
render: { render: {
item: this.renderItem.bind(this), item: this.renderItem.bind(this),
option: this.renderOption.bind(this), option: this.renderOption.bind(this),
option_create: function(data, escape) { option_create: (data, escape) => {
//If the input starts with "->", we prepend the current selected value, for easier extension of existing values
//This here handles the display part, while the createItem function handles the actual creation
if (data.input.startsWith("->")) {
//Get current selected value
const current = this._tomSelect.getItem(this._tomSelect.getValue()).textContent.replaceAll("→", "->").trim();
//Prepend it to the input
if (current) {
data.input = current + " " + data.input;
} else {
//If there is no current value, we remove the "->"
data.input = data.input.substring(2);
}
}
return '<div class="create"><i class="fa-solid fa-plus fa-fw"></i>&nbsp;<strong>' + escape(data.input) + '</strong>&hellip;&nbsp;' + return '<div class="create"><i class="fa-solid fa-plus fa-fw"></i>&nbsp;<strong>' + escape(data.input) + '</strong>&hellip;&nbsp;' +
'<small class="text-muted float-end">(' + addHint +')</small>' + '<small class="text-muted float-end">(' + addHint +')</small>' +
'</div>'; '</div>';
@ -63,14 +88,39 @@ export default class extends Controller {
//Add callbacks to update validity //Add callbacks to update validity
onInitialize: this.updateValidity.bind(this), onInitialize: this.updateValidity.bind(this),
onChange: this.updateValidity.bind(this), onChange: this.updateValidity.bind(this),
plugins: {
"autoselect_typed": {},
}
}; };
//Add clear button plugin, if an empty option is present
if (this.element.querySelector("option[value='']") !== null) {
settings.plugins["clear_button"] = {};
}
this._tomSelect = new TomSelect(this.element, settings); this._tomSelect = new TomSelect(this.element, settings);
//Do not do a sync here as this breaks the initial rendering of the empty option //Do not do a sync here as this breaks the initial rendering of the empty option
//this._tomSelect.sync(); //this._tomSelect.sync();
} }
createItem(input, callback) { createItem(input, callback) {
//If the input starts with "->", we prepend the current selected value, for easier extension of existing values
if (input.startsWith("->")) {
//Get current selected value
let current = this._tomSelect.getItem(this._tomSelect.getValue()).textContent.replaceAll("→", "->").trim();
//Replace no break spaces with normal spaces
current = current.replaceAll("\u00A0", " ");
//Prepend it to the input
if (current) {
input = current + " " + input;
} else {
//If there is no current value, we remove the "->"
input = input.substring(2);
}
}
callback({ callback({
//$%$ is a special value prefix, that is used to identify items, that are not yet in the DB //$%$ is a special value prefix, that is used to identify items, that are not yet in the DB
value: '$%$' + input, value: '$%$' + input,
@ -79,6 +129,31 @@ export default class extends Controller {
}); });
} }
createFilter(input) {
//Normalize the input (replace spacing around arrows)
if (input.includes("->")) {
const inputs = input.split("->");
inputs.forEach((value, index) => {
inputs[index] = value.trim();
});
input = inputs.join("->");
} else {
input = input.trim();
}
const options = this._tomSelect.options;
//Iterate over all options and check if the input is already present
for (let index in options) {
const option = options[index];
if (option.path === input) {
return false;
}
}
return true;
}
updateValidity() { updateValidity() {
//Mark this input as invalid, if the selected option is disabled //Mark this input as invalid, if the selected option is disabled

View file

@ -23,14 +23,21 @@ import "tom-select/dist/css/tom-select.bootstrap5.css";
import '../../css/components/tom-select_extensions.css'; import '../../css/components/tom-select_extensions.css';
import TomSelect from "tom-select"; import TomSelect from "tom-select";
import TomSelect_click_to_edit from '../../tomselect/click_to_edit/click_to_edit'
import TomSelect_autoselect_typed from '../../tomselect/autoselect_typed/autoselect_typed'
TomSelect.define('click_to_edit', TomSelect_click_to_edit)
TomSelect.define('autoselect_typed', TomSelect_autoselect_typed)
export default class extends Controller { export default class extends Controller {
_tomSelect; _tomSelect;
connect() { connect() {
let settings = { let settings = {
plugins: { plugins: {
remove_button:{ remove_button:{},
} 'autoselect_typed': {},
'click_to_edit': {},
}, },
persistent: false, persistent: false,
selectOnTab: true, selectOnTab: true,

View file

@ -94,13 +94,15 @@ export default class extends Controller {
showTags: this._showTags, showTags: this._showTags,
data: data, data: data,
showIcon: true, showIcon: true,
preventUnselect: true,
allowReselect: true,
onNodeSelected: (event) => { onNodeSelected: (event) => {
const node = event.detail.node; const node = event.detail.node;
if (node.href) { if (node.href) {
window.Turbo.visit(node.href, {action: "advance"}); window.Turbo.visit(node.href, {action: "advance"});
this._registerURLWatcher(node);
} }
}, },
//onNodeContextmenu: contextmenu_handler,
}, [BS5Theme, BS53Theme, FAIconTheme]); }, [BS5Theme, BS53Theme, FAIconTheme]);
this.treeTarget.addEventListener(EVENT_INITIALIZED, (event) => { this.treeTarget.addEventListener(EVENT_INITIALIZED, (event) => {
@ -108,12 +110,42 @@ export default class extends Controller {
const treeView = event.detail.treeView; const treeView = event.detail.treeView;
treeView.revealNode(treeView.getSelected()); treeView.revealNode(treeView.getSelected());
//Add the url watcher to all selected nodes
for (const node of treeView.getSelected()) {
this._registerURLWatcher(node);
}
//Add contextmenu event listener to the tree, which allows us to open the links in a new tab with a right click //Add contextmenu event listener to the tree, which allows us to open the links in a new tab with a right click
treeView.getTreeElement().addEventListener("contextmenu", this._onContextMenu.bind(this)); treeView.getTreeElement().addEventListener("contextmenu", this._onContextMenu.bind(this));
}); });
} }
_registerURLWatcher(node)
{
//Register a watcher for a location change, which will unselect the node, if the location changes
const desired_url = node.href;
//Ensure that the node is unselected, if the location changes
const unselectNode = () => {
//Parse url so we can properly compare them
const desired = new URL(node.href, window.location.origin);
//We only compare the pathname, because the hash and parameters should not matter
if(window.location.pathname !== desired.pathname) {
//The ignore parameter is important here, otherwise the node will not be unselected
node.setSelected(false, {silent: true, ignorePreventUnselect: true});
//Unregister the watcher
document.removeEventListener('turbo:load', unselectNode);
}
};
//Register the watcher via hotwire turbo
//We must just load to have the new url in window.location
document.addEventListener('turbo:load', unselectNode);
}
_onContextMenu(event) _onContextMenu(event)
{ {
//Find the node that was clicked and open link in new tab //Find the node that was clicked and open link in new tab

View file

@ -20,7 +20,7 @@
import {Controller} from "@hotwired/stimulus"; import {Controller} from "@hotwired/stimulus";
//import * as ZXing from "@zxing/library"; //import * as ZXing from "@zxing/library";
import {Html5QrcodeScanner, Html5Qrcode} from "html5-qrcode"; import {Html5QrcodeScanner, Html5Qrcode} from "@part-db/html5-qrcode";
/* stimulusFetch: 'lazy' */ /* stimulusFetch: 'lazy' */
export default class extends Controller { export default class extends Controller {
@ -50,7 +50,7 @@ export default class extends Controller {
}); });
this._scanner = new Html5QrcodeScanner(this.element.id, { this._scanner = new Html5QrcodeScanner(this.element.id, {
fps: 2, fps: 10,
qrbox: qrboxFunction, qrbox: qrboxFunction,
experimentalFeatures: { experimentalFeatures: {
//This option improves reading quality on android chrome //This option improves reading quality on android chrome
@ -61,6 +61,11 @@ export default class extends Controller {
this._scanner.render(this.onScanSuccess.bind(this)); this._scanner.render(this.onScanSuccess.bind(this));
} }
disconnect() {
this._scanner.pause();
this._scanner.clear();
}
onScanSuccess(decodedText, decodedResult) { onScanSuccess(decodedText, decodedResult) {
//Put our decoded Text into the input box //Put our decoded Text into the input box
document.getElementById('scan_dialog_input').value = decodedText; document.getElementById('scan_dialog_input').value = decodedText;

View file

@ -25,9 +25,20 @@ import "katex/dist/katex.css";
export default class extends Controller { export default class extends Controller {
static targets = ["input", "preview"]; static targets = ["input", "preview"];
static values = {
unit: {type: Boolean, default: false} //Render as upstanding (non-italic) text, useful for units
}
updatePreview() updatePreview()
{ {
katex.render(this.inputTarget.value, this.previewTarget, { let value = "";
if (this.unitValue) {
value = "\\mathrm{" + this.inputTarget.value + "}";
} else {
value = this.inputTarget.value;
}
katex.render(value, this.previewTarget, {
throwOnError: false, throwOnError: false,
}); });
} }

View file

@ -22,6 +22,13 @@ import TomSelect from "tom-select";
import katex from "katex"; import katex from "katex";
import "katex/dist/katex.css"; import "katex/dist/katex.css";
import TomSelect_click_to_edit from '../../tomselect/click_to_edit/click_to_edit'
import TomSelect_autoselect_typed from '../../tomselect/autoselect_typed/autoselect_typed'
TomSelect.define('click_to_edit', TomSelect_click_to_edit)
TomSelect.define('autoselect_typed', TomSelect_autoselect_typed)
/* stimulusFetch: 'lazy' */ /* stimulusFetch: 'lazy' */
export default class extends Controller export default class extends Controller
{ {
@ -53,7 +60,10 @@ export default class extends Controller
connect() { connect() {
const settings = { const settings = {
plugins: { plugins: {
clear_button:{} 'autoselect_typed': {},
'click_to_edit': {},
'clear_button': {},
'restore_on_backspace': {}
}, },
persistent: false, persistent: false,
maxItems: 1, maxItems: 1,

View file

@ -112,3 +112,10 @@ ul.structural_link li a:hover {
background-color: var(--bs-success); background-color: var(--bs-success);
border-color: var(--bs-success); border-color: var(--bs-success);
} }
/***********************************************
* Katex rendering with same height as text
***********************************************/
.katex-same-height-as-text .katex {
font-size: 1.0em;
}

View file

@ -51,7 +51,6 @@
.part-table-image { .part-table-image {
max-height: 40px; max-height: 40px;
object-fit: contain; object-fit: contain;
width: 100%;
} }
.part-info-image { .part-info-image {

View file

@ -108,8 +108,8 @@ body {
.back-to-top { .back-to-top {
cursor: pointer; cursor: pointer;
position: fixed; position: fixed;
bottom: 20px; bottom: 60px;
right: 20px; right: 40px;
display:none; display:none;
z-index: 1030; z-index: 1030;
} }

View file

@ -63,10 +63,6 @@ table.dataTable > tbody > tr.selected > td > a {
margin-block-end: 0; margin-block-end: 0;
} }
.card-footer-table {
padding-top: 0;
}
table.dataTable { table.dataTable {
margin-top: 0 !important; margin-top: 0 !important;
} }
@ -84,7 +80,7 @@ th.select-checkbox {
* Datatables definitions/overrides * Datatables definitions/overrides
********************************************************************/ ********************************************************************/
.dataTables_length { .dt-length {
display: inline-flex; display: inline-flex;
} }
@ -94,6 +90,16 @@ table.dataTable tr.selected td.select-checkbox:after
margin-top: -20px !important; margin-top: -20px !important;
} }
/** Show pagination right aligned */
.dt-paging .pagination {
justify-content: flex-end;
}
/** Fix table row coloring */
table.table.dataTable > :not(caption) > * > * {
background-color: var(--bs-table-bg);
}
/****************************************************** /******************************************************
Classes for Datatables export Classes for Datatables export
@ -104,52 +110,3 @@ Classes for Datatables export
.export-helper{ .export-helper{
display: none; display: none;
} }
/******************************************************
* Styling for the select all checkbox in the parts table
* Should match the styling of the select checkbox
******************************************************/
table.dataTable > thead > tr > th.select-checkbox {
position: relative;
}
table.dataTable > thead > tr > th.select-checkbox:before,
table.dataTable > thead > tr > th.select-checkbox:after {
display: block;
position: absolute;
top: 0.9em;
left: 50%;
width: 1em !important;
height: 1em !important;
box-sizing: border-box;
}
table.dataTable > thead > tr > th.select-checkbox:before {
content: " ";
margin-top: -5px;
margin-left: -6px;
border: 2px solid var(--bs-tertiary-color);
border-radius: 3px;
}
table.dataTable > tbody > tr > td.select-checkbox:before, table.dataTable > tbody > tr > th.select-checkbox:before {
border: 2px solid var(--bs-tertiary-color) !important;
}
table.dataTable > tbody > tr > td.select-checkbox:before, table.dataTable > tbody > tr > td.select-checkbox:after, table.dataTable > tbody > tr > th.select-checkbox:before, table.dataTable > tbody > tr > th.select-checkbox:after {
width: 1em !important;
height: 1em !important;
}
table.dataTable > thead > tr.selected > th.select-checkbox:after {
content: "✓";
font-size: 20px;
margin-top: -20px;
margin-left: -6px;
text-align: center;
/*text-shadow: 1px 1px #B0BED9, -1px -1px #B0BED9, 1px -1px #B0BED9, -1px 1px #B0BED9; */
}
table.dataTable.compact > thead > tr > th.select-checkbox:before {
margin-top: -12px;
}
table.dataTable.compact > thead > tr.selected > th.select-checkbox:after {
margin-top: -16px;
}

File diff suppressed because it is too large Load diff

View file

@ -24,9 +24,8 @@
/** Should be the same settings, as in label_style.css */ /** Should be the same settings, as in label_style.css */
.ck-html-label .ck-content { .ck-html-label .ck-content {
font-family: "DejaVu Sans Mono", monospace; font-family: "DejaVu Sans Mono", monospace;
font-size: 12px; font-size: 12pt;
line-height: 1.0; line-height: 1.0;
font-size-adjust: 1.5;
} }
.ck-html-label .ck-content p { .ck-html-label .ck-content p {

View file

@ -0,0 +1,69 @@
/******************************************************************************************
* This styles the checkboxes of the select extension exactly like the ones in bootstrap 5
******************************************************************************************/
table.dataTable > tbody > tr > .selected {
background-color: var(--bs-primary-bg-subtle) !important;
color: white;
}
table.dataTable > tbody > tr > .dt-select {
text-align: center;
vertical-align: middle;
}
table.dataTable > thead > tr > .dt-select {
text-align: center;
}
table.dataTable input.dt-select-checkbox {
--bs-form-check-bg: var(--bs-body-bg);
flex-shrink: 0;
width: 1em;
height: 1em;
margin-top: 0.25em;
vertical-align: top;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
background-color: var(--bs-form-check-bg);
background-image: var(--bs-form-check-bg-image);
background-repeat: no-repeat;
background-position: center;
background-size: contain;
border: var(--bs-border-width) solid var(--bs-border-color);
-webkit-print-color-adjust: exact;
color-adjust: exact;
print-color-adjust: exact;
border-radius: 0.25em;
}
table.dataTable input.dt-select-checkbox:checked {
background-color: rgb(var(--bs-secondary-rgb));
border-color: rgb(var(--bs-secondary-rgb));
--bs-form-check-bg-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='m6 10 3 3 6-6'/%3e%3c/svg%3e");
}
table.dataTable input.dt-select-checkbox:indeterminate {
background-color: rgb(var(--bs-secondary-rgb));
border-color: rgb(var(--bs-secondary-rgb));
--bs-form-check-bg-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10h8'/%3e%3c/svg%3e");
}
div.dt-container span.select-info,
div.dt-container span.select-item {
margin-left: 0.5em;
}
@media screen and (max-width: 640px) {
div.dt-container span.select-info,
div.dt-container span.select-item {
margin-left: 0;
display: block;
}
}
table.dataTable.table-sm tbody td.select-checkbox::before {
margin-top: -9px;
}

File diff suppressed because it is too large Load diff

View file

@ -44,4 +44,18 @@ import "./register_events";
import "./tristate_checkboxes"; import "./tristate_checkboxes";
//Define jquery globally //Define jquery globally
window.$ = window.jQuery = require("jquery") window.$ = window.jQuery = require("jquery");
//Use the local WASM file for the ZXing library
import {
setZXingModuleOverrides,
} from "barcode-detector/pure";
import wasmFile from "../../node_modules/zxing-wasm/dist/reader/zxing_reader.wasm";
setZXingModuleOverrides({
locateFile: (path, prefix) => {
if (path.endsWith(".wasm")) {
return wasmFile;
}
return prefix + path;
},
});

File diff suppressed because it is too large Load diff

View file

@ -98,6 +98,15 @@
dtOpts = config.options(dtOpts); dtOpts = config.options(dtOpts);
} }
//Choose the column where the className contains "select-column" and apply the select extension to its render field
//Added for Part-DB
for (let column of dtOpts.columns) {
if (column.className && column.className.includes('dt-select')) {
column.render = $.fn.dataTable.render.select();
}
}
root.html(data.template); root.html(data.template);
dt = $('table', root).DataTable(dtOpts); dt = $('table', root).DataTable(dtOpts);
if (config.state !== 'none') { if (config.state !== 'none') {

View file

@ -21,6 +21,7 @@
import {Dropdown} from "bootstrap"; import {Dropdown} from "bootstrap";
import ClipboardJS from "clipboard"; import ClipboardJS from "clipboard";
import {Modal} from "bootstrap";
class RegisterEventHelper { class RegisterEventHelper {
constructor() { constructor() {
@ -31,9 +32,11 @@ class RegisterEventHelper {
//Initialize ClipboardJS //Initialize ClipboardJS
this.registerLoadHandler(() => { this.registerLoadHandler(() => {
new ClipboardJS('.btn'); new ClipboardJS('.btn');
}) });
this.registerModalDropRemovalOnFormSubmit(); this.registerModalDropRemovalOnFormSubmit();
} }
registerModalDropRemovalOnFormSubmit() { registerModalDropRemovalOnFormSubmit() {
@ -43,6 +46,15 @@ class RegisterEventHelper {
if (back_drop) { if (back_drop) {
back_drop.remove(); back_drop.remove();
} }
//Remove scroll-lock if it is still active
if (document.body.classList.contains('modal-open')) {
document.body.classList.remove('modal-open');
//Remove the padding-right and overflow:hidden from the body
document.body.style.paddingRight = '';
document.body.style.overflow = '';
}
}); });
} }

View file

@ -0,0 +1,63 @@
/**
* Autoselect Typed plugin for Tomselect
*
* This plugin allows automatically selecting an option matching the typed text when the Tomselect element goes out of
* focus (is blurred) and/or when the delimiter is typed.
*
* #select_on_blur option
* Tomselect natively supports the "createOnBlur" option. This option picks up any remaining text in the input field
* and uses it to create a new option and selects that option. It does behave a bit strangely though, in that it will
* not select an already existing option when the input is blurred, so if you typed something that matches an option in
* the list and then click outside the box (without pressing enter) the entered text is just removed (unless you have
* allow duplicates on in which case it will create a new option).
* This plugin fixes that, such that Tomselect will first try to select an option matching the remaining uncommitted
* text and only when no matching option is found tries to create a new one (if createOnBlur and create is on)
*
* #select_on_delimiter option
* Normally when typing the delimiter (space by default) Tomselect will try to create a new option (and select it) (if
* create is on), but if the typed text matches an option (and allow duplicates is off) it refuses to react at all until
* you press enter. With this option, the delimiter will also allow selecting an option, not just creating it.
*/
function select_current_input(self){
if(self.isLocked){
return
}
const val = self.inputValue()
//Do nothing if the input is empty
if (!val) {
return
}
if (self.options[val]) {
self.addItem(val)
self.setTextboxValue()
}
}
export default function(plugin_options_) {
const plugin_options = Object.assign({
//Autoselect the typed text when the input element goes out of focus
select_on_blur: true,
//Autoselect the typed text when the delimiter is typed
select_on_delimiter: true,
}, plugin_options_);
const self = this
if(plugin_options.select_on_blur) {
this.hook("before", "onBlur", function () {
select_current_input(self)
})
}
if(plugin_options.select_on_delimiter) {
this.hook("before", "onKeyPress", function (e) {
const character = String.fromCharCode(e.keyCode || e.which);
if (self.settings.mode === 'multi' && character === self.settings.delimiter) {
select_current_input(self)
}
})
}
}

View file

@ -0,0 +1,93 @@
/**
* click_to_edit plugin for Tomselect
*
* This plugin allows editing (and selecting text in) any selected item by clicking it.
*
* Usually, when the user typed some text and created an item in Tomselect that item cannot be edited anymore. To make
* a change, the item has to be deleted and retyped completely. There is also generally no way to copy text out of a
* tomselect item. The "restore_on_backspace" plugin improves that somewhat, by allowing the user to edit an item after
* pressing backspace. However, it is somewhat confusing to first have to focus the field an then hit backspace in order
* to copy a piece of text. It may also not be immediately obvious for editing.
* This plugin transforms an item into editable text when it is clicked, e.g. when the user tries to place the caret
* within an item or when they try to drag across the text to highlight it.
* It also plays nice with the remove_button plugin which still removes (deselects) an option entirely.
*
* It is recommended to also enable the autoselect_typed plugin when using this plugin. Without it, the text in the
* input field (i.e. the item that was just clicked) is lost when the user clicks outside the field. Also, when the user
* clicks an option (making it text) and then tries to enter another one by entering the delimiter (e.g. space) nothing
* happens until enter is pressed or the text is changed from what it was.
*/
/**
* Return a dom element from either a dom query string, jQuery object, a dom element or html string
* https://stackoverflow.com/questions/494143/creating-a-new-dom-element-from-an-html-string-using-built-in-dom-methods-or-pro/35385518#35385518
*
* param query should be {}
*/
const getDom = query => {
if (query.jquery) {
return query[0];
}
if (query instanceof HTMLElement) {
return query;
}
if (isHtmlString(query)) {
var tpl = document.createElement('template');
tpl.innerHTML = query.trim(); // Never return a text node of whitespace as the result
return tpl.content.firstChild;
}
return document.querySelector(query);
};
const isHtmlString = arg => {
if (typeof arg === 'string' && arg.indexOf('<') > -1) {
return true;
}
return false;
};
function plugin(plugin_options_) {
const self = this
const plugin_options = Object.assign({
//If there is unsubmitted text in the input field, should that text be automatically used to select a matching
//element? If this is off, clicking on item1 and then clicking on item2 will result in item1 being deselected
auto_select_before_edit: true,
//If there is unsubmitted text in the input field, should that text be automatically used to create a matching
//element if no matching element was found or auto_select_before_edit is off?
auto_create_before_edit: true,
//customize this function to change which text the item is replaced with when clicking on it
text: option => {
return option[self.settings.labelField];
}
}, plugin_options_);
self.hook('after', 'setupTemplates', () => {
const orig_render_item = self.settings.render.item;
self.settings.render.item = (data, escape) => {
const item = getDom(orig_render_item.call(self, data, escape));
item.addEventListener('click', evt => {
if (self.isLocked) {
return;
}
const val = self.inputValue();
if (self.options[val]) {
self.addItem(val)
} else if (self.settings.create) {
self.createItem();
}
const option = self.options[item.dataset.value]
self.setTextboxValue(plugin_options.text.call(self, option));
self.focus();
self.removeItem(item);
}
);
return item;
}
});
}
export { plugin as default };

View file

@ -4,6 +4,10 @@
use App\Kernel; use App\Kernel;
use Symfony\Bundle\FrameworkBundle\Console\Application; use Symfony\Bundle\FrameworkBundle\Console\Application;
if (!is_dir(dirname(__DIR__).'/vendor')) {
throw new LogicException('Dependencies are missing. Try running "composer install".');
}
//Increase xdebug.max_nesting_level to 1000 if required (see issue #411) //Increase xdebug.max_nesting_level to 1000 if required (see issue #411)
//Check if xdebug extension is active, and xdebug.max_nesting_level is set to 256 or lower //Check if xdebug extension is active, and xdebug.max_nesting_level is set to 256 or lower
if (extension_loaded('xdebug') && ((int) ini_get('xdebug.max_nesting_level')) <= 256) { if (extension_loaded('xdebug') && ((int) ini_get('xdebug.max_nesting_level')) <= 256) {

View file

@ -1,4 +1,5 @@
{ {
"name": "part-db/part-db-server",
"type": "project", "type": "project",
"license": "AGPL-3.0-or-later", "license": "AGPL-3.0-or-later",
"require": { "require": {
@ -10,21 +11,23 @@
"ext-intl": "*", "ext-intl": "*",
"ext-json": "*", "ext-json": "*",
"ext-mbstring": "*", "ext-mbstring": "*",
"amphp/http-client": "^5.1",
"api-platform/core": "^3.1", "api-platform/core": "^3.1",
"beberlei/doctrineextensions": "^1.2", "beberlei/doctrineextensions": "^1.2",
"brick/math": "0.12.1 as 0.11.0", "brick/math": "0.12.1 as 0.11.0",
"composer/ca-bundle": "^1.5",
"composer/package-versions-deprecated": "^1.11.99.5", "composer/package-versions-deprecated": "^1.11.99.5",
"doctrine/annotations": "1.14.3", "doctrine/data-fixtures": "^2.0.0",
"doctrine/data-fixtures": "^1.6.6", "doctrine/dbal": "^4.0.0",
"doctrine/dbal": "^3.4.6",
"doctrine/doctrine-bundle": "^2.0", "doctrine/doctrine-bundle": "^2.0",
"doctrine/doctrine-migrations-bundle": "^3.0", "doctrine/doctrine-migrations-bundle": "^3.0",
"doctrine/orm": "^2.16", "doctrine/orm": "^3.2.0",
"dompdf/dompdf": "dev-master#511e7e0 as v2.0.3", "dompdf/dompdf": "^v3.0.0",
"erusev/parsedown": "^1.7", "erusev/parsedown": "^1.7",
"florianv/swap": "^4.0", "florianv/swap": "^4.0",
"florianv/swap-bundle": "dev-master", "florianv/swap-bundle": "dev-master",
"gregwar/captcha-bundle": "^2.1.0", "gregwar/captcha-bundle": "^2.1.0",
"hshn/base64-encoded-file": "^5.0",
"jbtronics/2fa-webauthn": "^v2.2.0", "jbtronics/2fa-webauthn": "^v2.2.0",
"jbtronics/dompdf-font-loader-bundle": "^1.0.0", "jbtronics/dompdf-font-loader-bundle": "^1.0.0",
"jfcherng/php-diff": "^6.14", "jfcherng/php-diff": "^6.14",
@ -37,12 +40,11 @@
"nelmio/cors-bundle": "^2.3", "nelmio/cors-bundle": "^2.3",
"nelmio/security-bundle": "^3.0", "nelmio/security-bundle": "^3.0",
"nyholm/psr7": "^1.1", "nyholm/psr7": "^1.1",
"ocramius/proxy-manager": "2.2.*", "omines/datatables-bundle": "^0.9.1",
"omines/datatables-bundle": "^0.8.0", "paragonie/sodium_compat": "^1.21",
"part-db/label-fonts": "^1.0", "part-db/label-fonts": "^1.0",
"php-translation/symfony-bundle": "^0.14.0", "rhukster/dom-sanitizer": "^1.0",
"phpdocumentor/reflection-docblock": "^5.2", "runtime/frankenphp-symfony": "^0.2.0",
"phpstan/phpdoc-parser": "^1.23",
"s9e/text-formatter": "^2.1", "s9e/text-formatter": "^2.1",
"scheb/2fa-backup-code": "^6.8.0", "scheb/2fa-backup-code": "^6.8.0",
"scheb/2fa-bundle": "^6.8.0", "scheb/2fa-bundle": "^6.8.0",
@ -53,6 +55,8 @@
"symfony/apache-pack": "^1.0", "symfony/apache-pack": "^1.0",
"symfony/asset": "6.4.*", "symfony/asset": "6.4.*",
"symfony/console": "6.4.*", "symfony/console": "6.4.*",
"symfony/css-selector": "6.4.*",
"symfony/dom-crawler": "6.4.*",
"symfony/dotenv": "6.4.*", "symfony/dotenv": "6.4.*",
"symfony/expression-language": "6.4.*", "symfony/expression-language": "6.4.*",
"symfony/flex": "^v2.3.1", "symfony/flex": "^v2.3.1",
@ -66,7 +70,6 @@
"symfony/process": "6.4.*", "symfony/process": "6.4.*",
"symfony/property-access": "6.4.*", "symfony/property-access": "6.4.*",
"symfony/property-info": "6.4.*", "symfony/property-info": "6.4.*",
"symfony/proxy-manager-bridge": "6.4.*",
"symfony/rate-limiter": "6.4.*", "symfony/rate-limiter": "6.4.*",
"symfony/runtime": "6.4.*", "symfony/runtime": "6.4.*",
"symfony/security-bundle": "6.4.*", "symfony/security-bundle": "6.4.*",
@ -82,36 +85,34 @@
"symfony/yaml": "6.4.*", "symfony/yaml": "6.4.*",
"tecnickcom/tc-lib-barcode": "^2.1.4", "tecnickcom/tc-lib-barcode": "^2.1.4",
"twig/cssinliner-extra": "^3.0", "twig/cssinliner-extra": "^3.0",
"twig/extra-bundle": "^3.0", "twig/extra-bundle": "^3.8",
"twig/html-extra": "^3.0", "twig/html-extra": "^3.8",
"twig/inky-extra": "^3.0", "twig/inky-extra": "^3.0",
"twig/intl-extra": "^3.0", "twig/intl-extra": "^3.8",
"twig/markdown-extra": "^3.0", "twig/markdown-extra": "^3.8",
"web-auth/webauthn-symfony-bundle": "^4.0.0", "twig/string-extra": "^3.8",
"webmozart/assert": "^1.4" "web-auth/webauthn-symfony-bundle": "^4.0.0"
}, },
"require-dev": { "require-dev": {
"dama/doctrine-test-bundle": "^v8.0.0", "dama/doctrine-test-bundle": "^v8.0.0",
"doctrine/doctrine-fixtures-bundle": "^3.2", "doctrine/doctrine-fixtures-bundle": "^4.0.0",
"ekino/phpstan-banned-code": "^v1.0.0", "ekino/phpstan-banned-code": "^v3.0.0",
"jbtronics/translation-editor-bundle": "^1.0",
"phpstan/extension-installer": "^1.0", "phpstan/extension-installer": "^1.0",
"phpstan/phpstan": "^1.4.7", "phpstan/phpstan": "^2.0.4",
"phpstan/phpstan-doctrine": "^1.2.11", "phpstan/phpstan-doctrine": "^2.0.1",
"phpstan/phpstan-strict-rules": "^1.5", "phpstan/phpstan-strict-rules": "^2.0.1",
"phpstan/phpstan-symfony": "^1.1.7", "phpstan/phpstan-symfony": "^2.0.0",
"phpunit/phpunit": "^9.5", "phpunit/phpunit": "^9.5",
"psalm/plugin-symfony": "^v5.0.1", "rector/rector": "^2.0.4",
"rector/rector": "^0.18.0",
"roave/security-advisories": "dev-latest", "roave/security-advisories": "dev-latest",
"symfony/browser-kit": "6.4.*", "symfony/browser-kit": "6.4.*",
"symfony/css-selector": "6.4.*",
"symfony/debug-bundle": "6.4.*", "symfony/debug-bundle": "6.4.*",
"symfony/maker-bundle": "^1.13", "symfony/maker-bundle": "^1.13",
"symfony/phpunit-bridge": "6.4.*", "symfony/phpunit-bridge": "6.4.*",
"symfony/stopwatch": "6.4.*", "symfony/stopwatch": "6.4.*",
"symfony/web-profiler-bundle": "6.4.*", "symfony/web-profiler-bundle": "6.4.*",
"symplify/easy-coding-standard": "^12.0", "symplify/easy-coding-standard": "^12.0"
"vimeo/psalm": "^5.6.0"
}, },
"suggest": { "suggest": {
"ext-bcmath": "Used to improve price calculation performance", "ext-bcmath": "Used to improve price calculation performance",
@ -162,7 +163,8 @@
"extra": { "extra": {
"symfony": { "symfony": {
"allow-contrib": false, "allow-contrib": false,
"require": "6.4.*" "require": "6.4.*",
"docker": true
} }
} }
} }

8389
composer.lock generated

File diff suppressed because it is too large Load diff

View file

@ -18,13 +18,11 @@ return [
DAMA\DoctrineTestBundle\DAMADoctrineTestBundle::class => ['test' => true], DAMA\DoctrineTestBundle\DAMADoctrineTestBundle::class => ['test' => true],
Twig\Extra\TwigExtraBundle\TwigExtraBundle::class => ['all' => true], Twig\Extra\TwigExtraBundle\TwigExtraBundle::class => ['all' => true],
Gregwar\CaptchaBundle\GregwarCaptchaBundle::class => ['all' => true], Gregwar\CaptchaBundle\GregwarCaptchaBundle::class => ['all' => true],
Translation\Bundle\TranslationBundle::class => ['all' => true],
Florianv\SwapBundle\FlorianvSwapBundle::class => ['all' => true], Florianv\SwapBundle\FlorianvSwapBundle::class => ['all' => true],
Nelmio\SecurityBundle\NelmioSecurityBundle::class => ['all' => true], Nelmio\SecurityBundle\NelmioSecurityBundle::class => ['all' => true],
Symfony\UX\Turbo\TurboBundle::class => ['all' => true], Symfony\UX\Turbo\TurboBundle::class => ['all' => true],
Jbtronics\TFAWebauthn\TFAWebauthnBundle::class => ['all' => true], Jbtronics\TFAWebauthn\TFAWebauthnBundle::class => ['all' => true],
Scheb\TwoFactorBundle\SchebTwoFactorBundle::class => ['all' => true], Scheb\TwoFactorBundle\SchebTwoFactorBundle::class => ['all' => true],
SpomkyLabs\CborBundle\SpomkyLabsCborBundle::class => ['all' => true],
Webauthn\Bundle\WebauthnBundle::class => ['all' => true], Webauthn\Bundle\WebauthnBundle::class => ['all' => true],
Nbgrp\OneloginSamlBundle\NbgrpOneloginSamlBundle::class => ['all' => true], Nbgrp\OneloginSamlBundle\NbgrpOneloginSamlBundle::class => ['all' => true],
Symfony\UX\StimulusBundle\StimulusBundle::class => ['all' => true], Symfony\UX\StimulusBundle\StimulusBundle::class => ['all' => true],
@ -33,4 +31,5 @@ return [
KnpU\OAuth2ClientBundle\KnpUOAuth2ClientBundle::class => ['all' => true], KnpU\OAuth2ClientBundle\KnpUOAuth2ClientBundle::class => ['all' => true],
Nelmio\CorsBundle\NelmioCorsBundle::class => ['all' => true], Nelmio\CorsBundle\NelmioCorsBundle::class => ['all' => true],
ApiPlatform\Symfony\Bundle\ApiPlatformBundle::class => ['all' => true], ApiPlatform\Symfony\Bundle\ApiPlatformBundle::class => ['all' => true],
Jbtronics\TranslationEditorBundle\JbtronicsTranslationEditorBundle::class => ['dev' => true],
]; ];

View file

@ -33,4 +33,9 @@ api_platform:
pagination_client_items_per_page: true # Allow clients to override the default items per page pagination_client_items_per_page: true # Allow clients to override the default items per page
keep_legacy_inflector: false keep_legacy_inflector: false
event_listeners_backward_compatibility_layer: false # Need to be true, or some tests will fail
use_symfony_listeners: true
serializer:
# Change this to false later, to remove the hydra prefix on the API
hydra_prefix: true

View file

@ -0,0 +1,5 @@
when@test:
dama_doctrine_test:
enable_static_connection: true
enable_static_meta_data_cache: true
enable_static_query_cache: true

View file

@ -8,15 +8,14 @@ datatables:
# Set options, as documented at https://datatables.net/reference/option/ # Set options, as documented at https://datatables.net/reference/option/
options: options:
lengthMenu : [[10, 25, 50, 100, -1], [10, 25, 50, 100, "All"]] lengthMenu : [[10, 25, 50, 100], [10, 25, 50, 100]] # We add the "All" option, when part tables are generated
pageLength: '%partdb.table.default_page_size%' # Set to -1 to disable pagination (i.e. show all rows) by default pageLength: '%partdb.table.default_page_size%' # Set to -1 to disable pagination (i.e. show all rows) by default
#dom: "<'row' <'col-sm-12' tr>><'row' <'col-sm-6'l><'col-sm-6 text-right'pif>>" dom: " <'row' <'col mb-2 input-group flex-nowrap' B l > <'col-auto mb-2' < p >>>
dom: " <'row'<'col mb-2 input-group' B l> <'col mb-2' <'pull-end' p>>>
<'card' <'card'
rt rt
<'card-footer card-footer-table text-muted' i > <'card-footer card-footer-table text-muted' i >
> >
<'row'<'col mt-2 input-group' B l> <'col mt-2' <'pull-right' p>>>" <'row' <'col mt-2 input-group flex-nowrap' B l > <'col-auto mt-2' < p >>>"
pagingType: 'simple_numbers' pagingType: 'simple_numbers'
searching: true searching: true
stateSave: true stateSave: true

View file

@ -1,5 +0,0 @@
translation:
symfony_profiler:
enabled: true
webui:
enabled: true

View file

@ -9,15 +9,26 @@ doctrine:
# either here or in the DATABASE_URL env var (see .env file) # either here or in the DATABASE_URL env var (see .env file)
types: types:
# UTC datetimes
datetime: datetime:
class: App\Doctrine\Types\UTCDateTimeType class: App\Doctrine\Types\UTCDateTimeType
date: date:
class: App\Doctrine\Types\UTCDateTimeType class: App\Doctrine\Types\UTCDateTimeType
datetime_immutable:
class: App\Doctrine\Types\UTCDateTimeImmutableType
date_immutable:
class: App\Doctrine\Types\UTCDateTimeImmutableType
big_decimal: big_decimal:
class: App\Doctrine\Types\BigDecimalType class: App\Doctrine\Types\BigDecimalType
tinyint: tinyint:
class: App\Doctrine\Types\TinyIntType class: App\Doctrine\Types\TinyIntType
# This was removed in doctrine/orm 4.0 but we need it for the WebauthnKey entity
array:
class: App\Doctrine\Types\ArrayType
schema_filter: ~^(?!internal)~ schema_filter: ~^(?!internal)~
# Only enable this when needed # Only enable this when needed
profiling_collect_backtrace: false profiling_collect_backtrace: false
@ -29,6 +40,8 @@ doctrine:
validate_xml_mapping: true validate_xml_mapping: true
naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware
auto_mapping: true auto_mapping: true
controller_resolver:
auto_mapping: true
mappings: mappings:
App: App:
type: attribute type: attribute
@ -39,10 +52,12 @@ doctrine:
dql: dql:
string_functions: string_functions:
regexp: DoctrineExtensions\Query\Mysql\Regexp regexp: App\Doctrine\Functions\Regexp
ifnull: DoctrineExtensions\Query\Mysql\IfNull
field: DoctrineExtensions\Query\Mysql\Field field: DoctrineExtensions\Query\Mysql\Field
field2: App\Doctrine\Functions\Field2 field2: App\Doctrine\Functions\Field2
natsort: App\Doctrine\Functions\Natsort
array_position: App\Doctrine\Functions\ArrayPosition
ilike: App\Doctrine\Functions\ILike
when@test: when@test:
doctrine: doctrine:

View file

@ -50,7 +50,6 @@ when@prod:
type: stream type: stream
path: "%kernel.logs_dir%/%kernel.environment%.log" path: "%kernel.logs_dir%/%kernel.environment%.log"
level: debug level: debug
formatter: monolog.formatter.json
console: console:
type: console type: console
process_psr_3_messages: false process_psr_3_messages: false
@ -74,7 +73,6 @@ when@docker:
type: stream type: stream
path: "php://stderr" path: "php://stderr"
level: debug level: debug
formatter: monolog.formatter.json
console: console:
type: console type: console
process_psr_3_messages: false process_psr_3_messages: false

View file

@ -32,7 +32,7 @@ nbgrp_onelogin_saml:
privateKey: '%env(string:default:saml.sp.privateKey:string:SAMLP_SP_PRIVATE_KEY)%' privateKey: '%env(string:default:saml.sp.privateKey:string:SAMLP_SP_PRIVATE_KEY)%'
# Optional settings # Optional settings
#baseurl: 'http://myapp.com' baseurl: '%partdb.default_uri%saml/'
strict: true strict: true
debug: false debug: false
security: security:

View file

@ -51,12 +51,16 @@ nelmio_security:
img-src: img-src:
- '*' - '*'
- 'data:' - 'data:'
# Required for be able to load pictures in the QR code scanner
- 'blob:'
style-src: style-src:
- 'self' - 'self'
- 'unsafe-inline' - 'unsafe-inline'
- 'data:' - 'data:'
script-src: script-src:
- 'self' - 'self'
# Required for loading the Wasm for the barcode scanner:
- 'wasm-unsafe-eval'
object-src: object-src:
- 'self' - 'self'
- 'data:' - 'data:'

View file

@ -1,11 +0,0 @@
translation:
locales: ["en", "de"]
edit_in_place:
enabled: false
config_name: app
configs:
app:
dirs: ["%kernel.project_dir%/templates", "%kernel.project_dir%/src"]
output_dir: "%kernel.project_dir%/translations"
excluded_names: ["*TestCase.php", "*Test.php"]
excluded_dirs: [cache, data, logs]

View file

@ -19,7 +19,7 @@ security:
provider: app_user_provider provider: app_user_provider
lazy: true lazy: true
user_checker: App\Security\UserChecker user_checker: App\Security\UserChecker
entry_point: form_login entry_point: App\Security\AuthenticationEntryPoint
# Enable user impersonation # Enable user impersonation
switch_user: { role: CAN_SWITCH_USER } switch_user: { role: CAN_SWITCH_USER }

View file

@ -11,11 +11,13 @@ parameters:
partdb.banner: '%env(trim:string:BANNER)%' # The info text shown in the homepage, if empty config/banner.md is used partdb.banner: '%env(trim:string:BANNER)%' # The info text shown in the homepage, if empty config/banner.md is used
partdb.default_currency: '%env(string:BASE_CURRENCY)%' # The currency that is used inside the DB (and is assumed when no currency is set). This can not be changed later, so be sure to set it the currency used in your country partdb.default_currency: '%env(string:BASE_CURRENCY)%' # The currency that is used inside the DB (and is assumed when no currency is set). This can not be changed later, so be sure to set it the currency used in your country
partdb.global_theme: '' # The theme to use globally (see public/build/themes/ for choices, use name without .css). Set to '' for default bootstrap theme partdb.global_theme: '' # The theme to use globally (see public/build/themes/ for choices, use name without .css). Set to '' for default bootstrap theme
partdb.locale_menu: ['en', 'de', 'it', 'fr', 'ru', 'ja'] # The languages that are shown in user drop down menu partdb.locale_menu: ['en', 'de', 'it', 'fr', 'ru', 'ja', 'cs', 'da', 'zh', 'pl'] # The languages that are shown in user drop down menu
partdb.enforce_change_comments_for: '%env(csv:ENFORCE_CHANGE_COMMENTS_FOR)%' # The actions for which a change comment is required (e.g. "part_edit", "part_create", etc.). If this is empty, change comments are not required at all. partdb.enforce_change_comments_for: '%env(csv:ENFORCE_CHANGE_COMMENTS_FOR)%' # The actions for which a change comment is required (e.g. "part_edit", "part_create", etc.). If this is empty, change comments are not required at all.
partdb.default_uri: '%env(string:DEFAULT_URI)%' # The default URI to use for the Part-DB instance (e.g. https://part-db.example.com/). This is used for generating links in emails partdb.default_uri: '%env(string:DEFAULT_URI)%' # The default URI to use for the Part-DB instance (e.g. https://part-db.example.com/). This is used for generating links in emails
partdb.db.emulate_natural_sort: '%env(bool:DATABASE_EMULATE_NATURAL_SORT)%' # If this is set to true, natural sorting is emulated on platforms that do not support it natively. This can be slow on large datasets.
###################################################################################################################### ######################################################################################################################
# Users and Privacy # Users and Privacy
###################################################################################################################### ######################################################################################################################
@ -115,6 +117,8 @@ parameters:
env(USE_GRAVATAR): '0' env(USE_GRAVATAR): '0'
env(MAX_ATTACHMENT_FILE_SIZE): '100M' env(MAX_ATTACHMENT_FILE_SIZE): '100M'
env(REDIRECT_TO_HTTPS): 0
env(ENFORCE_CHANGE_COMMENTS_FOR): '' env(ENFORCE_CHANGE_COMMENTS_FOR): ''
env(ERROR_PAGE_ADMIN_EMAIL): '' env(ERROR_PAGE_ADMIN_EMAIL): ''
@ -143,3 +147,5 @@ parameters:
env(HISTORY_SAVE_NEW_DATA): 1 env(HISTORY_SAVE_NEW_DATA): 1
env(EDA_KICAD_CATEGORY_DEPTH): 0 env(EDA_KICAD_CATEGORY_DEPTH): 0
env(DATABASE_EMULATE_NATURAL_SORT): 0

View file

@ -1,6 +0,0 @@
_translation_webui:
resource: '@TranslationBundle/Resources/config/routing_webui.yaml'
prefix: /admin
_translation_profiler:
resource: '@TranslationBundle/Resources/config/routing_symfony_profiler.yaml'

View file

@ -0,0 +1,3 @@
when@dev:
translation_editor:
resource: '@JbtronicsTranslationEditorBundle/config/routes.php'

View file

@ -1,3 +0,0 @@
_translation_edit_in_place:
resource: '@TranslationBundle/Resources/config/routing_edit_in_place.yaml'
prefix: /admin

View file

@ -76,18 +76,12 @@ services:
# Only the event classes specified here are saved to DB (set to []) to log all events # Only the event classes specified here are saved to DB (set to []) to log all events
$whitelist: [] $whitelist: []
App\EventSubscriber\LogSystem\EventLoggerSubscriber: App\EventListener\LogSystem\EventLoggerListener:
arguments: arguments:
$save_changed_fields: '%env(bool:HISTORY_SAVE_CHANGED_FIELDS)%' $save_changed_fields: '%env(bool:HISTORY_SAVE_CHANGED_FIELDS)%'
$save_changed_data: '%env(bool:HISTORY_SAVE_CHANGED_DATA)%' $save_changed_data: '%env(bool:HISTORY_SAVE_CHANGED_DATA)%'
$save_removed_data: '%env(bool:HISTORY_SAVE_REMOVED_DATA)%' $save_removed_data: '%env(bool:HISTORY_SAVE_REMOVED_DATA)%'
$save_new_data: '%env(bool:HISTORY_SAVE_NEW_DATA)%' $save_new_data: '%env(bool:HISTORY_SAVE_NEW_DATA)%'
tags:
- { name: 'doctrine.event_subscriber' }
App\EventSubscriber\LogSystem\LogDBMigrationSubscriber:
tags:
- { name: 'doctrine.event_subscriber' }
App\Form\AttachmentFormType: App\Form\AttachmentFormType:
arguments: arguments:
@ -307,6 +301,21 @@ services:
$options: '%env(string:PROVIDER_MOUSER_SEARCH_OPTION)%' $options: '%env(string:PROVIDER_MOUSER_SEARCH_OPTION)%'
$search_limit: '%env(int:PROVIDER_MOUSER_SEARCH_LIMIT)%' $search_limit: '%env(int:PROVIDER_MOUSER_SEARCH_LIMIT)%'
App\Services\InfoProviderSystem\Providers\LCSCProvider:
arguments:
$enabled: '%env(bool:PROVIDER_LCSC_ENABLED)%'
$currency: '%env(string:PROVIDER_LCSC_CURRENCY)%'
App\Services\InfoProviderSystem\Providers\OEMSecretsProvider:
arguments:
$api_key: '%env(string:PROVIDER_OEMSECRETS_KEY)%'
$country_code: '%env(string:PROVIDER_OEMSECRETS_COUNTRY_CODE)%'
$currency: '%env(PROVIDER_OEMSECRETS_CURRENCY)%'
$zero_price: '%env(PROVIDER_OEMSECRETS_ZERO_PRICE)%'
$set_param: '%env(PROVIDER_OEMSECRETS_SET_PARAM)%'
$sort_criteria: '%env(PROVIDER_OEMSECRETS_SORT_CRITERIA)%'
#################################################################################################################### ####################################################################################################################
# API system # API system
#################################################################################################################### ####################################################################################################################
@ -370,6 +379,10 @@ services:
$partdb_banner: '%partdb.banner%' $partdb_banner: '%partdb.banner%'
$project_dir: '%kernel.project_dir%' $project_dir: '%kernel.project_dir%'
App\Doctrine\Middleware\MySQLSSLConnectionMiddlewareWrapper:
arguments:
$enabled: '%env(bool:DATABASE_MYSQL_USE_SSL_CA)%'
$verify: '%env(bool:DATABASE_MYSQL_SSL_VERIFY_CERT)%'
#################################################################################################################### ####################################################################################################################
# Monolog # Monolog

View file

@ -11,17 +11,16 @@ To use API endpoints, the external application has to authenticate itself, so th
the data and which permissions the data and which permissions
the application should have during the access. Authentication is always bound to a specific user, so the external the application should have during the access. Authentication is always bound to a specific user, so the external
applications is acting on behalf of a applications is acting on behalf of a
specific user. This user limits the permissions of the application, so that it can only access data, which the user is specific user. This user limits the permissions of the application so that it can only access data, which the user is
allowed to access. allowed to access.
The only method currently available for authentication is to use API tokens: The only method currently available for authentication is to use API tokens:
## API tokens ## API tokens
An API token is a long alphanumeric string, which is bound to a specific user and can be used to authenticate as this An API token is a long alphanumeric string, which is bound to a specific user and can be used to authenticate as this user when accessing the API.
user, when accessing the API. The API token is passed via the `Authorization` HTTP header during the API request, like the
The API token is passed via the `Authentication` HTTP header during the API request, like the following: `Authorization: Bearer tcp_sdjfks....`.
following: `Authentication: Bearer tcp_sdjfks....`.
{: .important } {: .important }
> Everybody who knows the API token can access the API as the user, which is bound to the token. So you should treat the > Everybody who knows the API token can access the API as the user, which is bound to the token. So you should treat the
@ -36,7 +35,7 @@ not access the API anymore with this token.
### Token permissions and scopes ### Token permissions and scopes
API tokens are ultimately limited by the permissions of the user, which belongs to the token. That means that the token API tokens are ultimately limited by the permissions of the user, which belongs to the token. That means that the token
can only access data, which the user is allowed to access, no matter the token permissions. can only access data, that the user is allowed to access, no matter the token permissions.
But you can further limit the permissions of a token by choosing a specific scope for the token. The scope defines which But you can further limit the permissions of a token by choosing a specific scope for the token. The scope defines which
subset of permissions the token has, which can be less than the permissions of the user. For example, you can have a subset of permissions the token has, which can be less than the permissions of the user. For example, you can have a
@ -50,15 +49,15 @@ change anything in the database.
> Only use the full or admin scope, if you really need it, as they could potentially be used to do a lot of damage to > Only use the full or admin scope, if you really need it, as they could potentially be used to do a lot of damage to
> your Part-DB instance. > your Part-DB instance.
Following token scopes are available: The following token scopes are available:
* **Read-Only**: The token can only read non-sensitive data (like parts, but no users or groups) from the API and can * **Read-Only**: The token can only read non-sensitive data (like parts, but no users or groups) from the API and can
not change anything. not change anything.
* **Edit**: The token can read and write non-sensitive data via the API. This includes creating, updating and deleting * **Edit**: The token can read and write non-sensitive data via the API. This includes creating, updating and deleting
data. This should be enough for most applications. data. This should be enough for most applications.
* **Admin**: The token can read and write all data via the API, including sensitive data like users and groups. This * **Admin**: The token can read and write all data via the API, including sensitive data like users and groups. This
should only be used for trusted applications, which need to access sensitive data, and perform administrative actions. should only be used for trusted applications, which need to access sensitive data and perform administrative actions.
* **Full**: The token can do anything the user can do, including changing the users password and create new tokens. This * **Full**: The token can do anything the user can do, including changing the user's password and creating new tokens. This
should only be used for highly trusted applications!! should only be used for highly trusted applications!!
Please note, that in early versions of the API, there might be no endpoints yet, to really perform the actions, which Please note, that in early versions of the API, there might be no endpoints yet, to really perform the actions, which

View file

@ -29,15 +29,14 @@ features and how to use them.
The API is available under the `/api` path, but not reachable without proper permissions. The API is available under the `/api` path, but not reachable without proper permissions.
You have to give the users, which should be able to access the API the proper permissions (Miscellaneous -> API). You have to give the users, which should be able to access the API the proper permissions (Miscellaneous -> API).
Please note that there are two relevant permissions, the first one allows users to access the `/api/` path at all and Please note that there are two relevant permissions, the first one allows users to access the `/api/` path at all and show the documentation,
showing the documentation, and the second one allows them to create API tokens which are needed for the authentication of external applications.
and the second one allows them to create API tokens which is needed for authentication of external applications.
## Authentication ## Authentication
To use API endpoints, the external application has to authenticate itself, so that Part-DB knows which user is accessing To use API endpoints, the external application has to authenticate itself, so that Part-DB knows which user is accessing
the data and the data and
which permissions the application should have. Basically this is done by creating an API token for a user and then which permissions the application should have. Basically, this is done by creating an API token for a user and then
passing it on every request passing it on every request
with the `Authorization` header as bearer token, so you add a header `Authorization: Bearer <your token>`. with the `Authorization` header as bearer token, so you add a header `Authorization: Bearer <your token>`.
@ -46,11 +45,10 @@ See [Authentication chapter]({% link api/authentication.md %}) for more details.
## API endpoints ## API endpoints
The API is split into different endpoints, which are reachable under the `/api/` path of your Part-DB instance ( The API is split into different endpoints, which are reachable under the `/api/` path of your Part-DB instance (
so `https://your-part-db.local/api/`). e.g. `https://your-part-db.local/api/`).
There are various endpoints for each entity type (like `part`, `manufacturer`, etc.), which allow you to read and write There are various endpoints for each entity type (like `part`, `manufacturer`, etc.), which allow you to read and write data, and some special endpoints like `search` or `statistics`.
data and some special endpoints like `search` or `statistics`.
For example all API endpoints for managing categories are available under `/api/categories/`. Depending on the exact For example, all API endpoints for managing categories are available under `/api/categories/`. Depending on the exact
path and the HTTP method used, you can read, create, update or delete categories. path and the HTTP method used, you can read, create, update or delete categories.
For most entities, there are endpoints like this: For most entities, there are endpoints like this:
@ -66,29 +64,28 @@ For most entities, there are endpoints like this:
A full (interactive) list of endpoints can be displayed when visiting the `/api/` path in your browser, when you are A full (interactive) list of endpoints can be displayed when visiting the `/api/` path in your browser, when you are
logged in with a user, which is allowed to access the API. logged in with a user, which is allowed to access the API.
There is also a link to this page, on the user settings page in the API token section. There is also a link to this page, on the user settings page in the API token section.
This documentation also list all available fields for each entity type and the allowed operations. This documentation also lists all available fields for each entity type and the allowed operations.
## Formats ## Formats
The API supports different formats for the request and response data, which you can control via the `Accept` The API supports different formats for the request and response data, which you can control via the `Accept`
and `Content-Type` headers. and `Content-Type` headers.
You should use [JSON-LD](https://json-ld.org/) as format, which is basically JSON with some additional metadata, which You should use [JSON-LD](https://json-ld.org/) as format, which is basically JSON with some additional metadata, which
allows allows you to describe the data in a more structured way and also allows to link between different entities. You can achieve this
to describe the data in a more structured way and also allows to link between different entities. You can achieve this
by setting `Accept: application/ld+json` header to the API requests. by setting `Accept: application/ld+json` header to the API requests.
To get plain JSON without any metadata or links, use the `Accept: application/json` header. To get plain JSON without any metadata or links, use the `Accept: application/json` header.
Without an `Accept` header (e.g. when you call the endpoint in a browser), the API will return an HTML page with the Without an `Accept` header (e.g. when you call the endpoint in a browser), the API will return an HTML page with the
documentation, so be sure to include the desired `Accept` header in your API requests. documentation, so be sure to include the desired `Accept` header in your API requests.
If you can not control the `Accept` header, you can add an `.json` or `.jsonld` suffix to the URL to enforce a JSON or If you can not control the `Accept` header, you can add a `.json` or `.jsonld` suffix to the URL to enforce a JSON or
JSON-LD response (e.g. `/api/parts.jsonld`). JSON-LD response (e.g. `/api/parts.jsonld`).
## OpenAPI schema ## OpenAPI schema
Part-DB provides a [OpenAPI](https://swagger.io/specification/) (formally Swagger) schema for the API Part-DB provides a [OpenAPI](https://swagger.io/specification/) (formally Swagger) schema for the API
under `/api/docs.json` (so `https://your-part-db.local/api/docs.json`). under `/api/docs.json` (so `https://your-part-db.local/api/docs.json`).
This schema is a machine-readable description of the API, which can be imported in software to test the API or even This schema is a machine-readable description of the API, which can be imported into software to test the API or even
automatically generate client libraries for the API. automatically generate client libraries for the API.
API generators which can generate a client library for the API from the schema are available for many programming API generators which can generate a client library for the API from the schema are available for many programming
@ -120,14 +117,10 @@ See [API Platform docs](https://api-platform.com/docs/core/pagination) for more
## Filtering results / Searching ## Filtering results / Searching
When retrieving a list of entities, you can restrict the results by various filters. Almost all entities have a search When retrieving a list of entities, you can restrict the results by various filters. Almost all entities have a search
filter, filter, which allows you to only include entities, which (text) fields match the given search term: For example, if you only want
which allows you to only include entities, which (text) fields match the given search term: For example if you only want to get parts, with the Name "BC547", you can use `/api/parts.jsonld?name=BC547`. You can use `%` as a wildcard for multiple
to characters in the search term (Be sure to properly encode the search term, if you use special characters). For example, if you want
get parts, with the Name "BC547", you can use `/api/parts.jsonld?name=BC547`. You can use `%` as wildcard for multiple to get all parts, whose name starts with "BC", you can use `/api/parts.jsonld?name=BC%25` (the `%25` is the url encoded version of `%`).
characters
in the search term (Be sure to properly encode the search term, if you use special characters). For example if you want
to get all parts,
whose name starts with "BC", you can use `/api/parts.jsonld?name=BC%25` (the `%25` is the url encoded version of `%`).
There are other filters available for some entities, allowing you to search on other fields, or restricting the results There are other filters available for some entities, allowing you to search on other fields, or restricting the results
by numeric values or dates. See the endpoint documentation for the available filters. by numeric values or dates. See the endpoint documentation for the available filters.
@ -136,8 +129,8 @@ by numeric values or dates. See the endpoint documentation for the available fil
To get all parts with a certain category, manufacturer, etc. you can use the `category`, `manufacturer`, etc. query To get all parts with a certain category, manufacturer, etc. you can use the `category`, `manufacturer`, etc. query
parameters of the `/api/parts` endpoint. parameters of the `/api/parts` endpoint.
They are so-called entity filters and accept a comma separated list of IDs of the entities you want to filter by. They are so-called entity filters and accept a comma-separated list of IDs of the entities you want to filter by.
For example if you want to get all parts with the category "Resistor" (Category ID 1) and "Capacitor" (Category ID 2), For example, if you want to get all parts with the category "Resistor" (Category ID 1) and "Capacitor" (Category ID 2),
you can use `/api/parts.jsonld?category=1,2`. you can use `/api/parts.jsonld?category=1,2`.
Suffix an id with `+` to suffix, to include all direct children categories of the given category. Use the `++` suffix to Suffix an id with `+` to suffix, to include all direct children categories of the given category. Use the `++` suffix to
@ -150,7 +143,7 @@ See the endpoint documentation for the available entity filters.
## Ordering results ## Ordering results
When retrieving a list of entities, you can order the results by various fields using the `order` query parameter. When retrieving a list of entities, you can order the results by various fields using the `order` query parameter.
For example if you want to get all parts ordered by their name, you can use `/api/parts/?order[name]=asc`. You can use For example, if you want to get all parts ordered by their name, you can use `/api/parts/?order[name]=asc`. You can use
this parameter multiple times to order by multiple fields. this parameter multiple times to order by multiple fields.
See the endpoint documentation for the available fields to order by. See the endpoint documentation for the available fields to order by.
@ -161,12 +154,12 @@ Sometimes you only want to get a subset of the properties of an entity, for exam
part, but not all the other properties. part, but not all the other properties.
You can achieve this using the `properties[]` query parameter with the name of the field you want to get. You can use You can achieve this using the `properties[]` query parameter with the name of the field you want to get. You can use
this parameter multiple times to get multiple fields. this parameter multiple times to get multiple fields.
For example if you only want to get the name and the description of a part, you can For example, if you only want to get the name and the description of a part, you can
use `/api/parts/123?properties[]=name&properties[]=description`. use `/api/parts/123?properties[]=name&properties[]=description`.
It is also possible to use this filters on list endpoints (get collection), to only get a subset of the properties of It is also possible to use these filters on list endpoints (get collection), to only get a subset of the properties of
all entities in the collection. all entities in the collection.
See [API Platform docs](https://api-platform.com/docs/core/filters/#property-filter) for more infos. See [API Platform docs](https://api-platform.com/docs/core/filters/#property-filter) for more info.
## Change comment ## Change comment
@ -174,5 +167,63 @@ Similar to the changes using Part-DB web interface, you can add a change comment
which will be which will be
visible in the log of the entity. visible in the log of the entity.
You can pass the text for this via the `_comment` query parameter (beware the proper encoding). For You can pass the text for this via the `_comment` query parameter (beware of the proper encoding). For
example `/api/parts/123?_comment=This%20is%20a%20change%20comment`. example `/api/parts/123?_comment=This%20is%20a%20change%20comment`.
## Creating attachments and parameters
To create attachments and parameters, use the POST endpoint. Internally there are different types of attachments and
parameters, for each entity type, where the attachments or parameters are used (e.g. PartAttachment for parts, etc.).
The type of the attachment or parameter is automatically determined by the `element` property of the request data if a
IRI is passed. You can use the `_type` property to explicitly set the type of the attachment or parameter (the value must
be the value of the `@type` property of the owning entity. e.g. `Part` for parts).
For example, to create an attachment on a part, you can use the following request:
```
POST /api/attachments
{
"name": "front68",
"attachment_type": "/api/attachment_types/1",
"url": "https://invalid.invalid/test.url",
"element": "/api/parts/123"
}
```
## Uploading files to attachments
To upload files to the attachments you can use the special `upload` property of the attachment entity during write operations (POST, PUT, PATCH).
Under `data` you can pass a base64 encoded string of the file content, and under `filename` the name of the file.
Using the `private` property you can control if the file is the attachment should be stored privately or public.
For example, to upload a file to an attachment, you can use the following request:
```
PATCH /api/attachments/123
{
"upload": {
"data": "data:@file/octet-stream;base64,LS0gcGhwTXlB[...]",
"filename": "test.csv",
"private": false
},
"name": "Rename attachment"
}
```
This also works for creating new attachments, by including the `upload` property in the request data along with the other properties.
Using the `downloadUrl` property of `upload` you can say Part-DB to upload the file specified at the URL set on the attachment.
```
PATCH /api/attachments/123
{
"upload": {
"downloadUrl": true
},
"url": "https://host.invalid/myfile.pdf"
}
```

View file

@ -11,55 +11,55 @@ This page explains the different concepts of Part-DB and what their intended use
1. TOC 1. TOC
{:toc} {:toc}
## Part managment ## Part management
### Part ### Part
A part is the central concept of Part-DB. A part represents a single kind (or type) of a thing, like an electronic A part is the central concept of Part-DB. A part represents a single kind (or type) of a thing, like an electronic
component, a device, a book or similar (depending on what you use Part-DB for). A part entity just represents a certain component, a device, a book or similar (depending on what you use Part-DB for). A part entity just represents a certain
type of thing, so if you have 1000 times an BC547 transistor you would create ONE part with the name BC547 and set its type of thing, so if you have 1000 times a BC547 transistor you would create ONE part with the name BC547 and set its
quantity to 1000. The individual quantities (so a single BC547 transistor) of a part, should be indistinguishable from quantity to 1000. The individual quantities (so a single BC547 transistor) of a part, should be indistinguishable from
each other, so that it does not matter which one of your 1000 things of Part you use. each other so that it does not matter which one of your 1000 things of Part you use.
A part entity have many fields, which can be used to describe it better. Most of the fields are optional: A part entity has many fields, which can be used to describe it better. Most of the fields are optional:
* **Name** (Required): The name of the part or how you want to call it. This could be a manufacturer provided name, or a * **Name** (Required): The name of the part or how you want to call it. This could be a manufacturer-provided name, or a
name you thought of your self. The name have to be unique in a single category. name you thought of yourself. Each name needs to be unique and must exist in a single category.
* **Description**: A short (single-line) description of what this part is/does. For longer information you should use * **Description**: A short (single-line) description of what this part is/does. For longer information, you should use
the comment field or the specifications the comment field or the specifications
* **Category** (Required): The category (see there) to which this part belongs to. * **Category** (Required): The category (see there) to which this part belongs to.
* **Tags**: The list of tags this part belong to. Tags can be used to group parts logically (similar to the category), * **Tags**: The list of tags this part belongs to. Tags can be used to group parts logically (similar to the category),
but tags are much less strict and formal (they don't have to be defined forehands) and you can assign multiple tags to but tags are much less strict and formal (they don't have to be defined forehands) and you can assign multiple tags to
a part. When clicking on a tag, a list with all parts which have the same tag, is shown. a part. When clicking on a tag, a list with all parts which have the same tag, is shown.
* **Min Instock**: *Not really implemented yet*. Parts where the total instock is below this value, will show up for * **Min Instock**: *Not really implemented yet*. Parts where the total instock is below this value, will show up for
ordering. ordering.
* **Footprint**: See there. Useful especially for electronic parts, which have one of the common electronic footprints ( * **Footprint**: See there. Useful especially for electronic parts, which have one of the common electronic footprints (
like DIP8, SMD0805 or similar). If a part has no explicit defined preview picture, the preview picture of its like DIP8, SMD0805 or similar). If a part has no explicitly defined preview picture, the preview picture of its
footprint will be shown instead in tables. footprint will be shown instead in tables.
* **Manufacturer**: The manufacturer which has manufactured (not sold) this part. See Manufacturer entity for more info. * **Manufacturer**: The manufacturer which has manufactured (not sold) this part. See Manufacturer entity for more info.
* **Manufacturer part number** (MPN): If you have used your own name for a part, you can put the part number the * **Manufacturer part number** (MPN): If you have used your own name for a part, you can put the part number the
manufacturer uses in this field, so that you can find a part also under its manufacturer number. manufacturer uses in this field so that you can find a part also under its manufacturer number.
* **Link to product page**: If you want to link to the manufacturer website of a part, and it is not possible to * **Link to product page**: If you want to link to the manufacturer website of a part, and it is not possible to
determine it automatically from the part name, set in the manufacturer entity (or no manufacturer is set), you can set determine it automatically from the part name, set in the manufacturer entity (or no manufacturer is set), you can set
the link here for each part individually. the link here for each part individually.
* **Manufacturing Status**: The manufacturing status of this part, meaning the information about where the part is in * **Manufacturing Status**: The manufacturing status of this part, meaning the information about where the part is in
its manufacturing lifecycle. its manufacturing lifecycle.
* **Needs review**: If you think parts information maybe are inaccurate or incomplete and needs some later * **Needs review**: If you think parts information may be inaccurate or incomplete and needs some later
review/checking, you can set this flag. A part with this flag is marked, so that users know the information are not review/checking, you can set this flag. A part with this flag is marked, so that users know the information is not
completely trustworthy. completely trustworthy.
* **Favorite**: Parts with this flag are highlighted in parts lists * **Favorite**: Parts with this flag are highlighted in parts lists
* **Mass**: The mass of a single piece of this part (so of a single transistor). Given in grams. * **Mass**: The mass of a single piece of this part (so of a single transistor). Given in grams.
* **Internal Part number** (IPN): Each part is automatically assigned a numerical ID which identifies a part in the * **Internal Part number** (IPN): Each part is automatically assigned a numerical ID that identifies a part in the
database. This ID depends on when a part was created and can not be changed. If you want to assign your own unique database. This ID depends on when a part was created and can not be changed. If you want to assign your own unique
identifiers, or sync parts identifiers with the identifiers of another database you can use this field. identifiers, or sync parts identifiers with the identifiers of another database you can use this field.
### Stock / Part lot ### Stock / Part lot
A part can have many stock at multiple different locations. This is represented by part lots / stocks, which consists A part can have many stocks at multiple different locations. This is represented by part lots/stocks, which consists
basically of a storage location (so where are the parts of this lot are stored) and an amount (how many parts are there). basically of a storage location (so where the parts of this lot are stored) and an amount (how many parts are there).
### Purchase Information ### Purchase Information
The purchase information describe where the part can be bought (at which vendors) and to which prices. The purchase information describes where the part can be bought (at which vendors) and at which prices.
The first part (the order information) describes at which supplier the part can be bought and which is the name of the The first part (the order information) describes at which supplier the part can be bought and which is the name of the
part under which you can order the part there. part under which you can order the part there.
An order information can contain multiple price information, which describes the prices for the part at the supplier An order information can contain multiple price information, which describes the prices for the part at the supplier
@ -67,13 +67,13 @@ including bulk discount, etc.
### Parameters ### Parameters
Parameters represents various specifications / parameters of a part, like the maximum current of a diode, etc. The Parameters represent various specifications/parameters of a part, like the maximum current of a diode, etc. The
advantage of using parameters instead of just putting the data in the comment field or so, is that you can filter for advantage of using parameters instead of just putting the data in the comment field or so, is that you can filter for
parameters values (including ranges and more) later on. parameter's values (including ranges and more) later on.
Parameters describe can describe numeric values and/or text values for which they can be filtered. This basically allows Parameters can describe numeric values and/or text values for which they can be filtered. This allows
you to define custom fields on a part. you to define custom fields on a part.
Using the group field a parameter allows you to group parameters together in the info page later (all parameters with Using the group field as a parameter allows you to group parameters together on the info page later (all parameters with
the same group value will be shown under the same group title). the same group value will be shown under the same group title).
## Core data ## Core data
@ -99,17 +99,17 @@ possible category tree could look like this:
### Supplier ### Supplier
A Supplier is a vendor / distributor where you can buy/order parts. Price information of parts are associated with a A Supplier is a vendor/distributor where you can buy/order parts. Price information of parts is associated with a
supplier. supplier.
### Manufacturer ### Manufacturer
A manufacturer represents the company that manufacturer / build various parts (not necessary sell them). If the A manufacturer represents the company that manufacturers/builds various parts (not necessarily sell them). If the
manufacturer also sell the parts, you have to create a supplier for that. manufacturer also sells the parts, you have to create a supplier for that.
### Storage location ### Storage location
A storage location represents a place where parts can be stored. This could be a box, a shelf or other things (like the A storage location represents a place where parts can be stored. This could be a box, a shelf, or other things (like the
SMD feeder of a machine or so). SMD feeder of a machine or so).
Storage locations are hierarchical to represent storage locations contained in each other. Storage locations are hierarchical to represent storage locations contained in each other.
@ -129,12 +129,12 @@ Storage locations should be defined down to the smallest possible location, to m
### Footprint ### Footprint
In electronics many components have one of the common components cases / footprints. The footprint entity describes such In electronics, many components have one of the common components cases/footprints. The footprint entity describes such
common footprints, which can be assigned to parts. common footprints, which can be assigned to parts.
You can assign an image (and an 3D model) as an attachment to a footprint, which will be used as preview for parts with You can assign an image (and a 3D model) as an attachment to a footprint, which will be used as preview for parts with
this footprint, even if the parts do not have an explicitly assigned preview image. this footprint, even if the parts do not have an explicitly assigned preview image.
Footprints are a hierarchically which allows you to build logical sorted trees. An example tree could look like this: Footprints are hierarchically which allows you to build logically sorted trees. An example tree could look like this:
* Through-Hole components * Through-Hole components
* DIP * DIP
@ -153,17 +153,20 @@ Footprints are a hierarchically which allows you to build logical sorted trees.
### Measurement Unit ### Measurement Unit
By default, part in stock is counted in number of individual parts, which is fine for things like electronic components, By default, part in stock is counted in number of individual parts, which is fine for things like electronic components,
which exists only in integer quantities. However, if you have things with fractional units like the length of a wire or which exist only in integer quantities. However, if you have things with fractional units like the length of a wire or
the volume of a liquid, you have to define a measurement unit. the volume of a liquid, you have to define a measurement unit.
The measurement unit represents a physical quantity like mass, volume or length. The measurement unit represents a physical quantity like mass, volume, or length.
You can define a short unit for it (like m for Meters, or g for gramms) which will be shown, when a quantity of a part You can define a short unit for it (like m for Meters, or g for grams) which will be shown when a quantity of a part
with this unit is shown. with this unit is shown.
In order to cover wider use cases and allow you to define measurement units further, it is possible to define parameters
associated to a measurement unit. These parameters are distinct from a part's parameters and are not inherited.
### Currency ### Currency
By default, all prices are set in the base currency configured for the instance (by default euros). If you want to use By default, all prices are set in the base currency configured for the instance (by default euros). If you want to use
multiple currencies together (as e.g. vendors use foreign currencies for their price, and you do not want to update the multiple currencies together (e.g. vendors use foreign currencies for their price, and you do not want to update the
prices for every exchange rate change), you have to define these currencies here. prices for every exchange rate change), you have to define these currencies here.
You can set an exchange rate here in terms of the base currency (or fetch it from the internet if configured). The You can set an exchange rate here in terms of the base currency (or fetch it from the internet if configured). The
@ -173,7 +176,7 @@ exchange rate will be used to show users the prices in their preferred currency.
### Attachment ### Attachment
An attachment is a file that can be associated with another entity (like a Part, Storelocation, User, etc.). This could An attachment is a file that can be associated with another entity (like a Part, location, User, etc.). This could
for example be a datasheet in a Part, the logo of a vendor or some CAD drawing of a footprint. for example be a datasheet in a Part, the logo of a vendor or some CAD drawing of a footprint.
An attachment has an attachment type (see below), which groups the attachments logically (and optionally restricts the An attachment has an attachment type (see below), which groups the attachments logically (and optionally restricts the
@ -183,9 +186,9 @@ the webserver downloads the file from the supplied website and stores it locally
By default, all uploaded files, are accessible for everyone (even non-logged-in users), if the link is known. If your By default, all uploaded files, are accessible for everyone (even non-logged-in users), if the link is known. If your
Part-DB instance is publicly available, and you want to store private/sensitive files on it, you should mark the Part-DB instance is publicly available, and you want to store private/sensitive files on it, you should mark the
attachment as "Private attachment". Private attachments are only accessible to users, which has the permission to access attachment as "Private attachment". Private attachments are only accessible to users, which has permission to access
private attachments. private attachments.
Please not, that no thumbnails are generated for private attachments, which can have a performance impact. Please note, that no thumbnails are generated for private attachments, which can have a performance impact.
Part-DB ships some preview images for various common footprints like DIP-8 and others, as internal resources. These can Part-DB ships some preview images for various common footprints like DIP-8 and others, as internal resources. These can
be accessed/searched by typing the keyword in the URL field of a part and choosing one of the choices from the dropdown. be accessed/searched by typing the keyword in the URL field of a part and choosing one of the choices from the dropdown.
@ -195,35 +198,35 @@ be accessed/searched by typing the keyword in the URL field of a part and choosi
Most entities with attachments allow you to select one of the defined attachments as "Preview image". You can select an Most entities with attachments allow you to select one of the defined attachments as "Preview image". You can select an
image attachment here, that previews the entity, this could be a picture of a Part, the logo of a manufacturer or image attachment here, that previews the entity, this could be a picture of a Part, the logo of a manufacturer or
supplier, the schematic symbol of a category or the image of a footprint. supplier, the schematic symbol of a category or the image of a footprint.
The preview image will be shown in various locations together with the entities name. The preview image will be shown in various locations together with the entity's name.
Please note that as long as the picture is not secret, it should be stored on the Part-DB instance (by upload, or Please note that as long as the picture is not secret, it should be stored on the Part-DB instance (by uploading, or
letting Part-DB download the file) and *not* be marked as a private attachments, so that thumbnails can be generated for letting Part-DB download the file) and *not* be marked as a private attachment, so that thumbnails can be generated for
the picture (which improves performance). the picture (which improves performance).
### Attachment types ### Attachment types
Attachment types define logical groups of attachments. For example, you could define an attachment group "Datasheets" Attachment types define logical groups of attachments. For example, you could define an attachment group "Datasheets"
where all datasheets of Parts, Footprints, etc. belong in, "Pictures" for preview images and more. where all datasheets of Parts, Footprints, etc. belong in, "Pictures" for preview images and more.
You can define file type restrictions, which file types and extensions are allowed for files with that attachment type. You can define file type restrictions, and which file types and extensions are allowed for files with that attachment type.
## User System ## User System
### User ### User
Each person which should be able to use Part-DB (by logging in) is represented by a user entity, which defines things Each person who should be able to use Part-DB (by logging in) is represented by a user entity, which defines things
like access rights, the password, and other things. For security reasons, every person which will use Part-DB should use like access rights, the password, and other things. For security reasons, every person who will use Part-DB should use
its own personal account with a secret password. This allows to track activity of the users via the log. their own personal account with a secret password. This allows to track activity of the users via the log.
There is a special user called `anonymous`, whose access rights are used to determine what a non-logged in user can do. There is a special user called `anonymous`, whose access rights are used to determine what a non-logged-in user can do.
Normally the anonymous user should be the most restricted user. Normally the anonymous user should be the most restricted user.
For simplification of access management users can be assigned to groups. For simplification of access management users can be assigned to groups.
### Group ### Group
A group is entity, to which users can be assigned to. This can be used to logically group users by for example A group is an entity, to which users can be assigned to. This can be used to logically group users by for example
organisational structures and to simplify permissions management, as you can define groups with access rights for common organizational structures and to simplify permissions management, as you can define groups with access rights for common
use cases and then just assign users to them, without the need to change every permission on the users individually. use cases and then just assign users to them, without the need to change every permission on the users individually.
## Labels ## Labels
@ -231,9 +234,9 @@ use cases and then just assign users to them, without the need to change every p
### Label profiles ### Label profiles
A label profile represents a template for a label (for a storage location, a part or part lot). It consists of a size, a A label profile represents a template for a label (for a storage location, a part or part lot). It consists of a size, a
barcode type and the content. There are various placeholders which can be inserted in the text content and which will be barcode type and the content. There are various placeholders that can be inserted in the text content and which will be
used replaced with data for the actual thing. replaced with data for the actual thing.
You do not have to define a label profile to generate labels (you can just set the settings on the fly in the label You do not have to define a label profile to generate labels (you can just set the settings on the fly in the label
dialog), however if you want to generate many labels, it is recommended to save the settings as label profile, to save dialog), however, if you want to generate many labels, it is recommended to save the settings as a label profile, to save
it for later usage. This ensures that all generated labels look the same. it for later usage. This ensures that all generated labels look the same.

View file

@ -6,19 +6,19 @@ nav_order: 5
# Configuration # Configuration
Part-DBs behavior can be configured to your needs. There are different kind of configuration options: Options which are Part-DBs behavior can be configured to your needs. There are different kinds of configuration options: Options, which are
user changeable (changeable dynamically via frontend), options which can be configured by environment variables, and user-changeable (changeable dynamically via frontend), options that can be configured by environment variables, and
options which are only configurable via symfony config files. options that are only configurable via Symfony config files.
## User changeable ## User changeable
Following things can be changed for every user and a user can change it for himself (if he has the correct permission The following things can be changed for every user and a user can change it for himself (if he has the correct permission
for it). Configuration is either possible via the users own setting page (where you can also change the password) or via for it). Configuration is either possible via the user's own settings page (where you can also change the password) or via
the user admin page: the user admin page:
* **Language**: The language that the users prefers, and which will be used when no language is explicitly specified. * **Language**: The language that the users prefer, and which will be used when no language is explicitly specified.
Language can still always be changed via the language selector. By default, the global configured language is used. Language can still always be changed via the language selector. By default, the globally configured language is used.
* **Timezone**: The timezone which the user resides in and in which all dates and times should be shown. By default, the * **Timezone**: The timezone in which the user resides and in which all dates and times should be shown. By default, the
globally configured language. globally configured language.
* **Theme**: The theme to use for the front end. Allows the user to choose the front end design, he prefers. * **Theme**: The theme to use for the front end. Allows the user to choose the front end design, he prefers.
* **Preferred currency**: One of the defined currencies, in which all prices should be shown, if possible. Prices with * **Preferred currency**: One of the defined currencies, in which all prices should be shown, if possible. Prices with
@ -28,16 +28,27 @@ the user admin page:
The following configuration options can only be changed by the server administrator, by either changing the server The following configuration options can only be changed by the server administrator, by either changing the server
variables, changing the `.env.local` file or setting env for your docker container. Here are just the most important variables, changing the `.env.local` file or setting env for your docker container. Here are just the most important
options listed, see `.env` file for full list of possible env variables. options listed, see `.env` file for the full list of possible env variables.
### General options ### General options
* `DATABASE_URL`: Configures the database which Part-DB uses. For mysql use a string in the form * `DATABASE_URL`: Configures the database which Part-DB uses:
of `mysql://<USERNAME>:<PASSWORD>@<HOST>:<PORT>/<TABLE_NAME>` here * For MySQL (or MariaDB) use a string in the form of `mysql://<USERNAME>:<PASSWORD>@<HOST>:<PORT>/<TABLE_NAME>` here
(e.g. `DATABASE_URL=mysql://user:password@127.0.0.1:3306/part-db`). For sqlite use the following format to specify the (e.g. `DATABASE_URL=mysql://user:password@127.0.0.1:3306/part-db`).
* For SQLite use the following format to specify the
absolute path where it should be located `sqlite:///path/part/app.db`. You can use `%kernel.project_dir%` as absolute path where it should be located `sqlite:///path/part/app.db`. You can use `%kernel.project_dir%` as
placeholder for the Part-DB root folder (e.g. `sqlite:///%kernel.project_dir%/var/app.db`) placeholder for the Part-DB root folder (e.g. `sqlite:///%kernel.project_dir%/var/app.db`)
* `DEFAULT_LANG`: The default language to use server wide (when no language is explicitly specified by a user or via * For Postgresql use a string in the form of `DATABASE_URL=postgresql://user:password@127.0.0.1:5432/part-db?serverVersion=x.y`.
Please note that **`serverVersion=x.y`** variable is required due to dependency of Symfony framework.
* `DATABASE_MYSQL_USE_SSL_CA`: If this value is set to `1` or `true` and a MySQL connection is used, then the connection
is encrypted by SSL/TLS and the server certificate is verified against the system CA certificates or the CA certificate
bundled with Part-DB. Set `DATABASE_MYSQL_SSL_VERIFY_CERT` if you want to accept all certificates.
* `DATABASE_EMULATE_NATURAL_SORT` (default 0): If set to 1, Part-DB will emulate natural sorting, even if the database
does not support it natively. However this is much slower than the native sorting, and contain bugs or quirks, so use
it only, if you have to.
* `DEFAULT_LANG`: The default language to use server-wide (when no language is explicitly specified by a user or via
language chooser). Must be something like `en`, `de`, `fr`, etc. language chooser). Must be something like `en`, `de`, `fr`, etc.
* `DEFAULT_TIMEZONE`: The default timezone to use globally, when a user has no timezone specified. Must be something * `DEFAULT_TIMEZONE`: The default timezone to use globally, when a user has no timezone specified. Must be something
like `Europe/Berlin`. See [here](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) under TZ Database name like `Europe/Berlin`. See [here](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) under TZ Database name
@ -50,7 +61,7 @@ options listed, see `.env` file for full list of possible env variables.
* `INSTANCE_NAME`: The name of your installation. It will be shown as a title in the navbar and other places. By * `INSTANCE_NAME`: The name of your installation. It will be shown as a title in the navbar and other places. By
default `Part-DB`, but you can customize it to something likes `ExampleCorp. Inventory`. default `Part-DB`, but you can customize it to something likes `ExampleCorp. Inventory`.
* `ALLOW_ATTACHMENT_DOWNLOADS` (allowed values `0` or `1`): By setting this option to 1, users can make Part-DB directly * `ALLOW_ATTACHMENT_DOWNLOADS` (allowed values `0` or `1`): By setting this option to 1, users can make Part-DB directly
download a file specified as a URL and create it as local file. Please note that this allows users access to all download a file specified as a URL and create it as a local file. Please note that this allows users access to all
resources publicly available to the server (so full access to other servers in the same local network), which could resources publicly available to the server (so full access to other servers in the same local network), which could
be a security risk. be a security risk.
* `ATTACHMENT_DOWNLOAD_BY_DEFAULT`: When this is set to 1, the "download external file" checkbox is checked by default * `ATTACHMENT_DOWNLOAD_BY_DEFAULT`: When this is set to 1, the "download external file" checkbox is checked by default
@ -60,7 +71,7 @@ options listed, see `.env` file for full list of possible env variables.
not set their own picture). The users browsers have to download the pictures from a third-party (gravatar) server, so not set their own picture). The users browsers have to download the pictures from a third-party (gravatar) server, so
this might be a privacy risk. this might be a privacy risk.
* `MAX_ATTACHMENT_FILE_SIZE`: The maximum file size (in bytes) for attachments. You can use the suffix `K`, `M` or `G` * `MAX_ATTACHMENT_FILE_SIZE`: The maximum file size (in bytes) for attachments. You can use the suffix `K`, `M` or `G`
to specify the size in kilobytes, megabytes or gigabytes. By default `100M` (100 megabytes). Please note that this to specify the size in kilobytes, megabytes or gigabytes. By default `100M` (100 megabytes). Please note that this is
only the limit of Part-DB. You still need to configure the php.ini `upload_max_filesize` and `post_max_size` to allow only the limit of Part-DB. You still need to configure the php.ini `upload_max_filesize` and `post_max_size` to allow
bigger files to be uploaded. bigger files to be uploaded.
* `DEFAULT_URI`: The default URI base to use for the Part-DB, when no URL can be determined from the browser request. * `DEFAULT_URI`: The default URI base to use for the Part-DB, when no URL can be determined from the browser request.
@ -68,8 +79,8 @@ options listed, see `.env` file for full list of possible env variables.
emails and other places, where the URL is needed. It is also used, when SAML is enabled.s If you are using a reverse emails and other places, where the URL is needed. It is also used, when SAML is enabled.s If you are using a reverse
proxy, you should set this to the URL of the reverse proxy (e.g. `https://part-db.example.com`). **This value must end proxy, you should set this to the URL of the reverse proxy (e.g. `https://part-db.example.com`). **This value must end
with a slash**. with a slash**.
* `ENFORCE_CHANGE_COMMENTS_FOR`: With this option you can configure, where users are enforced to give a change reason, * `ENFORCE_CHANGE_COMMENTS_FOR`: With this option, you can configure, where users are enforced to give a change reason,
which will be written to the log. This is a comma separated list of values (e.g. `part_edit,part_delete`). Leave empty which will be written to the log. This is a comma-separated list of values (e.g. `part_edit,part_delete`). Leave empty
to make change comments optional everywhere. Possible values are: to make change comments optional everywhere. Possible values are:
* `part_edit`: Edit operation of an existing part * `part_edit`: Edit operation of an existing part
* `part_delete`: Delete operation of an existing part * `part_delete`: Delete operation of an existing part
@ -80,6 +91,10 @@ options listed, see `.env` file for full list of possible env variables.
* `datastructure_create`: Creation of a new datastructure (e.g. category, manufacturer, ...) * `datastructure_create`: Creation of a new datastructure (e.g. category, manufacturer, ...)
* `CHECK_FOR_UPDATES` (default `1`): Set this to 0, if you do not want Part-DB to connect to GitHub to check for new * `CHECK_FOR_UPDATES` (default `1`): Set this to 0, if you do not want Part-DB to connect to GitHub to check for new
versions, or if your server can not connect to the internet. versions, or if your server can not connect to the internet.
* `APP_SECRET`: This variable is a configuration parameter used for various security-related purposes,
particularly for securing and protecting various aspects of your application. It's a secret key that is used for
cryptographic operations and security measures (session management, CSRF protection, etc..). Therefore this
value should be handled as confidential data and not shared publicly.
### E-Mail settings ### E-Mail settings
@ -88,7 +103,7 @@ options listed, see `.env` file for full list of possible env variables.
mail account, you can use the following syntax `MAILER_DSN=smtp://user:password@smtp.mailserver.invalid:587` mail account, you can use the following syntax `MAILER_DSN=smtp://user:password@smtp.mailserver.invalid:587`
* `EMAIL_SENDER_EMAIL`: The email address from which emails should be sent from (in most cases this has to be the same * `EMAIL_SENDER_EMAIL`: The email address from which emails should be sent from (in most cases this has to be the same
as the email address used for SMTP access) as the email address used for SMTP access)
* `EMAIL_SENDER_NAME`: Similar to `EMAIL_SENDER_EMAIL` but this allows you to specify the name from which the mails are * `EMAIL_SENDER_NAME`: Similar to `EMAIL_SENDER_EMAIL`, but this allows you to specify the name from which the mails are
sent from. sent from.
* `ALLOW_EMAIL_PW_RESET`: Set this value to true, if you want to allow users to reset their password via an email * `ALLOW_EMAIL_PW_RESET`: Set this value to true, if you want to allow users to reset their password via an email
notification. You have to configure the mail provider first before via the MAILER_DSN setting. notification. You have to configure the mail provider first before via the MAILER_DSN setting.
@ -102,15 +117,15 @@ options listed, see `.env` file for full list of possible env variables.
Also specify the default order of the columns. This is a comma separated list of column names. Available columns Also specify the default order of the columns. This is a comma separated list of column names. Available columns
are: `name`, `id`, `ipn`, `description`, `category`, `footprint`, `manufacturer`, `storage_location`, `amount`, `minamount`, `partUnit`, `addedDate`, `lastModified`, `needs_review`, `favorite`, `manufacturing_status`, `manufacturer_product_number`, `mass`, `tags`, `attachments`, `edit`. are: `name`, `id`, `ipn`, `description`, `category`, `footprint`, `manufacturer`, `storage_location`, `amount`, `minamount`, `partUnit`, `addedDate`, `lastModified`, `needs_review`, `favorite`, `manufacturing_status`, `manufacturer_product_number`, `mass`, `tags`, `attachments`, `edit`.
### History/Eventlog related settings ### History/Eventlog-related settings
The following options are used to configure, which (and how much) data is written to the system log: The following options are used to configure, which (and how much) data is written to the system log:
* `HISTORY_SAVE_CHANGED_FIELDS`: When this option is set to true, the name of the fields which are changed, are saved to * `HISTORY_SAVE_CHANGED_FIELDS`: When this option is set to true, the name of the fields that are changed, are saved to
the DB (so for example it is logged that a user has changed, that the user has changed the name and description of the the DB (so for example it is logged that a user has changed, that the user has changed the name and description of the
field, but not the data/content of these changes) field, but not the data/content of these changes)
* `HISTORY_SAVE_CHANGED_DATA`: When this option is set to true, the changed data is saved to log (so it is logged, that * `HISTORY_SAVE_CHANGED_DATA`: When this option is set to true, the changed data is saved to log (so it is logged, that
a user has changed the name of a part and what the name was before). This can increase database size, when you have a a user has changed the name of a part and what the name was before). This can increase database size when you have a
lot of changes to entities. lot of changes to entities.
* `HISTORY_SAVE_REMOVED_DATA`: When this option is set to true, removed data is saved to log, meaning that you can * `HISTORY_SAVE_REMOVED_DATA`: When this option is set to true, removed data is saved to log, meaning that you can
easily undelete an entity, when it was removed accidentally. easily undelete an entity, when it was removed accidentally.
@ -123,10 +138,10 @@ then `HISTORY_SAVE_CHANGED_FIELDS`, `HISTORY_SAVE_CHANGED_DATA` and `HISTORY_SAV
### Error pages settings ### Error pages settings
* `ERROR_PAGE_ADMIN_EMAIL`: You can set an email-address here, which is shown on the error page, who should be contacted * `ERROR_PAGE_ADMIN_EMAIL`: You can set an email address here, which is shown on the error page, who should be contacted
about the issue (e.g. an IT support email of your company) about the issue (e.g. an IT support email of your company)
* `ERROR_PAGE_SHOW_HELP`: Set this 0, to disable the solution hints shown on an error page. These hints should not * `ERROR_PAGE_SHOW_HELP`: Set this 0, to disable the solution hints shown on an error page. These hints should not
contain sensitive information, but could confuse end-users. contain sensitive information but could confuse end-users.
### EDA related settings ### EDA related settings
@ -140,21 +155,21 @@ then `HISTORY_SAVE_CHANGED_FIELDS`, `HISTORY_SAVE_CHANGED_DATA` and `HISTORY_SAV
The following settings can be used to enable and configure Single-Sign on via SAML. This allows users to log in to The following settings can be used to enable and configure Single-Sign on via SAML. This allows users to log in to
Part-DB without entering a username and password, but instead they are redirected to a SAML Identity Provider (IdP) and Part-DB without entering a username and password, but instead they are redirected to a SAML Identity Provider (IdP) and
are logged in automatically. This is especially useful, when you want to use Part-DB in a company, where all users have are logged in automatically. This is especially useful when you want to use Part-DB in a company, where all users have
a SAML account (e.g. via Active Directory or LDAP). a SAML account (e.g. via Active Directory or LDAP).
You can find more advanced settings in the `config/packages/hslavich_onelogin_saml.yaml` file. Please note that this You can find more advanced settings in the `config/packages/hslavich_onelogin_saml.yaml` file. Please note that this
file is not backed up by the backup script, so you have to back up it manually, if you want to keep your changes. If you file is not backed up by the backup script, so you have to back up it manually, if you want to keep your changes. If you
want to edit it on docker, you have to map the file to a volume. want to edit it on docker, you have to map the file to a volume.
* `SAML_ENABLED`: When this is set to 1, SAML SSO is enabled and the SSO Login button is shown in the login form. You * `SAML_ENABLED`: When this is set to 1, SAML SSO is enabled and the SSO Login button is shown in the login form. You
have to configure the SAML settings below, before you can use this feature. have to configure the SAML settings below before you can use this feature.
* `SAML_BEHIND_PROXY`: Set this to 1, if Part-DB is behind a reverse proxy. See [here]({% link installation/reverse-proxy.md %}) * `SAML_BEHIND_PROXY`: Set this to 1, if Part-DB is behind a reverse proxy. See [here]({% link installation/reverse-proxy.md %})
for more information. Otherwise, leave it to 0 (default.) for more information. Otherwise, leave it to 0 (default.)
* `SAML_ROLE_MAPPING`: A [JSON](https://en.wikipedia.org/wiki/JSON) encoded map which specifies how Part-DB should * `SAML_ROLE_MAPPING`: A [JSON](https://en.wikipedia.org/wiki/JSON)-encoded map which specifies how Part-DB should
convert the user roles given by SAML attribute `group` should be converted to a Part-DB group (specified by ID). You convert the user roles given by SAML attribute `group` should be converted to a Part-DB group (specified by ID). You
can use a wildcard `*` to map all otherwise unmapped roles to a certain group. can use a wildcard `*` to map all otherwise unmapped roles to a certain group.
Example: `{"*": 1, "admin": 2, "editor": 3}`. This would map all roles to the group with ID 1, except the Example: `{"*": 1, "admin": 2, "editor": 3}`. This would map all roles to the group with ID 1, except the
role `admin`, which is mapped to the group with ID 2 and the role `editor`, which is mapped to the group with ID 3. role `admin`, which is mapped to the group with ID 2, and the role `editor`, which is mapped to the group with ID 3.
* `SAML_UPDATE_GROUP_ON_LOGIN`: When this is enabled the group of the user is updated on every login of the user based * `SAML_UPDATE_GROUP_ON_LOGIN`: When this is enabled the group of the user is updated on every login of the user based
on the SAML role attributes. When this is disabled, the group is only assigned on the first login of the user, and a on the SAML role attributes. When this is disabled, the group is only assigned on the first login of the user, and a
Part-DB administrator can change the group afterward by editing the user. Part-DB administrator can change the group afterward by editing the user.
@ -182,24 +197,31 @@ want to edit it on docker, you have to map the file to a volume.
The settings prefixes with `PROVIDER_*` are used to configure the information providers. The settings prefixes with `PROVIDER_*` are used to configure the information providers.
See the [information providers]({% link usage/information_provider_system.md %}) page for more information. See the [information providers]({% link usage/information_provider_system.md %}) page for more information.
### Other / less used options ### Other / less-used options
* `TRUSTED_PROXIES`: Set the IP addresses (or IP blocks) of trusted reverse proxies here. This is needed to get correct * `TRUSTED_PROXIES`: Set the IP addresses (or IP blocks) of trusted reverse proxies here. This is needed to get correct
IP information (see [here](https://symfony.com/doc/current/deployment/proxies.html) for more info). IP information (see [here](https://symfony.com/doc/current/deployment/proxies.html) for more info).
* `TRUSTED_HOSTS`: To prevent `HTTP Host header attacks` you can set a regex containing all host names via which Part-DB * `TRUSTED_HOSTS`: To prevent `HTTP Host header attacks` you can set a regex containing all host names via which Part-DB
should be accessible. If accessed via the wrong hostname, an error will be shown. should be accessible. If accessed via the wrong hostname, an error will be shown.
* `DEMO_MODE`: Set Part-DB into demo mode, which forbids users to change their passwords and settings. Used for the demo * `DEMO_MODE`: Set Part-DB into demo mode, which forbids users to change their passwords and settings. Used for the demo
instance, should not be needed for normal installations. instance. This should not be needed for normal installations.
* `NO_URL_REWRITE_AVAILABLE` (allowed values `true` or `false`): Set this value to true, if your webserver does not * `NO_URL_REWRITE_AVAILABLE` (allowed values `true` or `false`): Set this value to true, if your webserver does not
support rewrite. In this case, all URL paths will contain index.php/, which is needed then. Normally this setting do support rewrite. In this case, all URL paths will contain index.php/, which is needed then. Normally this setting does
not need to be changed. not need to be changed.
* `REDIRECT_TO_HTTPS`: If this is set to true, all requests to http will be redirected to https. This is useful if your
web server does not already do this (like the one used in the demo instance). If your web server already redirects to
https, you don't need to set this. Ensure that Part-DB is accessible via HTTPS before you enable this setting.
* `FIXER_API_KEY`: If you want to automatically retrieve exchange rates for base currencies other than euros, you have to * `FIXER_API_KEY`: If you want to automatically retrieve exchange rates for base currencies other than euros, you have to
configure an exchange rate provider API. [Fixer.io](https://fixer.io/) is preconfigured, and you just have to register configure an exchange rate provider API. [Fixer.io](https://fixer.io/) is preconfigured, and you just have to register
there and set the retrieved API key in this environment variable. there and set the retrieved API key in this environment variable.
* `APP_ENV`: This value should always be set to `prod` in normal use. Set it to `dev` to enable debug/development * `APP_ENV`: This value should always be set to `prod` in normal use. Set it to `dev` to enable debug/development
mode. (**You should not do this on a publicly accessible server, as it will leak sensitive information!**) mode. (**You should not do this on a publicly accessible server, as it will leak sensitive information!**)
* `BANNER`: You can configure the text that should be shown as the banner on the homepage. Useful especially for docker * `BANNER`: You can configure the text that should be shown as the banner on the homepage. Useful especially for docker
container. In all other applications you can just change the `config/banner.md` file. containers. In all other applications you can just change the `config/banner.md` file.
* `DISABLE_YEAR2038_BUG_CHECK`: If set to `1`, the year 2038 bug check is disabled on 32-bit systems, and dates after
2038 are no longer forbidden. However this will lead to 500 error messages when rendering dates after 2038 as all current
32-bit PHP versions can not format these dates correctly. This setting is for the case that future PHP versions will
handle this correctly on 32-bit systems. 64-bit systems are not affected by this bug, and the check is always disabled.
## Banner ## Banner
@ -212,8 +234,7 @@ markdown (and even some subset of HTML) syntax to format the text.
You can also configure some options via the `config/parameters.yaml` file. This should normally not need, You can also configure some options via the `config/parameters.yaml` file. This should normally not need,
and you should know what you are doing, when you change something here. You should expect, that you will have to do some and you should know what you are doing, when you change something here. You should expect, that you will have to do some
manual merge, when you have changed something here and update to a newer version of Part-DB. It is possible that manual merge, when you have changed something here and update to a newer version of Part-DB. It is possible that
configuration configuration options here will change or be completely removed in future versions of Part-DB.
options here will change or completely removed in future versions of Part-DB.
If you change something here, you have to clear the cache, before the changes will take effect with the If you change something here, you have to clear the cache, before the changes will take effect with the
command `bin/console cache:clear`. command `bin/console cache:clear`.

View file

@ -25,10 +25,10 @@ It is installed on a web server and so can be accessed with any browser without
## Features ## Features
* Inventory management of your electronic parts. Each part can be assigned to a category, footprint, manufacturer * Inventory management of your electronic parts. Each part can be assigned to a category, footprint, manufacturer,
and multiple store locations and price information. Parts can be grouped using tags. You can associate various files and multiple store locations and price information. Parts can be grouped using tags. You can associate various files
like datasheets or pictures with the parts. like datasheets or pictures with the parts.
* Multi-Language support (currently German, English, Russian, Japanese and French (experimental)) * Multi-language support (currently German, English, Russian, Japanese and French (experimental))
* Barcodes/Labels generator for parts and storage locations, scan barcodes via webcam using the builtin barcode scanner * Barcodes/Labels generator for parts and storage locations, scan barcodes via webcam using the builtin barcode scanner
* User system with groups and detailed (fine granular) permissions. * User system with groups and detailed (fine granular) permissions.
Two-factor authentication is supported (Google Authenticator and Webauthn/U2F keys) and can be enforced for groups. Two-factor authentication is supported (Google Authenticator and Webauthn/U2F keys) and can be enforced for groups.
@ -41,12 +41,12 @@ It is installed on a web server and so can be accessed with any browser without
* Event log: Track what changes happens to your inventory, track which user does what. Revert your parts to older * Event log: Track what changes happens to your inventory, track which user does what. Revert your parts to older
versions. versions.
* Responsive design: You can use Part-DB on your PC, your tablet and your smartphone using the same interface. * Responsive design: You can use Part-DB on your PC, your tablet and your smartphone using the same interface.
* MySQL and SQLite supported as database backends * MySQL, SQLite and PostgreSQL are supported as database backends
* Support for rich text descriptions and comments in parts * Support for rich text descriptions and comments in parts
* Support for multiple currencies and automatic update of exchange rates supported * Support for multiple currencies and automatic update of exchange rates supported
* Powerful search and filter function, including parametric search (search for parts according to some specifications) * Powerful search and filter function, including parametric search (search for parts according to some specifications)
* Easy migration from an existing PartKeepr instance (see [here]({%link partkeepr_migration.md %})) * Easy migration from an existing PartKeepr instance (see [here]({%link partkeepr_migration.md %}))
* Use cloud providers (like Octopart, Digikey, farnell or TME) to automatically get part information, datasheets and * Use cloud providers (like Octopart, Digikey, Farnell or TME) to automatically get part information, datasheets and
prices for parts (see [here]({% link usage/information_provider_system.md %})) prices for parts (see [here]({% link usage/information_provider_system.md %}))
* API to access Part-DB from other applications/scripts * API to access Part-DB from other applications/scripts
* [Integration with KiCad]({%link usage/eda_integration.md %}): Use Part-DB as central datasource for your * [Integration with KiCad]({%link usage/eda_integration.md %}): Use Part-DB as central datasource for your

View file

@ -7,10 +7,18 @@ nav_order: 1
# Choosing database: SQLite or MySQL # Choosing database: SQLite or MySQL
Part-DB saves its data in a [relational (SQL) database](https://en.wikipedia.org/wiki/Relational_database). Part-DB Part-DB saves its data in a [relational (SQL) database](https://en.wikipedia.org/wiki/Relational_database).
supports either the use of [SQLite](https://www.sqlite.org/index.html)
or [MySQL](https://www.mysql.com/) / [MariaDB](https://mariadb.org/) (which are mostly the same, except for some minor For this multiple database types are supported, currently these are:
differences).
* [SQLite](https://www.sqlite.org/index.html)
* [MySQL](https://www.mysql.com/) / [MariaDB](https://mariadb.org/) (which are mostly the same, except for some minor
differences)
* [PostgreSQL](https://www.postgresql.org/)
All these database types allow for the same basic functionality and allow Part-DB to run. However, there are some minor
differences between them, which might be important for you. Therefore the pros and cons of the different database types
are listed here.
{: .important } {: .important }
You have to choose between the database types before you start using Part-DB and **you can not change it (easily) after You have to choose between the database types before you start using Part-DB and **you can not change it (easily) after
@ -18,27 +26,157 @@ you have started creating data**. So you should choose the database type for you
## Comparison ## Comparison
**SQLite** is the default database type which is configured out of the box. All data is saved in a single file ( ### SQLite
normally `var/app.db` in the Part-DB folder) and no additional installation or configuration besides Part-DB is needed.
To use **MySQL/MariaDB** as database, you have to install and configure the MySQL server, configure it and create a
database and user for Part-DB, which needs some additional work. When using docker you need an additional docker
container, and volume for the data
When using **SQLite** The database can be backuped easily by just copying the SQLite file to a safe place. Ideally the * #### Pros
*MySQL** database has to be dumped to a SQL file (using `mysqldump`). The `console partdb:backup` command can do this
automatically
However, SQLite does not support certain operations like regex search, which has to be emulated by PHP and therefore are * **Easy to use**: No additional installation or configuration is needed, just start Part-DB and it will work out of the box
pretty slow compared to the same operation at MySQL. In future there might be features that may only be available, when * **Easy backup**: Just copy the SQLite file to a safe place, and you have a backup, which you can restore by copying it
using MySQL. back. No need to work with SQL dumps
In general MySQL might perform better for big Part-DB instances with many entries, lots of users and high activity, than #### Cons
SQLite.
## Conclusion and Suggestion * **Performance**: SQLite is not as fast as MySQL or PostgreSQL, especially when using complex queries or many users.
* **Emulated RegEx search**: SQLite does not support RegEx search natively. Part-DB can emulate it, however that is pretty slow.
* **Emualted natural sorting**: SQLite does not support natural sorting natively. Part-DB can emulate it, but it is pretty slow.
* **Limitations with Unicode**: SQLite has limitations in comparisons and sorting of Unicode characters, which might lead to
unexpected behavior when using non-ASCII characters in your data. For example `µ` (micro sign) is not seen as equal to
`μ` (greek minuscule mu), therefore searching for `µ` (micro sign) will not find parts containing `μ` (mu) and vice versa.
The other databases behave more intuitive in this case.
* **No advanced features**: SQLite do no support many of the advanced features of MySQL or PostgreSQL, which might be utilized
in future versions of Part-DB
### MySQL/MariaDB
**If possible, it is recommended to use MariaDB 10.7+ (instead of MySQL), as it supports natural sorting of columns natively.**
#### Pros
* **Performance**: Compared to SQLite, MySQL/MariaDB will probably perform better, especially in large databases with many
users and high activity.
* **Natural Sorting**: MariaDB 10.7+ supports natural sorting of columns. On other databases it has to be emulated, which is pretty
slow.
* **Native RegEx search**: MySQL supports RegEx search natively, which is faster than emulating it in PHP.
* **Advanced features**: MySQL/MariaDB supports many advanced features, which might be utilized in future versions of Part-DB.
* **Full Unicode support**: MySQL/MariaDB has better support for Unicode characters, which makes it more intuitive to use
non-ASCII characters in your data.
#### Cons
* **Additional installation and configuration**: You have to install and configure the MySQL server, create a database and
user for Part-DB, which needs some additional work compared to SQLite.
* **Backup**: The MySQL database has to be dumped to a SQL file (using `mysqldump`). The `console partdb:backup` command can automate this.
### PostgreSQL
#### Pros
* **Performance**: PostgreSQL is known for its performance, especially in large databases with many users and high activity.
* **Advanced features**: PostgreSQL supports many advanced features, which might be utilized in future versions of Part-DB.
* **Full Unicode support**: PostgreSQL has better support for Unicode characters, which makes it more intuitive to use
non-ASCII characters in your data.
* **Native RegEx search**: PostgreSQL supports RegEx search natively, which is faster than emulating it in PHP.
* **Native Natural Sorting**: PostgreSQL supports natural sorting of columns natively in all versions and in general the support for it
is better than on MariaDB.
* **Support of transactional DDL**: PostgreSQL supports transactional DDL, which means that if you encounter a problem during a schema change,
the database will automatically rollback the changes. On MySQL/MariaDB you have to manually rollback the changes, by restoring from a database backup.
#### Cons
* **New backend**: The support of postgresql is new, and it was not tested as much as the other backends. There might be some bugs caused by this.
* **Additional installation and configuration**: You have to install and configure the PostgreSQL server, create a database and
user for Part-DB, which needs some additional work compared to SQLite.
* **Backup**: The PostgreSQL database has to be dumped to a SQL file (using `pg_dump`). The `console partdb:backup` command can automate this.
## Recommendation
When you are a hobbyist and use Part-DB for your own small inventory management with only you as user (or maybe sometimes When you are a hobbyist and use Part-DB for your own small inventory management with only you as user (or maybe sometimes
a few other people), then the easy-to-use SQLite database will be fine. a few other people), then the easy-to-use SQLite database will be fine, as long as you can live with the limitations, stated above.
However using MariaDB (or PostgreSQL), has no disadvantages in that situation (besides the initial setup requirements), so you might
want to use it, to be prepared for future use cases.
When you are planning to have a very big database, with a lot of entries and many users which regularly (and When you are planning to have a very big database, with a lot of entries and many users which regularly using Part-DB, then you should
concurrently) using Part-DB you should maybe use MySQL as this will scale better. use MariaDB or PostgreSQL, as they will perform better in that situation and allow for more advanced features.
If you should use MariaDB or PostgreSQL depends on your personal preference and what you already have installed on your servers and
what you are familiar with.
## Using the different databases
The only difference in using the different databases, is a different value in the `DATABASE_URL` environment variable in the `.env.local` file
or in the `DATABASE_URL` environment variable in your server or container configuration. It has the shape of a URL, where the scheme (the part before `://`)
is the database type, and the rest is connection information.
**The env var format below is for the `env.local` file. It might work differently for other env configuration. E.g. in a docker-compose file you have to remove the quotes!**
### SQLite
```shell
DATABASE_URL="sqlite:///%kernel.project_dir%/var/app.db"
```
Here you just need to configure the path to the SQLite file, which is created by Part-DB when performing the database migrations.
The `%kernel.project_dir%` is a placeholder for the path to the project directory, which is replaced by the actual path by Symfony, so that you do not
need to specify the path manually. In the example the database will be created as `app.db` in the `var` directory of your Part-DB installation folder.
### MySQL/MariaDB
```shell
DATABASE_URL="mysql://user:password@127.0.0.1:3306/database?serverVersion=8.0.37"
```
Here you have to replace `user`, `password` and `database` with the credentials of the MySQL/MariaDB user and the database name you want to use.
The host (here 127.0.0.1) and port should also be specified according to your MySQL/MariaDB server configuration.
In the `serverVersion` parameter you can specify the version of the MySQL/MariaDB server you are using, in the way the server returns it
(e.g. `8.0.37` for MySQL and `10.4.14-MariaDB`). If you do not know it, you can leave the default value.
If you want to use a unix socket for the connection instead of a TCP connnection, you can specify the socket path in the `unix_socket` parameter.
```shell
DATABASE_URL="mysql://user:password@localhost/database?serverVersion=8.0.37&unix_socket=/var/run/mysqld/mysqld.sock"
```
### PostgreSQL
```shell
DATABASE_URL="postgresql://db_user:db_password@127.0.0.1:5432/db_name?serverVersion=12.19&charset=utf8"
```
Here you have to replace `db_user`, `db_password` and `db_name` with the credentials of the PostgreSQL user and the database name you want to use.
The host (here 127.0.0.1) and port should also be specified according to your PostgreSQL server configuration.
In the `serverVersion` parameter you can specify the version of the PostgreSQL server you are using, in the way the server returns it
(e.g. `12.19 (Debian 12.19-1.pgdg120+1)`). If you do not know it, you can leave the default value.
The `charset` parameter specify the character set of the database. It should be set to `utf8` to ensure that all characters are stored correctly.
If you want to use a unix socket for the connection instead of a TCP connnection, you can specify the socket path in the `host` parameter.
```shell
DATABASE_URL="postgresql://db_user@localhost/db_name?serverVersion=16.6&charset=utf8&host=/var/run/postgresql"
```
## Natural Sorting
Natural sorting is the sorting of strings in a way that numbers are sorted by their numerical value, not by their ASCII value.
For example in the classical binary sorting the string `DIP-4`, `DIP-8`, `DIP-16`, `DIP-28` would be sorted as following:
* `DIP-16`
* `DIP-28`
* `DIP-4`
* `DIP-8`
In natural sorting, it would be sorted as:
* `DIP-4`
* `DIP-8`
* `DIP-16`
* `DIP-28`
Part-DB can sort names in part tables and tree views naturally. PostgreSQL and MariaDB 10.7+ support natural sorting natively,
and it is automatically used if available.
For SQLite and MySQL < 10.7 it has to be emulated if wanted, which is pretty slow. Therefore it has to be explicity enabled by setting the
`DATABASE_EMULATE_NATURAL_SORT` environment variable to `1`. If it is 0 the classical binary sorting is used, on these databases. The emulations
might have some quirks and issues, so it is recommended to use a database which supports natural sorting natively, if you want to use it.

View file

@ -7,3 +7,5 @@ has_children: true
# Installation # Installation
Below you can find some guides to install Part-DB. Below you can find some guides to install Part-DB.
For the hobbyists without much experience, we recommend the docker installation or direct installation on debian.

View file

@ -16,11 +16,14 @@ where docker is available (especially recommended for Windows and macOS).
> network. > network.
> If you want to expose Part-DB to the internet, you have to configure a reverse proxy with an SSL certificate! > If you want to expose Part-DB to the internet, you have to configure a reverse proxy with an SSL certificate!
It is recommended to install Part-DB on a 64-bit system, as the 32-bit version of PHP is affected by the
[Year 2038 problem](https://en.wikipedia.org/wiki/Year_2038_problem) and can not handle dates after 2038 correctly.
## Docker-compose ## Docker-compose
Docker-compose configures the needed images and automatically creates the needed containers and volumes. Docker-compose configures the needed images and automatically creates the needed containers and volumes.
1. Install docker and docker-compose like described under https://docs.docker.com/compose/install/ 1. Install docker and docker-compose as described under https://docs.docker.com/compose/install/
2. Create a folder where the Part-DB data should live 2. Create a folder where the Part-DB data should live
3. Create a file named docker-compose.yaml with the following content: 3. Create a file named docker-compose.yaml with the following content:
@ -45,6 +48,12 @@ services:
# In docker env logs will be redirected to stderr # In docker env logs will be redirected to stderr
- APP_ENV=docker - APP_ENV=docker
# Uncomment this, if you want to use the automatic database migration feature. With this you have you do not have to
# run the doctrine:migrations:migrate commands on installation or upgrade. A database backup is written to the uploads/
# folder (under .automigration-backup), so you can restore it, if the migration fails.
# This feature is currently experimental, so use it at your own risk!
# - DB_AUTOMIGRATE=true
# You can configure Part-DB using environment variables # You can configure Part-DB using environment variables
# Below you can find the most essential ones predefined # Below you can find the most essential ones predefined
# However you can add any other environment configuration you want here # However you can add any other environment configuration you want here
@ -74,7 +83,7 @@ services:
# - TRUSTED_PROXIES=127.0.0.0/8,::1,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16 # - TRUSTED_PROXIES=127.0.0.0/8,::1,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16
``` ```
4. Customize the settings by changing the environment variables (or add new ones). See [Configuration]({% link 4. Customize the settings by changing the environment variables (or adding new ones). See [Configuration]({% link
configuration.md %}) for more information. configuration.md %}) for more information.
5. Inside the folder, run 5. Inside the folder, run
@ -90,10 +99,10 @@ docker exec --user=www-data partdb php bin/console doctrine:migrations:migrate
and watch for the password output and watch for the password output
6. Part-DB is available under `http://localhost:8080` and you can log in with username `admin` and the password shown 6. Part-DB is available under `http://localhost:8080` and you can log in with the username `admin` and the password shown
before before
The docker image uses a SQLite database and all data (database, uploads and other media) is put into folders relative to The docker image uses a SQLite database and all data (database, uploads, and other media) is put into folders relative to
the docker-compose.yml. the docker-compose.yml.
### MySQL ### MySQL
@ -127,6 +136,12 @@ services:
# In docker env logs will be redirected to stderr # In docker env logs will be redirected to stderr
- APP_ENV=docker - APP_ENV=docker
# Uncomment this, if you want to use the automatic database migration feature. With this you have you do not have to
# run the doctrine:migrations:migrate commands on installation or upgrade. A database backup is written to the uploads/
# folder (under .automigration-backup), so you can restore it, if the migration fails.
# This feature is currently experimental, so use it at your own risk!
# - DB_AUTOMIGRATE=true
# You can configure Part-DB using environment variables # You can configure Part-DB using environment variables
# Below you can find the most essential ones predefined # Below you can find the most essential ones predefined
# However you can add add any other environment configuration you want here # However you can add add any other environment configuration you want here
@ -155,7 +170,7 @@ services:
container_name: partdb_database container_name: partdb_database
image: mysql:8.0 image: mysql:8.0
restart: unless-stopped restart: unless-stopped
command: --default-authentication-plugin=mysql_native_password command: --default-authentication-plugin=mysql_native_password --log-bin-trust-function-creators=1
environment: environment:
# Change this Password # Change this Password
MYSQL_ROOT_PASSWORD: SECRET_ROOT_PASSWORD MYSQL_ROOT_PASSWORD: SECRET_ROOT_PASSWORD
@ -183,25 +198,29 @@ docker exec --user=www-data partdb php bin/console doctrine:migrations:migrate
## Direct use of docker image ## Direct use of docker image
You can use the `jbtronics/part-db1:master` image directly. You have to expose the port 80 to a host port and configure You can use the `jbtronics/part-db1:master` image directly. You have to expose port 80 to a host port and configure
volumes for `/var/www/html/uploads` and `/var/www/html/public/media`. volumes for `/var/www/html/uploads` and `/var/www/html/public/media`.
If you want to use SQLite database (which is default), you have to configure Part-DB to put the database file in a If you want to use SQLite database (which is default), you have to configure Part-DB to put the database file in a
mapped volume via the `DATABASE_URL` environment variable. mapped volume via the `DATABASE_URL` environment variable.
For example if you set `DATABASE_URL=sqlite:///%kernel.project_dir%/var/db/app.db` then you will have to map For example, if you set `DATABASE_URL=sqlite:///%kernel.project_dir%/var/db/app.db` then you will have to map
the `/var/www/html/var/db/` folder to the docker container (see docker-compose.yaml for example). the `/var/www/html/var/db/` folder to the docker container (see docker-compose.yaml for example).
You also have to create the database like described above in step 4. You also have to create the database as described above in step 4.
## Running console commands ## Running console commands
You can run the console commands described in README by You can run the console commands described in README by
executing `docker exec --user=www-data -it partdb bin/console [command]` executing `docker exec --user=www-data -it partdb bin/console [command]`
{: .warning }
> If you run a root console inside the container, and wanna execute commands on the webserver behalf, be sure to use `sudo -E` command (with the `-E` flag) to preserve env variables from the current shell.
> Otherwise Part-DB console might use the wrong configuration to execute commands.
## Troubleshooting ## Troubleshooting
*Login not possible. Login page is just reloading and no error message is shown or something like "CSFR token invalid"*: *Login is not possible. Login page is just reloading and no error message is shown or something like "CSFR token invalid"*:
Clear all cookies in your browser or use an inkognito tab for Part-DB. Clear all cookies in your browser or use an incognito tab for Part-DB.
This related to the fact that Part-DB can not set cookies via HTTP, after some webpage has set cookies before under This is related to the fact that Part-DB can not set cookies via HTTP after some webpages have set cookies before under
localhost via https. This is a security mechanism of the browser and can not be bypassed by Part-DB. localhost via HTTPS. This is a security mechanism of the browser and can not be bypassed by Part-DB.

View file

@ -8,9 +8,9 @@ nav_order: 4
# Part-DB installation guide for Debian 11 (Bullseye) # Part-DB installation guide for Debian 11 (Bullseye)
This guide shows you how to install Part-DB directly on Debian 11 using apache2 and SQLite. This guide should work with This guide shows you how to install Part-DB directly on Debian 11 using apache2 and SQLite. This guide should work with
recent Ubuntu and other Debian based distributions with little to no changes. recent Ubuntu and other Debian-based distributions with little to no changes.
Depending on what you want to do, using the prebuilt docker images may be a better choice, as you don't need to install Depending on what you want to do, using the prebuilt docker images may be a better choice, as you don't need to install
this many dependencies. See [here]({% link installation/installation_docker.md %}) for more information of the docker this many dependencies. See [here]({% link installation/installation_docker.md %}) for more information on the docker
installation. installation.
{: .warning } {: .warning }
@ -18,6 +18,9 @@ installation.
> network. > network.
> If you want to expose Part-DB to the internet, you HAVE to configure an SSL connection! > If you want to expose Part-DB to the internet, you HAVE to configure an SSL connection!
It is recommended to install Part-DB on a 64-bit system, as the 32-bit version of PHP is affected by the
[Year 2038 problem](https://en.wikipedia.org/wiki/Year_2038_problem) and can not handle dates after 2038 correctly.
## Installation with SQLite database ## Installation with SQLite database
### Install prerequisites ### Install prerequisites
@ -30,8 +33,8 @@ sudo apt install git curl zip ca-certificates software-properties-common apt-tra
### Install PHP and apache2 ### Install PHP and apache2
Part-DB is written in [PHP](https://php.net) and therefore needs an PHP interpreter to run. Part-DB needs PHP 8.1 or Part-DB is written in [PHP](https://php.net) and therefore needs a PHP interpreter to run. Part-DB needs PHP 8.1 or
higher, however it is recommended to use the most recent version of PHP for performance reasons and future higher. However, it is recommended to use the most recent version of PHP for performance reasons and future
compatibility. compatibility.
As Debian 11 does not ship PHP 8.1 in its default repositories, we have to add a repository for it. You can skip this As Debian 11 does not ship PHP 8.1 in its default repositories, we have to add a repository for it. You can skip this
@ -46,7 +49,7 @@ sudo curl -sSL https://packages.sury.org/php/README.txt | sudo bash -x
sudo apt update && sudo apt upgrade sudo apt update && sudo apt upgrade
``` ```
Now you can install PHP 8.1 and required packages (change the 8.1 in the package version according to the version you Now you can install PHP 8.1 and the required packages (change the 8.1 in the package version according to the version you
want to use): want to use):
```bash ```bash
@ -57,8 +60,8 @@ The apache2 webserver should be already installed with this command and configur
### Install composer ### Install composer
Part-DB uses [composer](https://getcomposer.org/) to install required PHP libraries. As the versions shipped in the Part-DB uses [composer](https://getcomposer.org/) to install required PHP libraries. As the version shipped in the
repositories is pretty old we install it manually: repositories is pretty old, we will install it manually:
```bash ```bash
# Download composer installer script # Download composer installer script
@ -72,7 +75,7 @@ chmod +x /usr/local/bin/composer
### Install yarn and nodejs ### Install yarn and nodejs
To build the front end (the user interface) Part-DB uses [yarn](https://yarnpkg.com/). As it depends on Node.js and the To build the front end (the user interface) Part-DB uses [yarn](https://yarnpkg.com/). As it depends on Node.js and the
shipped versions are pretty old, we install new versions from official Node.js repository: shipped versions are pretty old, we install new versions from the official Node.js repository:
```bash ```bash
# Add recent node repository (nodejs 18 is supported until 2025) # Add recent node repository (nodejs 18 is supported until 2025)
@ -102,7 +105,7 @@ later.
git clone https://github.com/Part-DB/Part-DB-symfony.git /var/www/partdb git clone https://github.com/Part-DB/Part-DB-symfony.git /var/www/partdb
``` ```
By default, you are now on the latest development version. In most cases you want to use the latest stable version. You By default, you are now on the latest development version. In most cases, you want to use the latest stable version. You
can switch to the latest stable version (tagged) by running the following command: can switch to the latest stable version (tagged) by running the following command:
```bash ```bash
@ -110,7 +113,7 @@ can switch to the latest stable version (tagged) by running the following comman
git checkout $(git describe --tags $(git rev-list --tags --max-count=1)) git checkout $(git describe --tags $(git rev-list --tags --max-count=1))
``` ```
Alternatively you can check out a specific version by running ( Alternatively, you can check out a specific version by running (
see [GitHub Releases page](https://github.com/Part-DB/Part-DB-server/releases) for a list of available versions): see [GitHub Releases page](https://github.com/Part-DB/Part-DB-server/releases) for a list of available versions):
```bash ```bash
@ -176,12 +179,12 @@ To check if everything is installed, run the following command:
sudo -u www-data php bin/console partdb:check-requirements sudo -u www-data php bin/console partdb:check-requirements
``` ```
The most things should be green, and no red ones. Yellow messages means optional dependencies which are not important Most things should be green, and no red ones. Yellow messages mean optional dependencies which are not important
but can improve performance and functionality. but can improve performance and functionality.
### Create a database for Part-DB ### Create a database for Part-DB
Part-DB by default uses a file based sqlite database to store the data. Use the following command to create the Part-DB by default uses a file-based SQLite database to store the data. Use the following command to create the
database. The database will normally be created at `/var/www/partdb/var/app.db`. database. The database will normally be created at `/var/www/partdb/var/app.db`.
```bash ```bash
@ -191,8 +194,7 @@ sudo -u www-data php bin/console doctrine:migrations:migrate
The command will warn you about schema changes and potential data loss. Continue with typing `yes`. The command will warn you about schema changes and potential data loss. Continue with typing `yes`.
The command will output several lines of information. Somewhere should be a yellow background message The command will output several lines of information. Somewhere should be a yellow background message
like `The initial password for the "admin" user is: f502481134`. Write down this password as you will need it later for like `The initial password for the "admin" user is: f502481134`. Write down this password as you will need it later for the initial login.
initial login.
### Configure apache2 to show Part-DB ### Configure apache2 to show Part-DB
@ -248,7 +250,7 @@ sudo service apache2 restart
``` ```
and Part-DB should now be available under `http://YourServerIP` (or `http://partdb.lan` if you configured DNS in your and Part-DB should now be available under `http://YourServerIP` (or `http://partdb.lan` if you configured DNS in your
network to point on the server). network to point to the server).
### Login to Part-DB ### Login to Part-DB
@ -288,7 +290,7 @@ sudo -u www-data php bin/console cache:clear
## MySQL/MariaDB database ## MySQL/MariaDB database
To use a MySQL database, follow the steps from above (except the creation of database, we will do this later). To use a MySQL database, follow the steps from above (except the creation of the database, we will do this later).
Debian 11 does not ship MySQL in its repositories anymore, so we use the compatible MariaDB instead: Debian 11 does not ship MySQL in its repositories anymore, so we use the compatible MariaDB instead:
1. Install maria-db with: 1. Install maria-db with:
@ -340,7 +342,7 @@ exit
Change it to the following (you have to replace `YOUR_SECRET_PASSWORD` with the password you have chosen in step 3): Change it to the following (you have to replace `YOUR_SECRET_PASSWORD` with the password you have chosen in step 3):
``` ```
DATABASE_URL=DATABASE_URL=mysql://partdb:YOUR_SECRET_PASSWORD@127.0.0.1:3306/partdb DATABASE_URL=mysql://partdb:YOUR_SECRET_PASSWORD@127.0.0.1:3306/partdb
``` ```
5. Create the database schema with: 5. Create the database schema with:

View file

@ -0,0 +1,42 @@
---
title: Kubernetes / Helm
layout: default
parent: Installation
nav_order: 5
---
# Kubernetes / Helm Charts
If you are using Kubernetes, you can use the [helm charts](https://helm.sh/) provided in this [repository](https://github.com/Part-DB/helm-charts).
## Usage
[Helm](https://helm.sh) must be installed to use the charts. Please refer to
Helm's [documentation](https://helm.sh/docs) to get started.
Once Helm has been set up correctly, add the repo as follows:
`helm repo add part-db https://part-db.github.io/helm-charts`
If you had already added this repo earlier, run `helm repo update` to retrieve
the latest versions of the packages. You can then run `helm search repo
part-db` to see the charts.
To install the part-db chart:
helm install my-part-db part-db/part-db
To uninstall the chart:
helm delete my-part-db
This repository is also available at [ArtifactHUB](https://artifacthub.io/packages/search?repo=part-db).
## Configuration
See the README in the [chart directory](https://github.com/Part-DB/helm-charts/tree/main/charts/part-db) for more
information on the available configuration options.
## Bugreports
If you find issues related to the helm charts, please open an issue in the [helm-charts repository](https://github.com/Part-DB/helm-charts).

View file

@ -13,7 +13,7 @@ configured.
## Setup ## Setup
1. Install composer and yarn like described in the [apache guide]({% link installation/installation_guide-debian.md 1. Install composer and yarn as described in the [apache guide]({% link installation/installation_guide-debian.md
%}#install-composer). %}#install-composer).
2. Create a folder for Part-DB and install and configure it as described 2. Create a folder for Part-DB and install and configure it as described
3. Instead of creating the config for apache, add the following snippet to your nginx config: 3. Instead of creating the config for apache, add the following snippet to your nginx config:
@ -53,6 +53,11 @@ server {
return 404; return 404;
} }
# Set Content-Security-Policy for svg files, to block embedded javascript in there
location ~* \.svg$ {
add_header Content-Security-Policy "default-src 'self'; script-src 'none'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; frame-ancestors 'none';";
}
error_log /var/log/nginx/parts.error.log; error_log /var/log/nginx/parts.error.log;
access_log /var/log/nginx/parts.access.log; access_log /var/log/nginx/parts.access.log;

View file

@ -0,0 +1,31 @@
---
title: Proxmox VE LXC
layout: default
parent: Installation
nav_order: 6
---
# Proxmox VE LXC
{: .warning }
> The proxmox VE LXC script for Part-DB is developed and maintained by [Proxmox VE Helper-Scripts](https://community-scripts.github.io/ProxmoxVE/)
> and not by the Part-DB developers. Keep in mind that the script is not officially supported by the Part-DB developers.
If you are using Proxmox VE you can use the scripts provided by [Proxmox VE Helper-Scripts community](https://community-scripts.github.io/ProxmoxVE/scripts?id=part-db)
to easily install Part-DB in a LXC container.
## Usage
To create a new LXC container with Part-DB, you can use the following command in the Proxmox VE shell:
```bash
bash -c "$(wget -qLO - https://github.com/community-scripts/ProxmoxVE/raw/main/ct/part-db.sh)"
```
The same command can be used to update an existing Part-DB container.
See the [helper script website](https://community-scripts.github.io/ProxmoxVE/scripts?id=part-db) for more information.
## Bugreports
If you find issues related to the proxmox VE LXC script, please open an issue in the [Proxmox VE Helper-Scripts repository](https://github.com/community-scripts/ProxmoxVE).

View file

@ -48,7 +48,7 @@ the [Keycloak Getting Started Guide](https://www.keycloak.org/docs/latest/gettin
*It is recommended to set this value to the domain name of your Part-DB installation, with an attached `/sp` ( *It is recommended to set this value to the domain name of your Part-DB installation, with an attached `/sp` (
e.g. `https://partdb.yourdomain.invalid/sp`)*. e.g. `https://partdb.yourdomain.invalid/sp`)*.
The name field should be set to something human-readable, like `Part-DB`. The name field should be set to something human-readable, like `Part-DB`.
3. Click on `Save` to create the new client. 3. Click on `Save` to create a new client.
### Configure the SAML client ### Configure the SAML client
@ -56,7 +56,7 @@ the [Keycloak Getting Started Guide](https://www.keycloak.org/docs/latest/gettin
* Set `Home URL` to the homepage of your Part-DB installation (e.g. `https://partdb.yourdomain.invalid/`). * Set `Home URL` to the homepage of your Part-DB installation (e.g. `https://partdb.yourdomain.invalid/`).
* Set `Valid redirect URIs` to your homepage with a wildcard at the end ( * Set `Valid redirect URIs` to your homepage with a wildcard at the end (
e.g. `https://partdb.yourdomain.invalid/*`). e.g. `https://partdb.yourdomain.invalid/*`).
* Set `Valid post logout redirect URIs` to `+` to allow all urls from the `Valid redirect URIs`. * Set `Valid post logout redirect URIs` to `+` to allow all URLs from the `Valid redirect URIs`.
* Set `Name ID format` to `username` * Set `Name ID format` to `username`
* Ensure `Force POST binding` is enabled. * Ensure `Force POST binding` is enabled.
* Ensure `Sign documents` is enabled. * Ensure `Sign documents` is enabled.
@ -136,7 +136,7 @@ as the SAML user, but no password set. The user will be marked as a SAML user, s
future. However, in other aspects the user is a normal user, so Part-DB admins can set permissions for SAML users like future. However, in other aspects the user is a normal user, so Part-DB admins can set permissions for SAML users like
for any other user and override permissions assigned via groups. for any other user and override permissions assigned via groups.
For large organizations you maybe want to automatically assign permissions to SAML users based on the roles or For large organizations, you maybe want to automatically assign permissions to SAML users based on the roles or
groups configured in the identity provider. For this purpose Part-DB allows you to map SAML roles or groups to Part-DB groups configured in the identity provider. For this purpose Part-DB allows you to map SAML roles or groups to Part-DB
groups. See the next section for details. groups. See the next section for details.
@ -144,11 +144,11 @@ groups. See the next section for details.
Part-DB allows you to configure a mapping between SAML roles or groups and Part-DB groups. This allows you to Part-DB allows you to configure a mapping between SAML roles or groups and Part-DB groups. This allows you to
automatically assign permissions to SAML users based on the roles or groups configured in the identity provider. For automatically assign permissions to SAML users based on the roles or groups configured in the identity provider. For
example if a user at your SAML provider has the role `admin`, you can configure Part-DB to assign the `admin` group to example, if a user at your SAML provider has the role `admin`, you can configure Part-DB to assign the `admin` group to
this user. This will give the user all permissions of the `admin` group. this user. This will give the user all permissions of the `admin` group.
For this you need first have to create the groups in Part-DB, to which you want to assign the users and configure their For this, you need first have to create the groups in Part-DB, to which you want to assign the users and configure their
permissions. You will need the IDs of the groups, which you can find in the `System->Group` page of Part-DB in the Info permissions. You will need the IDs of the groups, which you can find on the `System->Group` page of Part-DB in the Info
tab. tab.
The map is provided as [JSON](https://en.wikipedia.org/wiki/JSON) encoded map between the SAML role and the group ID, The map is provided as [JSON](https://en.wikipedia.org/wiki/JSON) encoded map between the SAML role and the group ID,
@ -158,7 +158,7 @@ you can configure via the `.env.local` or `docker-compose.yml` file. Please note
string in single quotes here, as JSON itself uses double quotes ( string in single quotes here, as JSON itself uses double quotes (
e.g. `SAML_ROLE_MAPPING='{ "*": 2, "editor": 3, "admin": 1 }`). e.g. `SAML_ROLE_MAPPING='{ "*": 2, "editor": 3, "admin": 1 }`).
For example if you want to assign the group with ID 1 (by default admin) to every SAML user which has the role `admin`, For example, if you want to assign the group with ID 1 (by default admin) to every SAML user which has the role `admin`,
the role with ID 3 (by default editor) to every SAML user with the role `editor` and everybody else to the group with ID the role with ID 3 (by default editor) to every SAML user with the role `editor` and everybody else to the group with ID
2 (by default readonly), you can configure the following map: 2 (by default readonly), you can configure the following map:
@ -176,9 +176,9 @@ If you want to assign users with a certain role to an empty group, provide the g
valid group ID, so the user will not be assigned to any group. valid group ID, so the user will not be assigned to any group.
The SAML roles (or groups depending on your configuration), have to be supplied via a SAML attribute `group`. You have The SAML roles (or groups depending on your configuration), have to be supplied via a SAML attribute `group`. You have
to configure your SAML identity provider to provide this attribute. For example in Keycloak you can configure this to configure your SAML identity provider to provide this attribute. For example, in Keycloak you can configure this
attribute in the `Client scopes` page. Select the `sp-dedicated` client scope (or create a new one) and click attribute on the `Client scopes` page. Select the `sp-dedicated` client scope (or create a new one) and click
on `Add mappers`. Select `Role mapping` or `Group membership`, change the field name and click `Add`. Now Part-DB will on `Add mappers`. Select `Role mapping` or `Group membership`, change the field name, and click `Add`. Now Part-DB will
be provided with the groups of the user based on the Keycloak user database. be provided with the groups of the user based on the Keycloak user database.
By default, the group is assigned to the user on the first login and updated on every login based on the SAML By default, the group is assigned to the user on the first login and updated on every login based on the SAML
@ -203,12 +203,12 @@ provide these attributes, you can use to automatically fill the corresponding fi
## Use SAML Login for existing users ## Use SAML Login for existing users
Part-DB distinguishes between local users and SAML users. Local users are users, which can log in via Part-DB login form Part-DB distinguishes between local users and SAML users. Local users are users, that can log in via the Part-DB login form
and which use the password (hash) saved in the Part-DB database. SAML users are stored in the database too (they are and use the password (hash) saved in the Part-DB database. SAML users are stored in the database too (they are
created on the first login of the user via SAML), but they use the SAML identity provider to authenticate the user and created on the first login of the user via SAML), but they use the SAML identity provider to authenticate the user and
have no password stored in the database. When you try you will get an error message. have no password stored in the database. When you try you will get an error message.
For security reasons it is not possible to authenticate via SAML as a local user (and vice versa). So if you have For security reasons, it is not possible to authenticate via SAML as a local user (and vice versa). So if you have
existing users in your Part-DB database and want them to be able to log in via SAML in the future, you can use existing users in your Part-DB database and want them to be able to log in via SAML in the future, you can use
the `php bin/console partdb:user:convert-to-saml-user username` command to convert them to SAML users. This will remove the `php bin/console partdb:user:convert-to-saml-user username` command to convert them to SAML users. This will remove
the password hash from the database and mark them as SAML users, so they can log in via SAML in the future. the password hash from the database and mark them as SAML users, so they can log in via SAML in the future.

View file

@ -12,34 +12,34 @@ nav_order: 101
This guide describes how to migrate from [PartKeepr](https://partkeepr.org/) to Part-DB. This guide describes how to migrate from [PartKeepr](https://partkeepr.org/) to Part-DB.
Part-DB has a built-in migration tool, which can be used to migrate the data from an existing PartKeepr instance to Part-DB has a built-in migration tool, which can be used to migrate the data from an existing PartKeepr instance to
a new Part-DB instance. Most of the data can be migrated, however there are some limitations, you can find below. a new Part-DB instance. Most of the data can be migrated, however, there are some limitations, that you can find below.
## What can be imported ## What can be imported
* Data structures (Categories, Footprints, Storage Locations, Manufacturers, Distributors, Part Measurement Units) * Data structures (Categories, Footprints, Storage Locations, Manufacturers, Distributors, Part Measurement Units)
* Basic part information's (Name, Description, Comment, etc.) * Basic part information (Name, Description, Comment, etc.)
* Attachments and images of parts, projects, footprints, manufacturers and storage locations * Attachments and images of parts, projects, footprints, manufacturers, and storage locations
* Part prices (distributor infos) * Part prices (distributor infos)
* Part parameters * Part parameters
* Projects (including parts and attachments) * Projects (including parts and attachments)
* Users (optional): Passwords however will be not migrated, and need to be reset later * Users (optional): Passwords however will not be migrated, and need to be reset later
## What can't be imported ## What can't be imported
* Metaparts (A dummy version of the metapart will be created in Part-DB, however it will not function as metapart) * Metaparts (A dummy version of the metapart will be created in Part-DB, however, it will not function as metapart)
* Multiple manufacturers per part (only the last manufacturer of a part will be migrated) * Multiple manufacturers per part (only the last manufacturer of a part will be migrated)
* Overage information for project parts (the overage info will be set as comment in the project BOM, but will have no * Overage information for project parts (the overage info will be set as a comment in the project BOM, but will have no
effect) effect)
* Batch Jobs * Batch Jobs
* Parameter Units (the units will be written into the parameters) * Parameter Units (the units will be written into the parameters)
* Project Reports and Project Runs * Project Reports and Project Runs
* Stock history * Stock History
* Any kind of PartKeepr preferences * Any kind of PartKeepr preferences
## How to migrate ## How to migrate
1. Install Part-DB like described in the installation guide. You can use any database backend you want (mysql or 1. Install Part-DB as described in the installation guide. You can use any database backend you want (MySQL or
sqlite). Run the database migration, but do not create any new data yet. SQLite). Run the database migration, but do not create any new data yet.
2. Export your PartKeepr database as XML file using [mysqldump](https://dev.mysql.com/doc/refman/8.0/en/mysqldump.html): 2. Export your PartKeepr database as XML file using [mysqldump](https://dev.mysql.com/doc/refman/8.0/en/mysqldump.html):
When the MySQL database is running on the local computer, and you are root you can just run the When the MySQL database is running on the local computer, and you are root you can just run the
command `mysqldump --xml PARTKEEPR_DATABASE --result-file pk.xml`. command `mysqldump --xml PARTKEEPR_DATABASE --result-file pk.xml`.
@ -47,7 +47,7 @@ a new Part-DB instance. Most of the data can be migrated, however there are some
run `mysqldump --xml -h PARTKEEPR_HOST -u PARTKEEPR_USER -p PARTKEEPR_DATABASE`, where you replace `PARTKEEPR_HOST` run `mysqldump --xml -h PARTKEEPR_HOST -u PARTKEEPR_USER -p PARTKEEPR_DATABASE`, where you replace `PARTKEEPR_HOST`
with the hostname of your MySQL database and `PARTKEEPR_USER` with the username of MySQL user which has access to the with the hostname of your MySQL database and `PARTKEEPR_USER` with the username of MySQL user which has access to the
PartKeepr database. You will be asked for the MySQL user password. PartKeepr database. You will be asked for the MySQL user password.
3. Go the Part-DB main folder and run the command `php bin/console partdb:migrations:import-partkeepr path/to/pk.xml`. 3. Go to the Part-DB main folder and run the command `php bin/console partdb:migrations:import-partkeepr path/to/pk.xml`.
This step will delete all existing data in the Part-DB database and import the contents of PartKeepr. This step will delete all existing data in the Part-DB database and import the contents of PartKeepr.
4. Copy the contents of `data/files/` from your PartKeepr installation to the `uploads/` folder of your Part-DB 4. Copy the contents of `data/files/` from your PartKeepr installation to the `uploads/` folder of your Part-DB
installation and the contents of `data/images` from PartKeepr to `public/media/` of Part-DB. installation and the contents of `data/images` from PartKeepr to `public/media/` of Part-DB.
@ -63,5 +63,5 @@ option on the database import command (step 3):
All imported users of PartKeepr will be assigned to a new group "PartKeepr Users", which has normal user permissions (so All imported users of PartKeepr will be assigned to a new group "PartKeepr Users", which has normal user permissions (so
editing data, but no administrative tasks). You can change the group and permissions later in Part-DB users management. editing data, but no administrative tasks). You can change the group and permissions later in Part-DB users management.
Passwords can not be imported from PartKeepr and all imported users get marked as disabled user. So to allow users to Passwords can not be imported from PartKeepr and all imported users get marked as disabled. So to allow users to
log in, you need to enable them in the user management and assign a password. log in, you need to enable them in the user management and assign a password.

View file

@ -16,7 +16,7 @@ on how to fix the problem. If you have a problem that is not listed here, please
If you encounter an error, try the following steps: If you encounter an error, try the following steps:
* Clear cache of Part-DB with the console command: * Clear the cache of Part-DB with the console command:
```bash ```bash
php bin/console cache:clear php bin/console cache:clear
@ -30,7 +30,7 @@ php bin/console doctrine:migrations:migrate
If this does not help, please [open an issue on GitHub](https://github.com/Part-DB/Part-DB-symfony). If this does not help, please [open an issue on GitHub](https://github.com/Part-DB/Part-DB-symfony).
## Search for user and reset password: ## Search for the user and reset the password:
You can list all users with the following command: `php bin/console partdb:users:list` You can list all users with the following command: `php bin/console partdb:users:list`
To reset the password of a user you can use the following To reset the password of a user you can use the following

View file

@ -18,33 +18,32 @@ sections carefully before proceeding to upgrade.
* PHP 8.1 or higher is required now (Part-DB 0.5 required PHP 5.4+, Part-DB 0.6 PHP 7.0). * PHP 8.1 or higher is required now (Part-DB 0.5 required PHP 5.4+, Part-DB 0.6 PHP 7.0).
Releases are available for Windows too, so almost everybody should be able to use PHP 8.1 Releases are available for Windows too, so almost everybody should be able to use PHP 8.1
* **Console access highly required.** The installation of composer and frontend dependencies require console access, * **Console access is highly recommended.** The installation of composer and frontend dependencies require console access,
also more sensitive stuff like database migration work via CLI now, so you should have console access on your server. also more sensitive stuff like database migration works via CLI now, so you should have console access on your server.
* Markdown/HTML is now used instead of BBCode for rich text in description and command fields. * Markdown/HTML is now used instead of BBCode for rich text in description and command fields.
It is possible to migrate your existing BBCode to Markdown It is possible to migrate your existing BBCode to Markdown
via `php bin/console php bin/console partdb:migrations:convert-bbcode`. via `php bin/console php bin/console partdb:migrations:convert-bbcode`.
* Server exceptions are not logged to event log anymore. For security reasons (exceptions can contain sensitive * Server exceptions are not logged into event log anymore. For security reasons (exceptions can contain sensitive
information) information) exceptions are only logged to server log (by default under './var/log'), so only the server admins can access it.
exceptions are only logged to server log (by default under './var/log'), so only the server admins can access it. * Profile labels are now saved in the database (before they were saved in a separate JSON file). **The profiles of legacy
* Profile labels are now saved in Database (before they were saved in a separate JSON file). **The profiles of legacy
Part-DB versions can not be imported into new Part-DB 1.0** Part-DB versions can not be imported into new Part-DB 1.0**
* Label placeholders now use the `[[PLACEHOLDER]]` format instead of `%PLACEHOLDER%`. Also, some placeholders has * Label placeholders now use the `[[PLACEHOLDER]]` format instead of `%PLACEHOLDER%`. Also, some placeholders have
changed. changed.
* Configuration is now done via configuration files / environment variables instead of the WebUI (this maybe change in * Configuration is now done via configuration files/environment variables instead of the WebUI (this may change in
the future). the future).
* Database updated are now done via console instead of the WebUI * Database updates are now done via console instead of the WebUI
* Permission system changed: **You will have to newly set the permissions of all users and groups!** * Permission system changed: **You will have to newly set the permissions of all users and groups!**
* Import / Export file format changed. Fields must be english now (unlike in legacy Part-DB versions, where german * Import / Export file format changed. Fields must be English now (unlike in legacy Part-DB versions, where German
fields in CSV were possible) fields in CSV were possible)
and you maybe have to change the header line/field names of your CSV files. and you may have to change the header line/field names of your CSV files.
## Missing features ## Missing features
* No possibility to mark parts for ordering (yet) * No possibility of marking parts for ordering (yet)
* No support for 3D models of footprints (yet) * No support for 3D models of footprints (yet)
* No possibility to disable footprints, manufacturers globally (or per category). This should not have a big impact, * No possibility to disable footprints, manufacturers globally (or per category). This should not have a big impact
when you forbid users to edit/create them. when you forbid users to edit/create them.
* No resistor calculator or SMD labels tools * No resistor calculator or SMD label tools
## Upgrade process ## Upgrade process
@ -56,12 +55,12 @@ sections carefully before proceeding to upgrade.
> Beware that all user and group permissions will be reset, and you have to set the permissions again > Beware that all user and group permissions will be reset, and you have to set the permissions again
> the new Part-DB as many permissions changed, and automatic migration is not possible. > the new Part-DB as many permissions changed, and automatic migration is not possible.
1. Upgrade your existing Part-DB version the newest Part-DB 0.5.* version (at the moment Part-DB 0.5.8), like described 1. Upgrade your existing Part-DB version the newest Part-DB 0.5.* version (at the moment Part-DB 0.5.8), as described
in the old Part-DB's repository. in the old Part-DB's repository.
2. Make a backup of your database and attachments. If something goes wrong during migration, you can use this backup to 2. Make a backup of your database and attachments. If something goes wrong during migration, you can use this backup to
start over. If you have some more complex permission configuration, you maybe want to do screenshots of it, so you start over. If you have some more complex permission configuration, you maybe want to do screenshots of it, so you
can redo it again later. can redo it again later.
3. Set up the new Part-DB like described in installation section. You will need to do the setup for a MySQL instance ( 3. Set up the new Part-DB as described in the installation section. You will need to do the setup for a MySQL instance (
either via docker or direct installation). Set the `DATABASE_URL` environment variable in your `.env.local` ( either via docker or direct installation). Set the `DATABASE_URL` environment variable in your `.env.local` (
or `docker-compose.yaml`) to your existing database. ( or `docker-compose.yaml`) to your existing database. (
e.g. `DATABASE_URL=mysql://PARTDB_USER:PASSWORD@localhost:3306/DATABASE_NAME`) e.g. `DATABASE_URL=mysql://PARTDB_USER:PASSWORD@localhost:3306/DATABASE_NAME`)

View file

@ -7,8 +7,8 @@ parent: Usage
# Backup and Restore Data # Backup and Restore Data
When working productively you should back up the data and configuration of Part-DB regularly to prevent data loss. This When working productively you should back up the data and configuration of Part-DB regularly to prevent data loss. This
is also useful, if you want to migrate your Part-DB instance from one server to another. In that case you just have to is also useful if you want to migrate your Part-DB instance from one server to another. In that case, you just have to
back up the data on server 1, move the backup to server 2, install Part-DB on server 2 and restore the backup. back up the data on server 1, move the backup to server 2, install Part-DB on server 2, and restore the backup.
## Backup (automatic / Part-DB supported) ## Backup (automatic / Part-DB supported)
@ -23,11 +23,11 @@ To back up all possible data, run the following
command: `php bin/console partdb:backup --full /path/to/backup/partdb_backup.zip`. command: `php bin/console partdb:backup --full /path/to/backup/partdb_backup.zip`.
It is possible to do only partial backups (config, attachments, or database). See `php bin/console partdb:backup --help` It is possible to do only partial backups (config, attachments, or database). See `php bin/console partdb:backup --help`
for more infos about these options. for more info about these options.
## Backup (manual) ## Backup (manual)
There are 3 parts which have to be backup-ed: The configuration files, which contains the instance specific options, the 3 parts have to be backup-ed: The configuration files, which contain the instance-specific options, the
uploaded files of attachments, and the database containing the most data of Part-DB. uploaded files of attachments, and the database containing the most data of Part-DB.
Everything else like thumbnails and cache files, are recreated automatically when needed. Everything else like thumbnails and cache files, are recreated automatically when needed.
@ -42,7 +42,7 @@ You have to recursively copy the `uploads/` folder and the `public/media` folder
### Database ### Database
#### Sqlite #### SQLite
If you are using sqlite, it is sufficient to just copy your `app.db` from your database location (normally `var/app.db`) If you are using sqlite, it is sufficient to just copy your `app.db` from your database location (normally `var/app.db`)
to your backup location. to your backup location.
@ -55,8 +55,8 @@ interface (`mysqldump -uBACKUP -pPASSWORD DATABASE`)
## Restore ## Restore
Install Part-DB as usual as described in the installation section, except the database creation / migration part. You Install Part-DB as usual as described in the installation section, except for the database creation/migration part. You
have to use the same database type (sqlite or mysql) as on the back-up server instance. have to use the same database type (SQLite or MySQL) as on the backuped server instance.
### Restore configuration ### Restore configuration
@ -69,7 +69,7 @@ Copy the `uploads/` and the `public/media/` folder from your backup into your ne
### Restore database ### Restore database
#### Sqlite #### SQLite
Copy the backup-ed `app.db` into the database folder normally `var/app.db` in Part-DB root folder. Copy the backup-ed `app.db` into the database folder normally `var/app.db` in Part-DB root folder.

View file

@ -8,11 +8,29 @@ parent: Usage
Part-DB provides some console commands to display various information or perform some tasks. Part-DB provides some console commands to display various information or perform some tasks.
The commands are invoked from the main directory of Part-DB with the command `php bin/console [command]` in the context The commands are invoked from the main directory of Part-DB with the command `php bin/console [command]` in the context
of the database user (so usually the webserver user), so you maybe have to use `sudo` or `su` to execute the commands. of the database user (so usually the webserver user), so you maybe have to use `sudo` or `su` to execute the commands:
```bash
sudo -u www-data php bin/console [command]
```
You can get help for every command with the parameter `--help`. See `php bin/console` for a list of all available You can get help for every command with the parameter `--help`. See `php bin/console` for a list of all available
commands. commands.
If you are running Part-DB in a docker container, you must either execute the commands from a shell inside a container,
or use the `docker exec` command to execute the command directly inside the container. For example if you docker container
is named `partdb`, you can execute the command `php bin/console cache:clear` with the following command:
```bash
docker exec --user=www-data partdb php bin/console cache:clear
```
{: .warning }
> If you run a root console inside the docker container, and wanna execute commands on the webserver behalf, be sure to use `sudo -E` command (with the `-E` flag) to preserve env variables from the current shell.
> Otherwise Part-DB console might use the wrong configuration to execute commands.
## Troubleshooting
## User management commands ## User management commands
* `php bin/console partdb:users:list`: List all users of this Part-DB instance * `php bin/console partdb:users:list`: List all users of this Part-DB instance
@ -53,3 +71,9 @@ commands.
* `php bin/console doctrine:migrations:migrate`: Migrate the database to the latest version * `php bin/console doctrine:migrations:migrate`: Migrate the database to the latest version
* `php bin/console doctrine:migrations:up-to-date`: Check if the database is up-to-date * `php bin/console doctrine:migrations:up-to-date`: Check if the database is up-to-date
## Attachment commands
* `php bin/console partdb:attachments:download`: Download all attachments, which are not already downloaded, to the
local filesystem. This is useful to create local backups of the attachments, no matter what happens on the remote and
also makes pictures thumbnails available for the frontend for them

View file

@ -6,7 +6,7 @@ parent: Usage
# EDA / KiCad integration # EDA / KiCad integration
Part-DB can function as central database for [EDA](https://en.wikipedia.org/wiki/Electronic_design_automation) or ECAD software used to design electronic schematics and PCBs. Part-DB can function as a central database for [EDA](https://en.wikipedia.org/wiki/Electronic_design_automation) or ECAD software used to design electronic schematics and PCBs.
You can connect your EDA software and can view your available parts, with the data saved from Part-DB directly in your EDA software. You can connect your EDA software and can view your available parts, with the data saved from Part-DB directly in your EDA software.
Part-DB allows to configure additional metadata for the EDA, to associate symbols and footprints for use inside the EDA software, so the part becomes Part-DB allows to configure additional metadata for the EDA, to associate symbols and footprints for use inside the EDA software, so the part becomes
directly usable inside the EDA software. directly usable inside the EDA software.
@ -20,12 +20,12 @@ This also allows to configure available and usable parts and their properties in
> Part-DB uses the HTTP library feature of KiCad, which is experimental and not part of the stable KiCad 7 releases. If you want to use this feature, you need to install a KiCad nightly build (7.99 version). This feature will most likely also be part of KiCad 8. > Part-DB uses the HTTP library feature of KiCad, which is experimental and not part of the stable KiCad 7 releases. If you want to use this feature, you need to install a KiCad nightly build (7.99 version). This feature will most likely also be part of KiCad 8.
Part-DB should be accessible from the PCs with KiCAD. The URL should be stable (so no dynamically changing IP). Part-DB should be accessible from the PCs with KiCAD. The URL should be stable (so no dynamically changing IP).
You require a user account in Part-DB, which has the permission to access Part-DB API and create API tokens. Every user can has its own account, or you setup a shared read-only account. You require a user account in Part-DB, which has permission to access Part-DB API and create API tokens. Every user can have its own account, or you set up a shared read-only account.
To connect KiCad with Part-DB do following steps: To connect KiCad with Part-DB do the following steps:
1. Create an API token on the user settings page for the KiCAD application and copy/save it, when it is shown. Currently KiCAD can only read Part-DB database, so a token with read only scope is enough. 1. Create an API token on the user settings page for the KiCAD application and copy/save it, when it is shown. Currently, KiCad can only read Part-DB database, so a token with a read-only scope is enough.
2. Add some EDA metadata to parts, categories or footprints. Only parts with useable info will show up in KiCad. See below for more info. 2. Add some EDA metadata to parts, categories, or footprints. Only parts with usable info will show up in KiCad. See below for more info.
3. Create a file `partd.kicad_httplib` (or similar, only the extension is important) with the following content: 3. Create a file `partd.kicad_httplib` (or similar, only the extension is important) with the following content:
``` ```
{ {
@ -44,34 +44,34 @@ To connect KiCad with Part-DB do following steps:
``` ```
4. Replace the `root_url` with the URL of your Part-DB instance plus `/en/kicad-api/`. You can find the right value for this in the Part-DB user settings page under "API endpoints" in the "API tokens" panel. 4. Replace the `root_url` with the URL of your Part-DB instance plus `/en/kicad-api/`. You can find the right value for this in the Part-DB user settings page under "API endpoints" in the "API tokens" panel.
5. Replace the `token` field value with the token you have generated in step 1. 5. Replace the `token` field value with the token you have generated in step 1.
6. Open KiCad and add this created file as library in the KiCad symbol table under (Preferences --> Manage Symbol Libraries) 6. Open KiCad and add this created file as a library in the KiCad symbol table under (Preferences --> Manage Symbol Libraries)
If you then place a new part, the library dialog opens, and you should be able to see the categories and parts from Part-DB. If you then place a new part, the library dialog opens, and you should be able to see the categories and parts from Part-DB.
### How to associate footprints and symbols with parts ### How to associate footprints and symbols with parts
Part-DB dont save any concrete footprints or symbols for the part. Instead Part-DB just contains a reference string in the part metadata, which points to a symbol/footprint in KiCads local library. Part-DB doesn't save any concrete footprints or symbols for the part. Instead, Part-DB just contains a reference string in the part metadata, which points to a symbol/footprint in KiCad's local library.
You can define this on a per-part basis using the KiCad symbol and KiCad footprint field in the EDA tab of the part editor. Or you can define it at a category (symbol) or footprint level, to assign this value to all parts with this category and footprint. You can define this on a per-part basis using the KiCad symbol and KiCad footprint field in the EDA tab of the part editor. Or you can define it at a category (symbol) or footprint level, to assign this value to all parts with this category and footprint.
For example to configure the values for an BC547 transistor you would put `Transistor_BJT:BC547` on the parts Kicad symbol to give it the right schematic symbol in EEschema and `Package_TO_SOT_THT:TO-92` to give it the right footprint in PcbNew. For example, to configure the values for a BC547 transistor you would put `Transistor_BJT:BC547` on the parts Kicad symbol to give it the right schematic symbol in EEschema and `Package_TO_SOT_THT:TO-92` to give it the right footprint in PcbNew.
If you type in a character, you will get an autocomplete list of all symbols and footprints available in the kicad standard library. You can also input your own value. If you type in a character, you will get an autocomplete list of all symbols and footprints available in the KiCad standard library. You can also input your own value.
### Parts and category visibility ### Parts and category visibility
Only parts and their categories, on which there is any kind of EDA metadata are defined show up in KiCad. So if you want to see parts in KiCad, Only parts and their categories, on which there is any kind of EDA metadata are defined show up in KiCad. So if you want to see parts in KiCad,
you need to define at least a symbol, footprint, reference prefix or value on a part, category or footprint. you need to define at least a symbol, footprint, reference prefix, or value on a part, category or footprint.
You can use the "Force visibility" checkbox on a part or category to override this behavior and force parts to be visible or hidden in KiCad. You can use the "Force visibility" checkbox on a part or category to override this behavior and force parts to be visible or hidden in KiCad.
*Please note that KiCad caches the library categories. So if you change something, which would change the visibile categories in KiCad, you have to reload EEschema to see the changes.* *Please note that KiCad caches the library categories. So if you change something, which would change the visible categories in KiCad, you have to reload EEschema to see the changes.*
### Category depth in KiCad ### Category depth in KiCad
For performance reasons, only the most top level categories of Part-DB are shown as categories in KiCad. All parts in the subcategories are shown in the top level category. For performance reasons, only the most top-level categories of Part-DB are shown as categories in KiCad. All parts in the subcategories are shown in the top-level category.
You can configure the depth of the categories shown in KiCad, via the `EDA_KICAD_CATEGORY_DEPTH` env option. The default value is 0, which meabs only the top level categories are shown. You can configure the depth of the categories shown in KiCad, via the `EDA_KICAD_CATEGORY_DEPTH` env option. The default value is 0, which means only the top-level categories are shown.
To show more levels of categories, you can set this value to a higher number. To show more levels of categories, you can set this value to a higher number.
If you set this value to -1, all parts are shown inside a single category in KiCad, without any subcategories. If you set this value to -1, all parts are shown inside a single category in KiCad, without any subcategories.

View file

@ -18,22 +18,22 @@ Before you start creating data structures, you should configure Part-DB to your
options. options.
This is done either via changing the `.env.local` file in a direct installation or by changing the env variables in This is done either via changing the `.env.local` file in a direct installation or by changing the env variables in
your `docker-compose.yaml` file. your `docker-compose.yaml` file.
A list of possible configuration options, can be found [here]({% link configuration.md %}). A list of possible configuration options can be found [here]({% link configuration.md %}).
## Change password, Set up Two-Factor-Authentication & Customize User settings ## Change password, Set up Two-Factor-Authentication & Customize User settings
If you have not already done, you should change your user password. You can do this in the user settings (available in If you have not already done so, you should change your user password. You can do this in the user settings (available in
the navigation bar drop down with the user symbol). the navigation bar drop-down with the user symbol).
![image]({% link assets/getting_started/change_password.png %}) ![image]({% link assets/getting_started/change_password.png %})
There you can also find the option, to set up Two-Factor Authentication methods like Google Authenticator. Using this is There you can also find the option, to set up Two-Factor Authentication methods like Google Authenticator. Using this is
highly recommended (especially if you have admin permissions) to increase the security of your account. (Two-Factor highly recommended (especially if you have admin permissions) to increase the security of your account. (Two-factor authentication
Authentication even can be enforced for all members of a user group) even can be enforced for all members of a user group)
In the user settings panel you can change account infos like your username, your first and last name (which will be In the user settings panel, you can change account info like your username, your first and last name (which will be
shown alongside your username to identify you better), department information and your email address. The email address shown alongside your username to identify you better), department information, and your email address. The email address
is used to send password reset mails, if your system is configured to use this. is used to send password reset mails if your system is configured to use this.
![image]({% link assets/getting_started/user_settings.png %}) ![image]({% link assets/getting_started/user_settings.png %})
@ -46,7 +46,7 @@ used.
The banner which is shown on the homepage, can be customized/changed by changing the `config/banner.md` file with a text The banner which is shown on the homepage, can be customized/changed by changing the `config/banner.md` file with a text
editor. You can use markdown and (safe) HTML here, to style and customize the banner. editor. You can use markdown and (safe) HTML here, to style and customize the banner.
You can even use Latex style equations by wrapping the expressions into `$` (like `$E=mc^2$`, which is rendered inline: You can even use LaTeX-style equations by wrapping the expressions into `$` (like `$E=mc^2$`, which is rendered inline:
$E=mc^2$) or `$$` (like `$$E=mc^2$$`) which will be rendered as a block, like so: $$E=mc^2$$ $E=mc^2$) or `$$` (like `$$E=mc^2$$`) which will be rendered as a block, like so: $$E=mc^2$$
## Create groups, users and customize permissions ## Create groups, users and customize permissions
@ -55,14 +55,14 @@ $E=mc^2$) or `$$` (like `$$E=mc^2$$`) which will be rendered as a block, like so
When logged in as administrator, you can open the users menu in the `Tools` section of the sidebar When logged in as administrator, you can open the users menu in the `Tools` section of the sidebar
under `System -> Users`. under `System -> Users`.
At this page you can create new users, change their passwords and settings and change their permissions. On this page you can create new users, change their passwords and settings, and change their permissions.
For each user which should use Part-DB you should set up an own account, so that tracking of what user did what works For each user who should use Part-DB you should set up their own account so that tracking of what user did works
properly. properly.
![image]({% link assets/getting_started/user_admin.png %}) ![image]({% link assets/getting_started/user_admin.png %})
You should check the permissions for every user and ensure that they are in the intended way, and no user has more You should check the permissions for every user and ensure that they are in the intended way, and no user has more
permissions than he needs. permissions than he needs.
For each capability you can choose between allow, forbid and inherit. In the last case, the permission is determined by For each capability, you can choose between allow, forbid, and inherit. In the last case, the permission is determined by
the group a user has (if no group is chosen, it equals forbid) the group a user has (if no group is chosen, it equals forbid)
![image]({% link assets/getting_started/user_permissions.png %}) ![image]({% link assets/getting_started/user_permissions.png %})
@ -75,35 +75,34 @@ to restrict the permissions.
### Groups ### Groups
If you have many users which should share the same permissions, it is useful to define the permissions using user If you have many users who should share the same permissions, it is useful to define the permissions using user
groups, which you can create and edit in the `System -> Groups` menu. groups, which you can create and edit in the `System -> Groups` menu.
By default 3 groups are defined: By default, 3 groups are defined:
* `readonly` which users only have read permissions (like viewing, searching parts, attachments, etc.) * `readonly` which users only have read permissions (like viewing, searching parts, attachments, etc.)
* `users` which users also have rights to edit/delete/create elements * `users` which users also have rights to edit/delete/create elements
* `admin` which users can do administrative operations (like creating new users, show global system log, etc.) * `admin` which users can do administrative operations (like creating new users, showing global system log, etc.)
Users only use the setting of a capability from a group, if the user has a group associated and the capability on the Users only use the setting of a capability from a group, if the user has a group associated and the capability on the
user is set to `inherit` (which is the default if creating a new user). You can override the permissions settings of a user is set to `inherit` (which is the default if creating a new user). You can override the permissions settings of a
group per user by explicitly settings the permission at the user. group per user by explicitly setting the permission of the user.
Groups are organized as trees, meaning a group can have parent and child permissions and child groups can inherit Groups are organized as trees, meaning a group can have parent and child permissions and child groups can inherit
permissions from their parents. permissions from their parents.
To inherit the permissions from a parent group set the capability to inherit, otherwise set it explicitly to override To inherit the permissions from a parent group set the capability to inherit, otherwise, set it explicitly to override
the parents' permission. the parents' permission.
## Create Attachment types ## Create Attachment types
Every attachment (that is a file associated with a part, data structure, etc.) must have an attachment type. They can Every attachment (that is a file associated with a part, data structure, etc.) must have an attachment type. They can
be used to group attachments logically, like differentiating between datasheets, pictures and other documents. be used to group attachments logically, like differentiating between datasheets, pictures, and other documents.
You can create/edit attachment types in the tools sidebar under "Edit -> Attachment types": You can create/edit attachment types in the tools sidebar under "Edit -> Attachment types":
![image]({% link assets/getting_started/attachment_type_admin.png %}) ![image]({% link assets/getting_started/attachment_type_admin.png %})
Depending on your use case different entries here make sense. For part management the following (additional) entries Depending on your use case different entries here make sense. For part management the following (additional) entries may make sense:
maybe make sense:
* Datasheets (restricted to pdfs, Allowed filetypes: `application/pdf`) * Datasheets (restricted to pdfs, Allowed filetypes: `application/pdf`)
* Pictures (for generic pictures of components, storage locations, etc., Allowed filetypes: `image/*` * Pictures (for generic pictures of components, storage locations, etc., Allowed filetypes: `image/*`
@ -111,34 +110,34 @@ maybe make sense:
For every attachment type a list of allowed file types, which can be uploaded to an attachment with this attachment For every attachment type a list of allowed file types, which can be uploaded to an attachment with this attachment
type, can be defined. You can either pass a list of allowed file extensions (e.g. `.pdf, .zip, .docx`) and/or a list type, can be defined. You can either pass a list of allowed file extensions (e.g. `.pdf, .zip, .docx`) and/or a list
of [Mime Types](https://en.wikipedia.org/wiki/Media_type) (e.g. `application/pdf, image/jpeg`) or a combination of both of [Mime Types](https://en.wikipedia.org/wiki/Media_type) (e.g. `application/pdf, image/jpeg`) or a combination of both
here. To allow all browser supported images, you can use `image/*` wildcard here. here. To allow all browser-supported images, you can use `image/*` wildcard here.
## (Optional) Create Currencies ## (Optional) Create Currencies
If you want to save price information for parts in a currency different to your global currency (by default Euro), you If you want to save price information for parts in a currency different from your global currency (by default Euro), you
have to define the additional currencies you want to use under `Edit -> Currencies`: have to define the additional currencies you want to use under `Edit -> Currencies`:
![image]({% link assets/getting_started/currencies_admin.png %}) ![image]({% link assets/getting_started/currencies_admin.png %})
You create a new currency, name it however you want (it is recommended to use the official name of the currency) and You create a new currency, name it however you want (it is recommended to use the official name of the currency),
select the currency ISO code from the list and save it. The currency symbol is determined automatically from chose ISO select the currency ISO code from the list, and save it. The currency symbol is determined automatically from the chosen ISO
code. code.
You can define an exchange rate in terms of your base currency (e.g. how many euros is one unit of your currency worth) You can define an exchange rate in terms of your base currency (e.g. how many euros is one unit of your currency worth)
to convert the currencies values in your preferred display currency automatically. to convert the currency values in your preferred display currency automatically.
## (Optional) Create Measurement Units ## (Optional) Create Measurement Units
By default, Part-DB assumes that the parts in inventory can be counted by individual indivisible pieces, like LEDs in a By default, Part-DB assumes that the parts in inventory can be counted by individual indivisible pieces, like LEDs in a
box or books in a shelf. box or books on a shelf.
However, if you want to manage things, that are divisible and the stock is described by a physical quantity, like However, if you want to manage things, that are divisible and the stock is described by a physical quantity, like
length for cables, or volumina of a liquid, you have to define additional measurement units. length for cables, or volumes of a liquid, you have to define additional measurement units.
This is possible under `Edit -> Measurement Units`: This is possible under `Edit -> Measurement Units`:
![image]({% link assets/getting_started/units_admin.png %}) ![image]({% link assets/getting_started/units_admin.png %})
You can give the measurement unit a name and an optional unit symbol (like `m` for meters) which is shown when You can give the measurement unit a name and an optional unit symbol (like `m` for meters) which is shown when
quantities in this unit are displayed. The option `Use SI prefix` is useful for almost all physical quantities, as big quantities in this unit are displayed. The option `Use SI prefix` is useful for almost all physical quantities, as big
and small numbers are automatically formatted with SI-prefixes (like 1.5kg instead 1500 grams). and small numbers are automatically formatted with SI prefixes (like 1.5kg instead 1500 grams).
The measurement unit can be selected for each part individually, by setting the option in the advanced tab of a part`s The measurement unit can be selected for each part individually, by setting the option in the advanced tab of a part`s
edit menu. edit menu.
@ -163,10 +162,10 @@ You can create/edit footprints in the tools sidebar under "Edit -> Footprints".
It is useful to create footprints for the most common packages, like SMD resistors, capacitors, etc. to make it easier It is useful to create footprints for the most common packages, like SMD resistors, capacitors, etc. to make it easier
to find parts with the same footprint. to find parts with the same footprint.
You should create these as a tree structure, so that you can group footprints by their type. You should create these as a tree structure so that you can group footprints by their type.
See [Concepts]({% link concepts.md %}) for an example tree structure. See [Concepts]({% link concepts.md %}) for an example tree structure.
You can define attachments here which are associated with the footprint. The attachment set as preview image, will be You can define attachments here which are associated with the footprint. The attachment set as the preview image, will be
used whenever a visual representation of the footprint is needed (e.g. in the part list). used whenever a visual representation of the footprint is needed (e.g. in the part list).
For many common footprints, you can use the built-in footprints, which can be found in the "Builtin footprint image For many common footprints, you can use the built-in footprints, which can be found in the "Builtin footprint image

View file

@ -34,13 +34,13 @@ find in the "Tools" sidebar panel.
> You will not be able to check the data before it is written to the database, so you should review the data before > You will not be able to check the data before it is written to the database, so you should review the data before
> using the import tool. > using the import tool.
You can upload the file which should be imported here and choose various options on how the data should be treated: You can upload the file that should be imported here and choose various options on how the data should be treated:
* **Format**: By default "auto" is selected here and Part-DB will try to detect the format of the file automatically * **Format**: By default "auto" is selected here and Part-DB will try to detect the format of the file automatically
based on its file extension. If you want to force a specific format or Part-DB can not auto-detect the format, you can based on its file extension. If you want to force a specific format or Part-DB can not auto-detect the format, you can
select it here. select it here.
* **CSV delimiter**: If you upload an CSV file, you can select the delimiter character which is used to separate the * **CSV delimiter**: If you upload a CSV file, you can select the delimiter character which is used to separate the
columns in the CSV file. Depending on the CSV file, this might be a comma (`,`), semicolon (`;`). columns in the CSV file. Depending on the CSV file, this might be a comma (`,`) or semicolon (`;`).
* **Category override**: You can select (or create) a category here, to which all imported parts should be assigned, no * **Category override**: You can select (or create) a category here, to which all imported parts should be assigned, no
matter what was specified in the import file. This can be useful if you want to assign all imports to a certain matter what was specified in the import file. This can be useful if you want to assign all imports to a certain
category or if no category is specified in the data. If you leave this field empty, the category will be determined by category or if no category is specified in the data. If you leave this field empty, the category will be determined by
@ -59,7 +59,7 @@ You can upload the file which should be imported here and choose various options
is not selected, the import will continue for the other parts and only the invalid parts will be skipped. is not selected, the import will continue for the other parts and only the invalid parts will be skipped.
After you have selected the options, you can start the import by clicking the "Import" button. When the import is After you have selected the options, you can start the import by clicking the "Import" button. When the import is
finished, you will see the results of the import in the lower half of the page. You find a table with the imported finished, you will see the results of the import in the lower half of the page. You can find a table with the imported
parts (including links to them) there. parts (including links to them) there.
#### Fields description #### Fields description
@ -83,14 +83,14 @@ leave them empty or do not include the column in your file.
* **`manufacturing_status`**: The manufacturing status of the part, must be one of the following * **`manufacturing_status`**: The manufacturing status of the part, must be one of the following
values: `announced`, `active`, `nrfnd`, `eol`, `discontinued` or left empty. values: `announced`, `active`, `nrfnd`, `eol`, `discontinued` or left empty.
* **`needs_review`** or **`needs_review`**: If this is set to `1`, the part will be marked as "needs review". * **`needs_review`** or **`needs_review`**: If this is set to `1`, the part will be marked as "needs review".
* **`tags`**: A comma separated list of tags for the part. * **`tags`**: A comma-separated list of tags for the part.
* **`mass`**: The mass of the part in grams. * **`mass`**: The mass of the part in grams.
* **`ipn`**: The IPN (Item Part Number) of the part. * **`ipn`**: The IPN (Item Part Number) of the part.
* **`minamount`**: The minimum amount of the part which should be in stock. * **`minamount`**: The minimum amount of the part which should be in stock.
* **`partUnit`**: The measurement unit of the part to use. Can be a path similar to the category field. * **`partUnit`**: The measurement unit of the part to use. Can be a path similar to the category field.
With the following fields you can specify storage locations and amount / quantity in stock of the part. An PartLot will With the following fields, you can specify storage locations and amount/quantity in stock of the part. A PartLot will
be created automatically from the data and assigned to the part. The following fields are helpers for an easy import for be created automatically from the data and assigned to the part. The following fields are helpers for an easy import of
parts at one storage location. If you need to create a Part with multiple PartLots you have to use JSON format (or CSV) parts at one storage location. If you need to create a Part with multiple PartLots you have to use JSON format (or CSV)
with nested objects: with nested objects:
@ -99,7 +99,7 @@ field.
**`amount`**, **`quantity`** or **`instock`**: The amount of the part in stock. If this value is not set, the part lot **`amount`**, **`quantity`** or **`instock`**: The amount of the part in stock. If this value is not set, the part lot
will be marked with "unknown amount" will be marked with "unknown amount"
The following fields can be used to specify the supplier/distributor, supplier product number and the price of the part. The following fields can be used to specify the supplier/distributor, supplier product number, and the price of the part.
This is only possible for a single supplier/distributor and price with these fields. If you need to specify multiple This is only possible for a single supplier/distributor and price with these fields. If you need to specify multiple
suppliers/distributors or prices, you have to use JSON format (or CSV) with nested objects. suppliers/distributors or prices, you have to use JSON format (or CSV) with nested objects.
**Please note that the supplier fields is required, if you want to import prices or supplier product numbers**. If the **Please note that the supplier fields is required, if you want to import prices or supplier product numbers**. If the
@ -125,23 +125,23 @@ give the user any additional information.
You can export data structures (like categories, manufacturers, etc.) in the respective edit page (e.g. Tools Panel -> You can export data structures (like categories, manufacturers, etc.) in the respective edit page (e.g. Tools Panel ->
Edit -> Category). Edit -> Category).
If you select a certain datastructure from your list, you can export it (and optionally all sub-datastructures) in the " If you select a certain data structure from your list, you can export it (and optionally all sub data structures) in the "
Export" tab. Export" tab.
If you want to export all data structures of a certain type (e.g. all categories in your database), you can select the " If you want to export all data structures of a certain type (e.g. all categories in your database), you can select the "
Export all" function in the "Import / Export" tab of the "new element" page. Export all" function in the "Import / Export" tab of the "new element" page.
You can select between the following export formats: You can select between the following export formats:
* **CSV** (Comma Separated Values): A semicolon separated list of values, where every line represents an element. This * **CSV** (Comma Separated Values): A semicolon-separated list of values, where every line represents an element. This
format can be imported into Excel or LibreOffice Calc and is easy to work with. However, it does not support nested format can be imported into Excel or LibreOffice Calc and is easy to work with. However, it does not support nested
data structures or sub data (like parameters, attachments, etc.), very well (many columns are generated, as every data structures or sub data (like parameters, attachments, etc.), very well (many columns are generated, as every
possible sub data is exported as a separate column). possible sub-data is exported as a separate column).
* **JSON** (JavaScript Object Notation): A text-based format, which is easy to work with programming languages. It * **JSON** (JavaScript Object Notation): A text-based format, which is easy to work with programming languages. It
supports nested datastructures and sub data (like parameters, attachments, etc.) very well. However, it is not easy to supports nested data structures and sub-data (like parameters, attachments, etc.) very well. However, it is not easy to
work with in Excel or LibreOffice Calc and you maybe need to write some code to work with the exported data work with in Excel or LibreOffice Calc and you may need to write some code to work with the exported data
efficiently. efficiently.
* **YAML** (Yet another Markup Language): Very similar to JSON * **YAML** (Yet Another Markup Language): Very similar to JSON
* **XML** (Extensible Markup Language): Good support with nested datastructures. Similar use case as JSON and YAML. * **XML** (Extensible Markup Language): Good support with nested data structures. Similar use cases as JSON and YAML.
Also, you can select between the following export levels: Also, you can select between the following export levels:
@ -149,7 +149,7 @@ Also, you can select between the following export levels:
* **Extended**: This will export all commonly used information about this data structure (like notes, options, etc.) * **Extended**: This will export all commonly used information about this data structure (like notes, options, etc.)
* **Full**: This will export all available information about this data structure (like all parameters, attachments) * **Full**: This will export all available information about this data structure (like all parameters, attachments)
Please note that the level will also be applied to all sub data or children elements. So if you select "Full" for a Please note that the level will also be applied to all sub-data or children elements. So if you select "Full" for a
part, all the associated categories, manufacturers, footprints, etc. will also be exported with all available part, all the associated categories, manufacturers, footprints, etc. will also be exported with all available
information, this can lead to very large export files. information, this can lead to very large export files.

View file

@ -6,11 +6,11 @@ parent: Usage
# Information provider system # Information provider system
Part-DB can create parts based on information from external sources: For example with the right setup you can just Part-DB can create parts based on information from external sources: For example, with the right setup you can just
search for a part number search for a part number
and Part-DB will query selected distributors and manufacturers for the part and create a part with the information it and Part-DB will query selected distributors and manufacturers for the part and create a part with the information it
found. found.
This way your Part-DB parts automatically get datasheet links, prices, parameters and more, with just a few clicks. This way your Part-DB parts automatically get datasheet links, prices, parameters, and more, with just a few clicks.
## Usage ## Usage
@ -37,17 +37,21 @@ filled in.
![image]({% link assets/usage/information_provider_system/animation.gif %}) ![image]({% link assets/usage/information_provider_system/animation.gif %})
If you want to update an existing part, go to the parts info page and click on the "Update from info provider" button in
the tools tab. You will be redirected to a search page, where you can search the info providers to automatically update this
part.
## Alternative names ## Alternative names
Part-DB tries to automatically find existing elements from your database for the information it got from the providers Part-DB tries to automatically find existing elements from your database for the information it got from the providers
for fields like manufacturer, footprint, etc. for fields like manufacturer, footprint, etc.
For this it searches for an element with the same name (case-insensitive) as the information it got from the provider. So For this, it searches for an element with the same name (case-insensitive) as the information it got from the provider. So
e.g. if the provider returns "EXAMPLE CORP" as manufacturer, e.g. if the provider returns "EXAMPLE CORP" as the manufacturer,
Part-DB will automatically select the element with the name "Example Corp" from your database. Part-DB will automatically select the element with the name "Example Corp" from your database.
As the names of these fields differ from provider to provider (and maybe not even normalized for the same provider), you As the names of these fields differ from provider to provider (and maybe not even normalized for the same provider), you
can define multiple alternative names for an element (on their editing page). can define multiple alternative names for an element (on their editing page).
For example if define a manufacturer "Example Corp" with the alternative names "Example Corp.", "Example Corp", "Example For example, if you define a manufacturer "Example Corp" with the alternative names "Example Corp.", "Example Corp", "Example
Corp. Inc." and "Example Corporation", Corp. Inc." and "Example Corporation",
then the provider can return any of these names and Part-DB will still automatically select the right element. then the provider can return any of these names and Part-DB will still automatically select the right element.
@ -68,12 +72,12 @@ add the alternative names "Datasheet" and "Image" to the alternative names field
The system tries to be as flexible as possible, so many different information sources can be used. The system tries to be as flexible as possible, so many different information sources can be used.
Each information source is called am "info provider" and handles the communication with the external source. Each information source is called am "info provider" and handles the communication with the external source.
The providers are just a driver which handles the communication with the different external sources and converts them The providers are just a driver that handles the communication with the different external sources and converts them
into a common format Part-DB understands. into a common format Part-DB understands.
That way it is pretty easy to create new providers as they just need to do very little work. That way it is pretty easy to create new providers as they just need to do very little work.
Normally the providers utilize an API of a service, and you need to create an account at the provider and get an API key. Normally the providers utilize an API of a service, and you need to create an account at the provider and get an API key.
Also, there are limits on how many requests you can do per day or months, depending on the provider and your contract Also, there are limits on how many requests you can do per day or month, depending on the provider and your contract
with them. with them.
The following providers are currently available and shipped with Part-DB: The following providers are currently available and shipped with Part-DB:
@ -82,8 +86,7 @@ The following providers are currently available and shipped with Part-DB:
### Octopart ### Octopart
The Octopart provider uses the [Octopart / Nexar API](https://nexar.com/api) to search for parts and getting The Octopart provider uses the [Octopart / Nexar API](https://nexar.com/api) to search for parts and get information.
information.
To use it you have to create an account at Nexar and create a new application on To use it you have to create an account at Nexar and create a new application on
the [Nexar Portal](https://portal.nexar.com/). the [Nexar Portal](https://portal.nexar.com/).
The name does not matter, but it is important that the application has access to the "Supply" scope. The name does not matter, but it is important that the application has access to the "Supply" scope.
@ -96,7 +99,7 @@ can see your current usage on the Nexar portal.
Part-DB caches the search results internally, so if you have searched for a part before, it will not count against your Part-DB caches the search results internally, so if you have searched for a part before, it will not count against your
monthly limit again, when you create it from the search results. monthly limit again, when you create it from the search results.
Following env configuration options are available: The following env configuration options are available:
* `PROVIDER_OCTOPART_CLIENT_ID`: The client ID you got from Nexar (mandatory) * `PROVIDER_OCTOPART_CLIENT_ID`: The client ID you got from Nexar (mandatory)
* `PROVIDER_OCTOPART_SECRET`: The client secret you got from Nexar (mandatory) * `PROVIDER_OCTOPART_SECRET`: The client secret you got from Nexar (mandatory)
@ -104,19 +107,19 @@ Following env configuration options are available:
default: `EUR`). If an offer is only available in a certain currency, default: `EUR`). If an offer is only available in a certain currency,
Part-DB will save the prices in their native currency, and you can use Part-DB currency conversion feature to convert Part-DB will save the prices in their native currency, and you can use Part-DB currency conversion feature to convert
it to your preferred currency. it to your preferred currency.
* `PROVIDER_OCOTPART_COUNTRY`: The country you want to get prices in if available (optional, 2 letter ISO-code, * `PROVIDER_OCTOPART_COUNTRY`: The country you want to get prices in if available (optional, 2 letter ISO-code,
default: `DE`). To get correct prices, you have to set this and the currency setting to the correct value. default: `DE`). To get the correct prices, you have to set this and the currency setting to the correct value.
* `PROVIDER_OCTOPART_SEARCH_LIMIT`: The maximum number of results to return per search (optional, default: `10`). This * `PROVIDER_OCTOPART_SEARCH_LIMIT`: The maximum number of results to return per search (optional, default: `10`). This
affects how quickly your monthly limit is used up. affects how quickly your monthly limit is used up.
* `PROVIDER_OCTOPART_ONLY_AUTHORIZED_SELLERS`: If set to `true`, only offers * `PROVIDER_OCTOPART_ONLY_AUTHORIZED_SELLERS`: If set to `true`, only offers
from [authorized sellers](https://octopart.com/authorized) will be returned (optional, default: `false`). from [authorized sellers](https://octopart.com/authorized) will be returned (optional, default: `false`).
**Attention**: If you change the octopart clientID after you have already used the provider, you have to remove the **Attention**: If you change the Octopart clientID after you have already used the provider, you have to remove the
OAuth token in the Part-DB database. Remove the entry in the table `oauth_tokens` with the name `ip_octopart_oauth`. OAuth token in the Part-DB database. Remove the entry in the table `oauth_tokens` with the name `ip_octopart_oauth`.
### Digi-Key ### Digi-Key
The Digi-Key provider uses the [Digi-Key API](https://developer.digikey.com/) to search for parts and getting shopping The Digi-Key provider uses the [Digi-Key API](https://developer.digikey.com/) to search for parts and get shopping
information from [Digi-Key](https://www.digikey.com/). information from [Digi-Key](https://www.digikey.com/).
To use it you have to create an account at Digi-Key and get an API key on To use it you have to create an account at Digi-Key and get an API key on
the [Digi-Key API page](https://developer.digikey.com/). the [Digi-Key API page](https://developer.digikey.com/).
@ -124,7 +127,7 @@ You must create an organization there and create a "Production app". Most settin
grant access to the "Product Information" API. grant access to the "Product Information" API.
You will get a Client ID and a Client Secret, which you have to put in the Part-DB env configuration (see below). You will get a Client ID and a Client Secret, which you have to put in the Part-DB env configuration (see below).
Following env configuration options are available: The following env configuration options are available:
* `PROVIDER_DIGIKEY_CLIENT_ID`: The client ID you got from Digi-Key (mandatory) * `PROVIDER_DIGIKEY_CLIENT_ID`: The client ID you got from Digi-Key (mandatory)
* `PROVIDER_DIGIKEY_SECRET`: The client secret you got from Digi-Key (mandatory) * `PROVIDER_DIGIKEY_SECRET`: The client secret you got from Digi-Key (mandatory)
@ -134,7 +137,7 @@ Following env configuration options are available:
The Digi-Key provider needs an additional OAuth connection. To do this, go to the information provider The Digi-Key provider needs an additional OAuth connection. To do this, go to the information provider
list (`https://your-partdb-instance.tld/tools/info_providers/providers`), list (`https://your-partdb-instance.tld/tools/info_providers/providers`),
go the Digi-Key provider (in the disabled page) and click on the "Connect OAuth" button. You will be redirected to go to Digi-Key provider (in the disabled page), and click on the "Connect OAuth" button. You will be redirected to
Digi-Key, where you have to log in and grant access to the app. Digi-Key, where you have to log in and grant access to the app.
To do this your user needs the "Manage OAuth tokens" permission from the "System" section in the "System" tab. To do this your user needs the "Manage OAuth tokens" permission from the "System" section in the "System" tab.
The OAuth connection should only be needed once, but if you have any problems with the provider, just click the button The OAuth connection should only be needed once, but if you have any problems with the provider, just click the button
@ -142,13 +145,13 @@ again, to establish a new connection.
### TME ### TME
The TME provider use the API of [TME](https://www.tme.eu/) to search for parts and getting shopping information from The TME provider uses the API of [TME](https://www.tme.eu/) to search for parts and getting shopping information from
them. them.
To use it you have to create an account at TME and get an API key on the [TME API page](https://developers.tme.eu/en/). To use it you have to create an account at TME and get an API key on the [TME API page](https://developers.tme.eu/en/).
You have to generate a new anonymous key there and enter the key and secret in the Part-DB env configuration (see You have to generate a new anonymous key there and enter the key and secret in the Part-DB env configuration (see
below). below).
Following env configuration options are available: The following env configuration options are available:
* `PROVIDER_TME_KEY`: The API key you got from TME (mandatory) * `PROVIDER_TME_KEY`: The API key you got from TME (mandatory)
* `PROVIDER_TME_SECRET`: The API secret you got from TME (mandatory) * `PROVIDER_TME_SECRET`: The API secret you got from TME (mandatory)
@ -167,7 +170,7 @@ You have to create an account at Farnell and get an API key on the [Farnell API
Register a new application there (settings does not matter, as long as you select the "Product Search API") and you will Register a new application there (settings does not matter, as long as you select the "Product Search API") and you will
get an API key. get an API key.
Following env configuration options are available: The following env configuration options are available:
* `PROVIDER_ELEMENT14_KEY`: The API key you got from Farnell (mandatory) * `PROVIDER_ELEMENT14_KEY`: The API key you got from Farnell (mandatory)
* `PROVIDER_ELEMENT14_STORE_ID`: The store ID you want to use. This decides the language of results, currency and * `PROVIDER_ELEMENT14_STORE_ID`: The store ID you want to use. This decides the language of results, currency and
@ -181,7 +184,11 @@ information from [Mouser](https://www.mouser.com/).
You have to create an account at Mouser and register for an API key for the Search API on You have to create an account at Mouser and register for an API key for the Search API on
the [Mouser API page](https://www.mouser.de/api-home/). the [Mouser API page](https://www.mouser.de/api-home/).
You will receive an API token, which you have to put in the Part-DB env configuration (see below): You will receive an API token, which you have to put in the Part-DB env configuration (see below):
At the registration you choose a country, language and currency in which you want to get the results. At the registration you choose a country, language, and currency in which you want to get the results.
*Attention*: Currently (January 2024) the mouser API seems to be somewhat broken, in the way that it does not return any
information about datasheets and part specifications. Therefore Part-DB can not retrieve them, even if they are shown
at the mouser page. See [issue #503](https://github.com/Part-DB/Part-DB-server/issues/503) for more info.
Following env configuration options are available: Following env configuration options are available:
@ -192,6 +199,59 @@ Following env configuration options are available:
* `PROVIDER_MOUSER_SEARCH_WITH_SIGNUP_LANGUAGE`: A bit of an obscure option. The original description of Mouser is: Used * `PROVIDER_MOUSER_SEARCH_WITH_SIGNUP_LANGUAGE`: A bit of an obscure option. The original description of Mouser is: Used
when searching for keywords in the language specified when you signed up for Search API. when searching for keywords in the language specified when you signed up for Search API.
### LCSC
[LCSC](https://www.lcsc.com/) is a Chinese distributor of electronic parts. It does not offer a public API, but the LCSC
webshop uses an internal JSON based API to render the page. Part-DB can use this inofficial API to get part information
from LCSC.
**Please note, that the use of this internal API is not intended or endorsed by LCS and it could break at any time. So use it at your own risk.**
An API key is not required, it is enough to enable the provider using the following env configuration options:
* `PROVIDER_LCSC_ENABLED`: Set this to `1` to enable the LCSC provider
* `PROVIDER_LCSC_CURRENCY`: The currency you want to get prices in (see LCSC webshop for available currencies, default: `EUR`)
### OEMsecrets
The oemsecrets provider uses the [oemsecrets API](https://www.oemsecrets.com/) to search for parts and getting shopping
information from them. Similar to octopart it aggregates offers from different distributors.
You can apply for a free API key on the [oemsecrets API page](https://www.oemsecrets.com/api/) and put the key you get
in the Part-DB env configuration (see below).
The following env configuration options are available:
* `PROVIDER_OEMSECRETS_KEY`: The API key you got from oemsecrets (mandatory)
* `PROVIDER_OEMSECRETS_COUNTRY_CODE`: The two-letter code of the country you want to get the prices for
* `PROVIDER_OEMSECRETS_CURRENCY`: The currency you want to get prices in (optional, default: `EUR`)
* `PROVIDER_OEMSECRETS_ZERO_PRICE`: If set to `1`, parts with a price of 0 will be included in the search results, otherwise
they will be excluded (optional, default: `0`)
* `PROVIDER_OEMSECRETS_SET_PARAM`: If set to `1`, the provider will try to extract parameters from the part description
* `PROVIDER_OEMSECRETS_SORT_CRITERIA`: The criteria to sort the search results by. If set to 'C', it further sorts by
completeness (prioritizing items with the most detailed information). If set to 'M', it further sorts by manufacturer name.
If set to any other value, no sorting is performed.
### Reichelt
The reichelt provider uses webscraping from [reichelt.com](https://reichelt.com/) to get part information.
This is not an official API and could break at any time. So use it at your own risk.
The following env configuration options are available:
* `PROVIDER_REICHELT_ENABLED`: Set this to `1` to enable the Reichelt provider
* `PROVIDER_REICHELT_CURRENCY`: The currency you want to get prices in. Only possible for countries which use Non-EUR (optional, default: `EUR`)
* `PROVIDER_REICHELT_COUNTRY`: The country you want to get the prices for (optional, default: `DE`)
* `PROVIDER_REICHELT_LANGUAGE`: The language you want to get the descriptions in (optional, default: `en`)
* `PROVIDER_REICHELT_INCLUDE_VAT`: If set to `1`, the prices will be gross prices (including tax), otherwise net prices (optional, default: `1`)
### Pollin
The pollin provider uses webscraping from [pollin.de](https://www.pollin.de/) to get part information.
This is not an official API and could break at any time. So use it at your own risk.
The following env configuration options are available:
* `PROVIDER_POLLIN_ENABLED`: Set this to `1` to enable the Pollin provider
### Custom provider ### Custom provider
To create a custom provider, you have to create a new class implementing the `InfoProviderInterface` interface. As long To create a custom provider, you have to create a new class implementing the `InfoProviderInterface` interface. As long

View file

@ -93,7 +93,7 @@ all text and search fields in Part-DB.
### Currency symbols ### Currency symbols
Please not the following keybindings are bound to a specific keycode. The key character is not the same on all Please note, the following keybindings are bound to a specific keycode. The key character is not the same on all
keyboards. keyboards.
It is given here for a US keyboard layout. It is given here for a US keyboard layout.
@ -108,7 +108,7 @@ For a German keyboard layout, replace ; with ö, and ' with ä.
### Others ### Others
Please not the following keybindings are bound to a specific keycode. The key character is not the same on all Please note the following keybindings are bound to a specific keycode. The key character is not the same on all
keyboards. keyboards.
It is given here for a US keyboard layout. It is given here for a US keyboard layout.
@ -117,6 +117,6 @@ For a German keyboard layout, replace `[` with `0`, and `]` with `´`.
| Key | Character | | Key | Character |
|--------------------------------|--------------------| |--------------------------------|--------------------|
| **Alt + [** (code 219) | © (Copyright char) | | **Alt + [** (code 219) | © (Copyright char) |
| **Alt + Shift + [** (code 219) | (Registered char) | | **Alt + Shift + [** (code 219) | ® (Registered char) |
| **Alt + ]** (code 221) | ™ (Trademark char) | | **Alt + ]** (code 221) | ™ (Trademark char) |
| **Alt + Shift + ]** (code 221) | (Degree char) | | **Alt + Shift + ]** (code 221) | ° (Degree char) |

View file

@ -7,12 +7,12 @@ parent: Usage
# Labels # Labels
Part-DB support the generation and printing of labels for parts, part lots and storage locations. Part-DB support the generation and printing of labels for parts, part lots and storage locations.
You can use the "Tools -> Label generator" menu entry to create labels, or click the label generation link on the part. You can use the "Tools -> Label generator" menu entry to create labels or click the label generation link on the part.
You can define label templates by creating Label profiles. This way you can create many similar looking labels with for You can define label templates by creating Label profiles. This way you can create many similar-looking labels with for
many parts. many parts.
The content of the labels is defined by the templates content field. You can use the WYSIWYG editor to create and style The content of the labels is defined by the template's content field. You can use the WYSIWYG editor to create and style
the content (or write HTML code). the content (or write HTML code).
Using the "Label placeholder" menu in the editor, you can insert placeholders for the data of the parts. Using the "Label placeholder" menu in the editor, you can insert placeholders for the data of the parts.
It will be replaced by the concrete data when the label is generated. It will be replaced by the concrete data when the label is generated.
@ -20,7 +20,7 @@ It will be replaced by the concrete data when the label is generated.
## Label placeholders ## Label placeholders
A placeholder has the format `[[PLACEHOLDER]]` and will be filled with the concrete data by Part-DB. A placeholder has the format `[[PLACEHOLDER]]` and will be filled with the concrete data by Part-DB.
You can use the "Placeholders" dropdown in content editor, to automatically insert the placeholders. You can use the "Placeholders" dropdown in the content editor, to automatically insert the placeholders.
### Common ### Common
@ -89,15 +89,169 @@ If you select "Twig" in parser mode under advanced settings, you can input a twi
source mode). You can use most of the twig tags and filters listed source mode). You can use most of the twig tags and filters listed
in [official documentation](https://twig.symfony.com/doc/3.x/). in [official documentation](https://twig.symfony.com/doc/3.x/).
The following variables are in injected into Twig and can be accessed using `{% raw %}{{ variable }}` ( Twig allows you for much more complex and dynamic label generation. You can use loops, conditions, and functions to create
the label content and you can access almost all data Part-DB offers. The label templates are evaluated in a special sandboxed environment,
where only certain operations are allowed. Only read access to entities is allowed. However as it circumvents Part-DB normal permission system,
the twig mode is only available to users with the "Twig mode" permission.
The following variables are in injected into Twig and can be accessed using `{% raw %}{{ variable }}{% endraw %}` (
or `{% raw %}{{ variable.property }}{% endraw %}`): or `{% raw %}{{ variable.property }}{% endraw %}`):
| Variable name | Description | | Variable name | Description |
|--------------------------------------------|-------------------------------------------------------------------------------------| |--------------------------------------------|--------------------------------------------------------------------------------------|
| `{% raw %}{{ element }}{% endraw %}` | The target element, selected in label dialog | | `{% raw %}{{ element }}{% endraw %}` | The target element, selected in label dialog. |
| `{% raw %}{{ user }}{% endraw %}` | The current logged in user. Null if you are not logged in | | `{% raw %}{{ user }}{% endraw %}` | The current logged in user. Null if you are not logged in |
| `{% raw %}{{ install_title }}{% endraw %}` | The name of the current Part-DB instance (similar to [[INSTALL_NAME]] placeholder). | | `{% raw %}{{ install_title }}{% endraw %}` | The name of the current Part-DB instance (similar to [[INSTALL_NAME]] placeholder). |
| `{% raw %}{{ page }}{% endraw %}` | The page number (the nth-element for which the label is generated | | `{% raw %}{{ page }}{% endraw %}` | The page number (the nth-element for which the label is generated |
| `{% raw %}{{ last_page }}{% endraw %}` | The page number of the last element. Equals the number of all pages / element labels |
| `{% raw %}{{ paper_width }}{% endraw %}` | The width of the label paper in mm |
| `{% raw %}{{ paper_height }}{% endraw %}` | The height of the label paper in mm |
### Use the placeholders in twig mode
You can use the placeholders described above in the twig mode on `element` using the `{% raw %}{{ placeholder('PLACEHOLDER', element) }}{% endraw %}`
function or the ``{{ "[[PLACEHOLDER]]"|placeholders(element) }}`` filter:
```twig
{% raw %}
{# The function can be used to get the a single placeholder value of an element, if the placeholder does not exist, null is returned #}
{{ placeholder('[[NAME]]', element) }}
{# The filter can be used to replace all placeholders in a string with the values of the element #}
{{ "[[NAME]]: [[DESCRIPTION]]"|placeholders(element) }}
{# Using the apply environment every placeholder in the apply block will be replaced automatically #}
{% apply placeholders(element) %}
[[NAME]]: [[DESCRIPTION]]
{% endapply %}
{# If the block contains HTML use placeholders(element)|raw to prevent escaping of the HTML #}
{% apply placeholders(element)|raw %}
<b>[[NAME]]</b>: [[DESCRIPTION]]
{% endapply %}
{% endraw %}
```
### Important entity fields in twig mode
In twig mode you have access to many fields of the entity you are generating the label for and their associated entities.
Following are some important fields of the entities listed. See the [SandboxedTwigFactory service](https://github.com/Part-DB/Part-DB-server/blob/master/src/Services/LabelSystem/SandboxedTwigFactory.php) for the full list of allowed class methods.
Please not that the field names might change in the future.
#### Part
| Field name | Description |
|---------------------|-----------------------------------------------------------------------------------------------|
| `id` | The internal ID of the part |
| `name` | The name of the part |
| `category` | The category of the part |
| `manufacturer` | The manufacturer of the part |
| `footprint` | The footprint of the part |
| `mass` | The mass of the part |
| `ManufacturerProductNumber` | The manufacturer product number of the part |
| `tags` | The tags of the part |
| `description` | The rich text (markdown) description of the part |
| `comment` | The rich text (markdown) comment of the part |
| `lastModified` | The datetime object when the part was last modified |
| `creationDate` | The datetime object when the part was created |
| `ipn` | The internal part number of the part |
| `partUnit` | The unit of the part |
| `amountSum` | The sum of the amount of all part lots of this part |
| `amountUnknwon` | Bool: True if there is at least one part lot with unknown amount |
| `partLots` | The part lots of the part |
| `parameters` | The parameters of the part |
| `orderdetails` | The order details of the part as array of Orderdetails |
#### Part lot
| Field name | Description |
|---------------------|-----------------------------------------------------------------------------------------------|
| `id` | The internal ID of the part lot |
| `name` | The name of the part lot |
| `comment` | The rich text (markdown) comment of the part lot |
| `expirationDate` | The expiration date of the part lot (as Datetime object) |
| `amount` | The amount of parts in this lot |
| `storageLocation` | The storage location of this part lot |
| `part` | The part of this part lot |
| `needsRefill` | Bool: True if the part lot needs a refill |
| `expired` | Bool: True if the part lot is expired |
| `vendorBarcode` | The vendor barcode field of the lot |
#### Structural entities like categories, manufacturers, footprints, and storage locations
| Field name | Description |
|---------------------|-----------------------------------------------------------------------------------------------|
| `id` | The internal ID of the entity |
| `name` | The name of the entity |
| `comment` | The rich text (markdown) comment of the entity |
| `parent` | The parent entity of the entity |
| `children` | The children entities of the entity |
| `lastModified` | The datetime object when the entity was last modified |
| `creationDate` | The datetime object when the entity was created |
| `level` | The level of the entity in the hierarchy |
| `fullPath` | The full path of the entity (you can pass the delimiter as parameter) |
| `pathArray` | The path of the entity as array of strings |
#### Orderdetails
| Field name | Description |
|---------------------|-----------------------------------------------------------------------------------------------|
| `id` | The internal ID of the order detail |
| `part` | The part of the order detail |
| `supplier` | The supplier/distributor of the order detail |
| `obsolete` | Bool: True if the order detail is obsolete |
| `pricedetails` | The price details of the order detail as array of Pricedetails |
#### Pricedetails
| Field name | Description |
|---------------------|-----------------------------------------------------------------------------------------------|
| `id` | The internal ID of the price detail |
| `price` | The price of the price detail |
| `currency` | The currency of the price detail |
| `currencyIsoCode` | The ISO code of the used currency |
| `pricePerUnit` | The price per unit of the price detail |
| `priceRelatedQuantity` | The related quantity of the price detail |
| `minDiscountQuantity` | The minimum discount quantity of the price detail |
#### User
| Field name | Description |
|---------------------|-----------------------------------------------------------------------------------------------|
| `id` | The internal ID of the user |
| `username` | The username of the user |
| `email` | The email of the user |
| `fullName` | The full name of the user |
| `lastName` | The last name of the user |
| `firstName` | The first name of the user |
| `department` | The department of the user |
### Part-DB specific twig functions and filters
Part-DB offers some custom twig functions and filters, which can be used in the twig mode and ease the rendering of
certain data:
#### Functions
| Function name | Description |
|----------------------------------------------|-----------------------------------------------------------------------------------------------|
| `placeholder(placeholder, element)` | Get the value of a placeholder of an element |
| `entity_type(element)` | Get the type of an entity as string |
| `entity_url(element, type)` | Get the URL to a specific entity type page (e.g. `info`, `edit`, etc.) |
| `barcode_svg(content, type)` | Generate a barcode SVG from the content and type (e.g. `QRCODE`, `CODE128` etc.). A svg string is returned, which you need to data uri encode to inline it. |
### Filters
| Filter name | Description |
|----------------------------------------------|-----------------------------------------------------------------------------------------------|
| `format_bytes` | Format a byte count to a human readable string |
| `format_money(price, currency)` | Format a price to a human readable string with the currency |
| `format_amount(amount, unit)` | Format an amount to a human readable string with the unit object |
| `format_si(value, unit_str)` | Format a value using SI prefixes and the given unit string |
| `placeholders(element)` | Replace all placeholders in a string with the values of the element |
## Use custom fonts for PDF labels ## Use custom fonts for PDF labels
@ -124,12 +278,12 @@ the label generator settings:
The default used font (DejaVu) does not support all characters. Especially characters from non-latin languages like The default used font (DejaVu) does not support all characters. Especially characters from non-latin languages like
Chinese, Japanese, Korean, Arabic, Hebrew, Cyrillic, etc. are not supported. Chinese, Japanese, Korean, Arabic, Hebrew, Cyrillic, etc. are not supported.
For this we use [Unifont](http://unifoundry.com/unifont.html) as fallback font. This font supports all (or most) unicode For this, we use [Unifont](http://unifoundry.com/unifont.html) as fallback font. This font supports all (or most) Unicode
characters, but is not as beautiful as DejaVu. characters but is not as beautiful as DejaVu.
If you want to use a different (more beautiful) font, you can use the [custom fonts](#use-custom-fonts-for-pdf-labels) If you want to use a different (more beautiful) font, you can use the [custom fonts](#use-custom-fonts-for-pdf-labels)
feature. feature.
There is the [Noto](https://www.google.com/get/noto/) font family from Google, which supports a lot of languages and is There is the [Noto](https://www.google.com/get/noto/) font family from Google, which supports a lot of languages and is
available in different styles (regular, bold, italic, bold-italic). available in different styles (regular, bold, italic, bold-italic).
For example, you can use [Noto CJK](https://github.com/notofonts/noto-cjk) for more beautiful Chinese, Japanese For example, you can use [Noto CJK](https://github.com/notofonts/noto-cjk) for more beautiful Chinese, Japanese,
and Korean characters. and Korean characters.

View file

@ -10,9 +10,9 @@ Following you can find miscellaneous tips and tricks for using Part-DB.
## Create data structures directly from part edit page ## Create data structures directly from part edit page
Instead of first creating a category, manufacturer, footprint, etc. and then creating the part, you can create the Instead of first creating a category, manufacturer, footprint, etc., and then creating the part, you can create the
data structures directly from the part edit page: Just type the name of the data structure you want to create into the data structures directly from the part edit page: Just type the name of the data structure you want to create into the
select field on the part edit page and press "Create new ...". The new datastructure will be created, when you save select field on the part edit page and press "Create new ...". The new data structure will be created when you save
the part changes. the part changes.
You can create also create nested data structures this way. For example, if you want to create a new category "AVRs", You can create also create nested data structures this way. For example, if you want to create a new category "AVRs",
@ -20,23 +20,23 @@ as a subcategory of "MCUs", you can just type "MCUs->AVRs" into the category sel
The new category "AVRs" will be created as a subcategory of "MCUs". If the category "MCUs" does not exist, it will The new category "AVRs" will be created as a subcategory of "MCUs". If the category "MCUs" does not exist, it will
be created too. be created too.
## Builtin footprint images ## Built-in footprint images
Part-DB includes several builtin images for common footprints. You can use these images in your footprint Part-DB includes several built-in images for common footprints. You can use these images in your footprint
data structures, data structures,
by creating an attachment on the datastructure and selecting it as preview image. by creating an attachment on the data structure and selecting it as the preview image.
Type the name of the footprint image you want to use into the URL field of the attachment and select it from the Type the name of the footprint image you want to use into the URL field of the attachment and select it from the
dropdown menu. You can find a gallery of all builtin footprint images and their names in the "Builtin footprint image dropdown menu. You can find a gallery of all builtin footprint images and their names in the "Builtin footprint image
gallery", gallery",
which you can find in the "Tools" menu (you maybe need to give your user the permission to access this tool). which you can find in the "Tools" menu (you may need to give your user the permission to access this tool).
## Parametric search ## Parametric search
In the "parameters" tab of the filter panel on parts list page, you can define constraints, which parameter values In the "parameters" tab of the filter panel on parts list page, you can define constraints, and which parameter values
have to fulfill. This allows you to search for parts with specific parameters (or parameter ranges), for example you have to fulfill. This allows you to search for parts with specific parameters (or parameter ranges), for example, you
can search for all parts with a voltage rating of greater than 5 V. can search for all parts with a voltage rating of greater than 5 V.
## View own users permissions ## View own user's permissions
If you want to see which permissions your user has, you can find a list of the permissions in the "Permissions" panel If you want to see which permissions your user has, you can find a list of the permissions in the "Permissions" panel
on the user info page. on the user info page.
@ -49,10 +49,8 @@ part).
You can find a list of supported features in the [KaTeX documentation](https://katex.org/docs/supported.html). You can find a list of supported features in the [KaTeX documentation](https://katex.org/docs/supported.html).
To input a LaTeX equation, you have to wrap it in a pair of dollar signs (`$`). Single dollar signs mark inline To input a LaTeX equation, you have to wrap it in a pair of dollar signs (`$`). Single dollar signs mark inline
equations, equations, double dollar signs mark displayed equations (which will be their own line and centered).
double dollar signs mark displayed equations (which will be its own line and centered). For example, the following For example, the following equation will be rendered as an inline equation:
equation
will be rendered as an inline equation:
``` ```
$E=mc^2$ $E=mc^2$
@ -78,7 +76,7 @@ free API used by default only supports the Euro as base currency.
On almost any editing operation it is possible to add a comment describing, what or why you changed something. On almost any editing operation it is possible to add a comment describing, what or why you changed something.
This comment will be written to changelog and can be viewed later. This comment will be written to changelog and can be viewed later.
If you want to enforce your users to add comments to certain operations, you can do this by setting If you want to force your users to add comments to certain operations, you can do this by setting
the `ENFORCE_CHANGE_COMMENTS_FOR` option. the `ENFORCE_CHANGE_COMMENTS_FOR` option.
See the configuration reference for more information. See the configuration reference for more information.
@ -86,7 +84,7 @@ See the configuration reference for more information.
For maker spaces and universities with a lot of users, where each user can have his own stock, which only he should be For maker spaces and universities with a lot of users, where each user can have his own stock, which only he should be
able to access, you can assign able to access, you can assign
the user as "owner" of a part lot. This way, only him is allowed to add or remove parts from this lot. the user as "owner" of a part lot. This way, only he is allowed to add or remove parts from this lot.
## Update notifications ## Update notifications

View file

@ -235,4 +235,14 @@ EOD;
{ {
$this->warnIf(true, "Migration not needed for SQLite. Skipping..."); $this->warnIf(true, "Migration not needed for SQLite. Skipping...");
} }
public function postgreSQLUp(Schema $schema): void
{
$this->warnIf(true, "Migration not needed for Postgres. Skipping...");
}
public function postgreSQLDown(Schema $schema): void
{
$this->warnIf(true, "Migration not needed for Postgres. Skipping...");
}
} }

View file

@ -380,4 +380,14 @@ final class Version20190902140506 extends AbstractMultiPlatformMigration
{ {
$this->warnIf(true, "Migration not needed for SQLite. Skipping..."); $this->warnIf(true, "Migration not needed for SQLite. Skipping...");
} }
public function postgreSQLUp(Schema $schema): void
{
$this->warnIf(true, "Migration not needed for Postgres. Skipping...");
}
public function postgreSQLDown(Schema $schema): void
{
$this->warnIf(true, "Migration not needed for Postgres. Skipping...");
}
} }

View file

@ -88,4 +88,14 @@ final class Version20190913141126 extends AbstractMultiPlatformMigration
{ {
$this->warnIf(true, "Migration not needed for SQLite. Skipping..."); $this->warnIf(true, "Migration not needed for SQLite. Skipping...");
} }
public function postgreSQLUp(Schema $schema): void
{
$this->warnIf(true, "Migration not needed for Postgres. Skipping...");
}
public function postgreSQLDown(Schema $schema): void
{
$this->warnIf(true, "Migration not needed for Postgres. Skipping...");
}
} }

View file

@ -179,4 +179,14 @@ final class Version20190924113252 extends AbstractMultiPlatformMigration
{ {
$this->warnIf(true, "Migration not needed for SQLite. Skipping..."); $this->warnIf(true, "Migration not needed for SQLite. Skipping...");
} }
public function postgreSQLUp(Schema $schema): void
{
$this->warnIf(true, "Migration not needed for Postgres. Skipping...");
}
public function postgreSQLDown(Schema $schema): void
{
$this->warnIf(true, "Migration not needed for Postgres. Skipping...");
}
} }

View file

@ -65,4 +65,14 @@ final class Version20191214153125 extends AbstractMultiPlatformMigration
{ {
$this->warnIf(true, "Migration not needed for SQLite. Skipping..."); $this->warnIf(true, "Migration not needed for SQLite. Skipping...");
} }
public function postgreSQLUp(Schema $schema): void
{
$this->warnIf(true, "Migration not needed for Postgres. Skipping...");
}
public function postgreSQLDown(Schema $schema): void
{
$this->warnIf(true, "Migration not needed for Postgres. Skipping...");
}
} }

Some files were not shown because too many files have changed in this diff Show more