mirror of
https://github.com/Part-DB/Part-DB-server.git
synced 2026-02-21 17:22:28 +01:00
Compare commits
970 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
78bd858ebb | ||
|
|
19819454fa | ||
|
|
26a4b57cfb | ||
|
|
f3729ef9db | ||
|
|
ab09d319e9 | ||
|
|
df23ba07ba | ||
|
|
d20b668e87 | ||
|
|
f0646597fe | ||
|
|
6d783fd581 | ||
|
|
14fbf18733 | ||
|
|
e35c7c496f | ||
|
|
a218b8fdd6 | ||
|
|
1491672cf8 | ||
|
|
f9894ffff7 | ||
|
|
7b565817d6 | ||
|
|
a03b2ecf73 | ||
|
|
dd2f74e19e | ||
|
|
c1dcaf926a | ||
|
|
c116db9593 | ||
|
|
1b92b9f171 | ||
|
|
17e79207f0 | ||
|
|
4d187741e0 | ||
|
|
85c3031fcd | ||
|
|
a3e012d754 | ||
|
|
60f8e754c2 | ||
|
|
3e13a0d9d9 | ||
|
|
cd91dc8b5a | ||
|
|
bcaf96ed59 | ||
|
|
e2437d4c33 | ||
|
|
3798217abc | ||
|
|
57423436ce | ||
|
|
e824f6376a | ||
|
|
1f4bedc9b0 | ||
|
|
aa66285909 | ||
|
|
c6229568c5 | ||
|
|
6110f5be40 | ||
|
|
ea9cc6723f | ||
|
|
b5721dcfd0 | ||
|
|
d7383539ba | ||
|
|
11cdc282d2 | ||
|
|
b23f59271b | ||
|
|
999fe48a31 | ||
|
|
963079afbf | ||
|
|
a6d508205b | ||
|
|
fdf52a59fe | ||
|
|
dd0f8ec97c | ||
|
|
641b47b189 | ||
|
|
e1120dbfa7 | ||
|
|
f9d47e0865 | ||
|
|
d991643b0e | ||
|
|
8b8079a6f1 | ||
|
|
5faeb5dd56 | ||
|
|
5b3156ccf4 | ||
|
|
dc355773c9 | ||
|
|
1daf556206 | ||
|
|
1911c62edd | ||
|
|
2fe2740b62 | ||
|
|
4d7d624033 | ||
|
|
0abe3f0e61 | ||
|
|
77a6204798 | ||
|
|
64af418be2 | ||
|
|
15411d6c81 | ||
|
|
fd645a0bce | ||
|
|
f888028823 | ||
|
|
abc554c7b8 | ||
|
|
07cc8a9534 | ||
|
|
60ecbc7c32 | ||
|
|
b7af538cbf | ||
|
|
49c8b8003b | ||
|
|
65d04d4afb | ||
|
|
a449e82a22 | ||
|
|
34fd611946 | ||
|
|
62cbc168fb | ||
|
|
74d1904df1 | ||
|
|
7d69d6ba30 | ||
|
|
bc37d11f13 | ||
|
|
1825080d9e | ||
|
|
6926f6b233 | ||
|
|
459ae163da | ||
|
|
fc7b1e6d31 | ||
|
|
3198e5d750 | ||
|
|
f31cac580a | ||
|
|
753a12765b | ||
|
|
cbffc485f3 | ||
|
|
c15ddcdf9f | ||
|
|
264ed3aaab | ||
|
|
61a5ebde6b | ||
|
|
f4b4f14a67 | ||
|
|
9994dbd9db | ||
|
|
d976865e7a | ||
|
|
0445b87567 | ||
|
|
64c86fa11d | ||
|
|
548339911f | ||
|
|
e914a32894 | ||
|
|
f28e369c01 | ||
|
|
30b2c8b841 | ||
|
|
b5c7a789a2 | ||
|
|
168b4f6c15 | ||
|
|
bf5ed030fe | ||
|
|
b76b2740a7 | ||
|
|
d5f002ac20 | ||
|
|
2ec1a10623 | ||
|
|
ee69f9e576 | ||
|
|
b7af08503c | ||
|
|
08a1ce5f64 | ||
|
|
22f8448c65 | ||
|
|
6b0f0d31b9 | ||
|
|
feca20ef77 | ||
|
|
9e04a3405f | ||
|
|
46adb6d8b8 | ||
|
|
66e184c6b1 | ||
|
|
5b812104af | ||
|
|
0346b339c4 | ||
|
|
c6bff42cf7 | ||
|
|
03712fcf96 | ||
|
|
dbff543fa8 | ||
|
|
08bd4d54e3 | ||
|
|
eb30fb6e83 | ||
|
|
05e9b63f89 | ||
|
|
da0845c11c | ||
|
|
584062c29a | ||
|
|
752cfb3698 | ||
|
|
18db20e511 | ||
|
|
0f0adfcf36 | ||
|
|
7e99746b1e | ||
|
|
30afcc02b9 | ||
|
|
8ff2fef855 | ||
|
|
76295b73c8 | ||
|
|
8c00769757 | ||
|
|
773d0e9d20 | ||
|
|
d14f596479 | ||
|
|
700ed42ce5 | ||
|
|
dc2369c71e | ||
|
|
5fc760f6ad | ||
|
|
ffb5d3e790 | ||
|
|
512947e0d0 | ||
|
|
9e69a09a19 | ||
|
|
b447a69dae | ||
|
|
d52e6b5881 | ||
|
|
6cff19358a | ||
|
|
a6d476f953 | ||
|
|
aba73174ab | ||
|
|
83d43d931c | ||
|
|
64cebaba77 | ||
|
|
07535c26a6 | ||
|
|
aab1dcf8e6 | ||
|
|
4b88de9316 | ||
|
|
84c111ac7c | ||
|
|
2feeb1c868 | ||
|
|
17000da97e | ||
|
|
5b09cbf1ac | ||
|
|
07088c94e7 | ||
|
|
1da5e7ccd7 | ||
|
|
b9956e38b8 | ||
|
|
36879dd7da | ||
|
|
099ea63740 | ||
|
|
615defa84a | ||
|
|
3eeeb01ad1 | ||
|
|
73f6d79925 | ||
|
|
b0f5d9b55f | ||
|
|
50069c7611 | ||
|
|
c86694ab8f | ||
|
|
478d5e2a3a | ||
|
|
e7b766906d | ||
|
|
c5435df6f9 | ||
|
|
e8f4cd9fec | ||
|
|
378d695a24 | ||
|
|
a4b16f7f09 | ||
|
|
1fe3a614c9 | ||
|
|
773e393f55 | ||
|
|
87626589a3 | ||
|
|
01784a9d1f | ||
|
|
f99323f9b3 | ||
|
|
83ad99215f | ||
|
|
958d59a0ff | ||
|
|
de8a68c70d | ||
|
|
5f87d5b1ac | ||
|
|
c2ea880dad | ||
|
|
7eba4254e6 | ||
|
|
76bb3eae9d | ||
|
|
3da656c08b | ||
|
|
b6dc3eb1a2 | ||
|
|
fefa65941b | ||
|
|
74d75c6e1f | ||
|
|
01ed3eeecd | ||
|
|
9a3b9b84bc | ||
|
|
90a1ffa2ac | ||
|
|
5442aa5e07 | ||
|
|
0ab604d468 | ||
|
|
0b178b46f2 | ||
|
|
d12bde2b1e | ||
|
|
96a771e7ac | ||
|
|
3e6b80d1cf | ||
|
|
4d7d196a3c | ||
|
|
4e1f6277c6 | ||
|
|
626c4dd5d6 | ||
|
|
c8bd800b9f | ||
|
|
0fa03d8bb0 | ||
|
|
22606f01d2 | ||
|
|
3c2e535117 | ||
|
|
7f612bc371 | ||
|
|
cc2332a83a | ||
|
|
c7892cb9e2 | ||
|
|
5bd2d9b344 | ||
|
|
81f8b365e9 | ||
|
|
8ab9cf1417 | ||
|
|
b7cfdebad5 | ||
|
|
0447a7e6b3 | ||
|
|
6d67ee8106 | ||
|
|
2d7058329c | ||
|
|
9e58baa574 | ||
|
|
6d8cb9cc08 | ||
|
|
5cfccab671 | ||
|
|
3953e36921 | ||
|
|
7163df6d46 | ||
|
|
5f86253b94 | ||
|
|
93d0f97cfd | ||
|
|
9732b71f85 | ||
|
|
cf11320789 | ||
|
|
5e326bca12 | ||
|
|
3c52e57a44 | ||
|
|
2002b9d5d3 | ||
|
|
323c70393d | ||
|
|
eabd03dc53 | ||
|
|
3ac82cf76a | ||
|
|
1409d19922 | ||
|
|
bdcd51d533 | ||
|
|
563edb1731 | ||
|
|
cd7013f776 | ||
|
|
783a00ca2f | ||
|
|
e233940f1f | ||
|
|
717a9fb0a3 | ||
|
|
d0a5b4dcd7 | ||
|
|
294f7cf005 | ||
|
|
eb24aa2e68 | ||
|
|
a1c680d14d | ||
|
|
5144b75ed7 | ||
|
|
aeed7c0802 | ||
|
|
2b470e6cdd | ||
|
|
e6870c61ee | ||
|
|
f8ccd5bc22 | ||
|
|
7239aef47f | ||
|
|
91cab91c81 | ||
|
|
ce318bab9a | ||
|
|
b500fa82bb | ||
|
|
388d26fa05 | ||
|
|
9fd3012c27 | ||
|
|
3f36972764 | ||
|
|
9cd5d14708 | ||
|
|
cc82547699 | ||
|
|
a9be442dd1 | ||
|
|
ffbcf25246 | ||
|
|
e9665d7a7a | ||
|
|
0a06467f79 | ||
|
|
31510f6762 | ||
|
|
b298ee0003 | ||
|
|
97b539e1c6 | ||
|
|
6546fba218 | ||
|
|
b97132dbb5 | ||
|
|
aeeb4b87ec | ||
|
|
9a4877cdb0 | ||
|
|
919beda7f5 | ||
|
|
306ecff9c7 | ||
|
|
0c689d492b | ||
|
|
c3de0ccacc | ||
|
|
0d5bc2b29f | ||
|
|
d675f072d6 | ||
|
|
6f30db4877 | ||
|
|
cdcfcc7717 | ||
|
|
71765558fc | ||
|
|
5d3b1a7bcd | ||
|
|
a2a477e4e5 | ||
|
|
f32c0f52b6 | ||
|
|
47fc7db953 | ||
|
|
cc267c0edf | ||
|
|
f5a3ab1f9b | ||
|
|
f6c97b58aa | ||
|
|
7a2928e202 | ||
|
|
f53c98312e | ||
|
|
180505cba4 | ||
|
|
6d6a69e1dd | ||
|
|
5f61e096f9 | ||
|
|
1becde537b | ||
|
|
3c5a96ba5c | ||
|
|
470df57f58 | ||
|
|
185c88fa3e | ||
|
|
79262972aa | ||
|
|
1369091b90 | ||
|
|
b0322b4c03 | ||
|
|
c402ec40a5 | ||
|
|
1964084155 | ||
|
|
4b5f9648b1 | ||
|
|
9d9287cefb | ||
|
|
18ae32f15a | ||
|
|
7cd2662c77 | ||
|
|
4f0730b6f9 | ||
|
|
d7bc74fb2b | ||
|
|
a0b31cfd7e | ||
|
|
33033bc5b1 | ||
|
|
d6daac0762 | ||
|
|
6a5a632a0e | ||
|
|
c64633299a | ||
|
|
f4e173d3fb | ||
|
|
5ff8d1c1cb | ||
|
|
aad40aefbc | ||
|
|
ff77dac5fb | ||
|
|
ced53c2690 | ||
|
|
6f66d50ff6 | ||
|
|
06f88341ba | ||
|
|
2a9a86aaaf | ||
|
|
2409c7f62b | ||
|
|
1b276c5eae | ||
|
|
608bd247af | ||
|
|
e9cdd20dcc | ||
|
|
37dccd4249 | ||
|
|
485d162d82 | ||
|
|
aaf230fc58 | ||
|
|
f9cafae789 | ||
|
|
c758027d4c | ||
|
|
c178d45f73 | ||
|
|
8c9abce633 | ||
|
|
0753b7137f | ||
|
|
9d54001f89 | ||
|
|
00bb005e4e | ||
|
|
60b8650a1a | ||
|
|
ec4eccdf08 | ||
|
|
64c38042a0 | ||
|
|
e09f60e71f | ||
|
|
0e75d76720 | ||
|
|
852624ae7e | ||
|
|
00708608cd | ||
|
|
e339b7d9f0 | ||
|
|
2f958dafae | ||
|
|
3df47ed748 | ||
|
|
c7a02ae870 | ||
|
|
42356cc2a3 | ||
|
|
b796ae36db | ||
|
|
7bd44484be | ||
|
|
607bb45f5f | ||
|
|
90518056cd | ||
|
|
1e52ec42ca | ||
|
|
1e04ee14de | ||
|
|
469f9e8933 | ||
|
|
c49aff5cfc | ||
|
|
39009a71d5 | ||
|
|
0430178fe2 | ||
|
|
cf9df883c9 | ||
|
|
198befe2bc | ||
|
|
7195bd6cd6 | ||
|
|
a5fa2da80c | ||
|
|
593d37f37c | ||
|
|
2ddd6753ca | ||
|
|
9537c4f210 | ||
|
|
e0ce6ba165 | ||
|
|
ee50ce26f8 | ||
|
|
94a6de4a90 | ||
|
|
d5902314c3 | ||
|
|
ccb94c8a13 | ||
|
|
f285061a76 | ||
|
|
78a6262665 | ||
|
|
8a13799829 | ||
|
|
34059ad99d | ||
|
|
87e881f8e0 | ||
|
|
1823bc6528 | ||
|
|
077beb37b1 | ||
|
|
8182e83846 | ||
|
|
59f62d4a4c | ||
|
|
60125534ec | ||
|
|
48385cadc9 | ||
|
|
ba6abe6ca7 | ||
|
|
79ad243bf4 | ||
|
|
5ab21e019d | ||
|
|
d8469efba2 | ||
|
|
43c15de55c | ||
|
|
d2144a1fed | ||
|
|
915444b5da | ||
|
|
6387c24c89 | ||
|
|
f01ec9dbe4 | ||
|
|
219fbe5fca | ||
|
|
64db3ed965 | ||
|
|
deec059a38 | ||
|
|
316b09ddf3 | ||
|
|
866ef73774 | ||
|
|
138d5c6e0f | ||
|
|
4bed50d894 | ||
|
|
4e57750214 | ||
|
|
3738cb6025 | ||
|
|
0af5a58dbe | ||
|
|
09acca950d | ||
|
|
e04b635c98 | ||
|
|
9bd1b86f6e | ||
|
|
17b49e7ae5 | ||
|
|
7b6ba37667 | ||
|
|
879b702fc1 | ||
|
|
f265b9d19d | ||
|
|
6be55d1837 | ||
|
|
fc6643bd6f | ||
|
|
55943f5d8f | ||
|
|
56d120cd08 | ||
|
|
3e693642b6 | ||
|
|
8fe3f4cf5c | ||
|
|
be14fe548c | ||
|
|
85f3ba6aaa | ||
|
|
133652c296 | ||
|
|
b9331ac1ef | ||
|
|
08f7b2cc87 | ||
|
|
1a2bdaf8e5 | ||
|
|
d81dec78ae | ||
|
|
f78bd03521 | ||
|
|
6aa16272d8 | ||
|
|
e80f7c08ab | ||
|
|
675f05f0fb | ||
|
|
b1f23e1684 | ||
|
|
d612164885 | ||
|
|
b257e1d5f7 | ||
|
|
f26776ecd5 | ||
|
|
bf4a23652c | ||
|
|
e7681aedb1 | ||
|
|
098fcb29fb | ||
|
|
eb46ea19e3 | ||
|
|
99ee05a90f | ||
|
|
fd31f983af | ||
|
|
80bae4167f | ||
|
|
eaee4af715 | ||
|
|
7d4723c3e4 | ||
|
|
33a0981981 | ||
|
|
b62dc1241d | ||
|
|
e2270aec38 | ||
|
|
73346fcdaf | ||
|
|
7b112512a9 | ||
|
|
0e5613b57b | ||
|
|
e66ff40733 | ||
|
|
73d61f7440 | ||
|
|
35a0e8464a | ||
|
|
040e86ea6d | ||
|
|
8dad143f8d | ||
|
|
bcd41c4d9b | ||
|
|
3bc6e61869 | ||
|
|
3486957447 | ||
|
|
6b5c51bdc5 | ||
|
|
676c8eeefb | ||
|
|
f5a15b23d6 | ||
|
|
6d3b0261b3 | ||
|
|
dedb3071d6 | ||
|
|
a43ee52086 | ||
|
|
97ccb0cb21 | ||
|
|
1fb334b0ca | ||
|
|
fa4af99525 | ||
|
|
b3153dac68 | ||
|
|
c981476706 | ||
|
|
1a3e5ec705 | ||
|
|
aaff0835a3 | ||
|
|
9bf814d4cd | ||
|
|
b5c0f37f88 | ||
|
|
05d73d2f68 | ||
|
|
ff284d056c | ||
|
|
2393c759f3 | ||
|
|
0a983513ea | ||
|
|
c737348cea | ||
|
|
e8e2258357 | ||
|
|
d847b74522 | ||
|
|
5750e7dbdf | ||
|
|
ffe76f9d2e | ||
|
|
5b1ad541a8 | ||
|
|
4824a82c3f | ||
|
|
f7cea1100c | ||
|
|
827dd01e28 | ||
|
|
d969f49ecc | ||
|
|
0f336b6f89 | ||
|
|
43cc37d10f | ||
|
|
6a00b8e168 | ||
|
|
1b3fc2c23c | ||
|
|
8e96971b9c | ||
|
|
8e39e330fe | ||
|
|
15ba6572df | ||
|
|
1c222ff293 | ||
|
|
2fb1ec7f8a | ||
|
|
70f1db9619 | ||
|
|
11be65678e | ||
|
|
80ed064cd6 | ||
|
|
62b1e33616 | ||
|
|
52f2ef6d30 | ||
|
|
8ace78a873 | ||
|
|
5c30210534 | ||
|
|
1d03b6c38d | ||
|
|
d3ead8742e | ||
|
|
ed6b0057b7 | ||
|
|
90fbcb88d8 | ||
|
|
be2ed52d93 | ||
|
|
f1af19a52a | ||
|
|
4c4501073c | ||
|
|
b8b9a416ac | ||
|
|
fc7e436ca9 | ||
|
|
1de1eebc59 | ||
|
|
a4d411656b | ||
|
|
1ec4266f96 | ||
|
|
61f02d693f | ||
|
|
cd80552ce7 | ||
|
|
d59b8817c3 | ||
|
|
8ce5f4a796 | ||
|
|
2e8cb35acc | ||
|
|
c0f626e9bd | ||
|
|
2ddfe48aba | ||
|
|
2c6de84c9a | ||
|
|
87cf4c2d08 | ||
|
|
3a8c835880 | ||
|
|
e2dbd3d873 | ||
|
|
55aabddd41 | ||
|
|
eb07820523 | ||
|
|
8116217019 | ||
|
|
6fb1845ff7 | ||
|
|
75325f0ed8 | ||
|
|
0577f9e166 | ||
|
|
52c6884e28 | ||
|
|
2be76a488f | ||
|
|
686535fe42 | ||
|
|
5c17aee1e4 | ||
|
|
9b35ac3a99 | ||
|
|
59b78e850f | ||
|
|
3a8c5a788f | ||
|
|
afcbbe0f43 | ||
|
|
d10d29e590 | ||
|
|
7b61cb3163 | ||
|
|
4c1c6701b3 | ||
|
|
f423fdf7f8 | ||
|
|
a5995a2ce8 | ||
|
|
c810b6772c | ||
|
|
b74ab18a6d | ||
|
|
edc54aaf91 | ||
|
|
b3b205cd6e | ||
|
|
2fe4def775 | ||
|
|
7bbf612394 | ||
|
|
97ab1f0492 | ||
|
|
81bfcdd158 | ||
|
|
6862d318f0 | ||
|
|
412fa3f0bf | ||
|
|
01d9109c45 | ||
|
|
dd914d1d64 | ||
|
|
5cf3624a3a | ||
|
|
c7ff8c2dd1 | ||
|
|
83c202d675 | ||
|
|
f7648e3311 | ||
|
|
c203de082e | ||
|
|
a95ba1acc4 | ||
|
|
db325525e4 | ||
|
|
db97114fb4 | ||
|
|
b18a300f10 | ||
|
|
61ffb857ee | ||
|
|
701212239d | ||
|
|
422fa01c6f | ||
|
|
62820b4dd9 | ||
|
|
8ea92ef330 | ||
|
|
de82249d8d | ||
|
|
94a26ae75a | ||
|
|
f9fdae9de9 | ||
|
|
0cb46039dd | ||
|
|
c4439cc9db | ||
|
|
6cd9640b30 | ||
|
|
f9bce3dfdb | ||
|
|
8eb0c997ed | ||
|
|
a8f96e06bd | ||
|
|
9a2945927f | ||
|
|
89f9249ec6 | ||
|
|
24f572253f | ||
|
|
4fc9c19893 | ||
|
|
f6fcd730a8 | ||
|
|
716a56979d | ||
|
|
538476be99 | ||
|
|
93a170a893 | ||
|
|
e0301f096f | ||
|
|
9e3cb4d694 | ||
|
|
49b76c3e43 | ||
|
|
9962784991 | ||
|
|
6336b38cfc | ||
|
|
2362835275 | ||
|
|
8a4ede9d43 | ||
|
|
cc1595e048 | ||
|
|
ca16763423 | ||
|
|
b6dd5bb881 | ||
|
|
f8e299ec56 | ||
|
|
91e9c6e048 | ||
|
|
b941b97eee | ||
|
|
d38ac652fc | ||
|
|
bdcf3b71ce | ||
|
|
ddbf8b7725 | ||
|
|
a6fd4547a7 | ||
|
|
d20153c569 | ||
|
|
15e072a2ff | ||
|
|
f98e20aa84 | ||
|
|
e7a1b33ae6 | ||
|
|
2d5f23271f | ||
|
|
059110ae7a | ||
|
|
ac84c175af | ||
|
|
3b6014c229 | ||
|
|
9cb265c6f5 | ||
|
|
a47f0ccc12 | ||
|
|
e032f6b33d | ||
|
|
98e179ba06 | ||
|
|
2ebb4fef4c | ||
|
|
e72b120c12 | ||
|
|
7b87b00b44 | ||
|
|
2b793bf242 | ||
|
|
49ae906029 | ||
|
|
4f82a0f026 | ||
|
|
ae8edffdc8 | ||
|
|
2b67c1c631 | ||
|
|
d395cf66a0 | ||
|
|
956ed9e8ae | ||
|
|
63726b09d6 | ||
|
|
f78d42cc30 | ||
|
|
5d1c807a86 | ||
|
|
fad077aad9 | ||
|
|
24f47bee73 | ||
|
|
d93b7b2cb2 | ||
|
|
ab03111a84 | ||
|
|
1ba03b69f6 | ||
|
|
9957f64628 | ||
|
|
6505af2a8b | ||
|
|
54c74bac6e | ||
|
|
5cf4c879dd | ||
|
|
aa00db48ce | ||
|
|
4a158db632 | ||
|
|
f57a0ecba2 | ||
|
|
3614c82632 | ||
|
|
9207d41f17 | ||
|
|
c5abd0ff3f | ||
|
|
2c2bde1e05 | ||
|
|
dcff8c0d9a | ||
|
|
44555e5289 | ||
|
|
9c4eff68a3 | ||
|
|
8f9122c706 | ||
|
|
3eb1b476dd | ||
|
|
0de9f48be4 | ||
|
|
162b482a8b | ||
|
|
2a46358ccf | ||
|
|
8146d6c293 | ||
|
|
5ab067cf86 | ||
|
|
720859197c | ||
|
|
ce064a0b37 | ||
|
|
bfd82fb415 | ||
|
|
655f656781 | ||
|
|
3f32841f49 | ||
|
|
4d7c021925 | ||
|
|
ac923fe669 | ||
|
|
d35b62995e | ||
|
|
ae7d2745db | ||
|
|
5ff47e63bc | ||
|
|
389341f613 | ||
|
|
00b51ad40d | ||
|
|
34c39597f5 | ||
|
|
4516e75b6f | ||
|
|
040518cca8 | ||
|
|
5d336e5fb9 | ||
|
|
e7d0103869 | ||
|
|
55cb10910f | ||
|
|
ecded8af93 | ||
|
|
20826daa18 | ||
|
|
742f1f4622 | ||
|
|
49cf20545f | ||
|
|
289e6f3d1c | ||
|
|
b246d17a33 | ||
|
|
c6b6616ee3 | ||
|
|
d6500c45aa | ||
|
|
6fd79688b0 | ||
|
|
c6478857bc | ||
|
|
8a711ffecb | ||
|
|
139ea879df | ||
|
|
6a0968cc02 | ||
|
|
5a1fa409d8 | ||
|
|
225da163bb | ||
|
|
801ed0fbaf | ||
|
|
ea44fe0f16 | ||
|
|
6081fe3295 | ||
|
|
6df65a0b9d | ||
|
|
0aec9419ec | ||
|
|
bb510a9240 | ||
|
|
cce3e1cfb8 | ||
|
|
4977f6c270 | ||
|
|
fe1715259a | ||
|
|
f4c0d84380 | ||
|
|
8a20584e27 | ||
|
|
218b0adb8f | ||
|
|
7d99607919 | ||
|
|
9adfcc7aec | ||
|
|
2da7463edf | ||
|
|
4a644d8712 | ||
|
|
afa17ca429 | ||
|
|
50708c6942 | ||
|
|
cbdf0a9392 | ||
|
|
b7c8ca2a48 | ||
|
|
3817ba774d | ||
|
|
e8771ea118 | ||
|
|
2f46fbfc7a | ||
|
|
78b0e1bf7e | ||
|
|
19530a9102 | ||
|
|
74051c5649 | ||
|
|
f3f391ab43 | ||
|
|
fc75621f1a | ||
|
|
fc3290271c | ||
|
|
71cd4057a7 | ||
|
|
485b35fbd4 | ||
|
|
172884ace8 | ||
|
|
b788c3745c | ||
|
|
7658cfcdbd | ||
|
|
52c8ea13af | ||
|
|
8f424f3273 | ||
|
|
3d7cf8f7f3 | ||
|
|
930adaf439 | ||
|
|
e5a14557a2 | ||
|
|
6a2ff9d153 | ||
|
|
bea90a7d94 | ||
|
|
e57d6e508a | ||
|
|
219b57a362 | ||
|
|
df8f54f5a4 | ||
|
|
fcbb1849ec | ||
|
|
684334ba22 | ||
|
|
5629215ce4 | ||
|
|
f63b6d7207 | ||
|
|
98dc553938 | ||
|
|
7ee01d9a05 | ||
|
|
dc6a67c2f0 | ||
|
|
affed459df | ||
|
|
8d4b8b02b8 | ||
|
|
8c430a3af0 | ||
|
|
b7573a40d7 | ||
|
|
624696711d | ||
|
|
56828e9e00 | ||
|
|
d2358c9550 | ||
|
|
ab11747fab | ||
|
|
44cb0fa434 | ||
|
|
13814695ac | ||
|
|
377e2eb613 | ||
|
|
bf4725a768 | ||
|
|
ed65abf786 | ||
|
|
8d29fe8679 | ||
|
|
f4f77c62c8 | ||
|
|
2cc08cdea1 | ||
|
|
03dc6d63ed | ||
|
|
bcb3ccec9a | ||
|
|
4bec8efea1 | ||
|
|
58b2c2bd69 | ||
|
|
636776c531 | ||
|
|
ca4a33d408 | ||
|
|
9db158f4d4 | ||
|
|
ea8b179df1 | ||
|
|
efc152e3c8 | ||
|
|
e68827bf3b | ||
|
|
58bf69882f | ||
|
|
915f313efd | ||
|
|
52d29099a2 | ||
|
|
c06fc926a1 | ||
|
|
79ab1a2277 | ||
|
|
7c03630e24 | ||
|
|
34a65419c7 | ||
|
|
7191ece7a5 | ||
|
|
0837f84a43 | ||
|
|
0bc4699cdc | ||
|
|
bb1285c35c | ||
|
|
21fc554589 | ||
|
|
a43af180a7 | ||
|
|
88ea920dfb | ||
|
|
132aac3951 | ||
|
|
7640ed08bc | ||
|
|
1dbf36b86b | ||
|
|
508de10191 | ||
|
|
ccfe259c69 | ||
|
|
0573f80525 | ||
|
|
8fb4e6c4ee | ||
|
|
05b2515b3b | ||
|
|
0ecb339fdf | ||
|
|
92ddebc289 | ||
|
|
1a3f0675bf | ||
|
|
c24019fd57 | ||
|
|
55641a234c | ||
|
|
9f52d364c9 | ||
|
|
edce70bc12 | ||
|
|
b8a7f81f55 | ||
|
|
ef9b2aefe5 | ||
|
|
cd1413a74e | ||
|
|
4e9d93957e | ||
|
|
9c4e9066f9 | ||
|
|
b4d1af2bce | ||
|
|
5ec676c40c | ||
|
|
5096aea5bb | ||
|
|
feedd190dc | ||
|
|
3423fffaca | ||
|
|
1624fd2e28 | ||
|
|
10b3094d5e | ||
|
|
580e638f67 | ||
|
|
e44428f87c | ||
|
|
379f7ef865 | ||
|
|
427f6e4d55 | ||
|
|
07a1e9fc3c | ||
|
|
78d64e8f1b | ||
|
|
559a9a9f3e | ||
|
|
ac6dd23fd6 | ||
|
|
1e515df0b5 | ||
|
|
35490762a6 | ||
|
|
c25e23d3d9 | ||
|
|
8bb8257e62 | ||
|
|
5f096927bd | ||
|
|
434826c125 | ||
|
|
89595cd5dc | ||
|
|
d991e15a94 | ||
|
|
6a1aefa5a5 | ||
|
|
272684e7eb | ||
|
|
9be3eba694 | ||
|
|
5a3fc0fb43 | ||
|
|
47ef8e9568 | ||
|
|
e4285bbc78 | ||
|
|
49b6a42791 | ||
|
|
b62fd602f2 | ||
|
|
923e40ed8f | ||
|
|
3c724a227a | ||
|
|
90d26eb16a | ||
|
|
b629744e1a | ||
|
|
b0ab43c39a | ||
|
|
2c33b381c1 | ||
|
|
c50a80e8df | ||
|
|
bafbd63610 | ||
|
|
557347d42d | ||
|
|
c828aa3bc0 | ||
|
|
376d29e829 | ||
|
|
97ee4f36e3 | ||
|
|
d766f255ef | ||
|
|
19ae9e7456 | ||
|
|
61ea312403 | ||
|
|
13193c9368 | ||
|
|
31e0ce4c64 | ||
|
|
43238aff0a | ||
|
|
d598bfc35b | ||
|
|
1c836918ca | ||
|
|
4a6a3b9269 | ||
|
|
1534f780aa | ||
|
|
4c6ceab8e8 | ||
|
|
021e28aca8 | ||
|
|
334d81db08 | ||
|
|
6ffd45a82a | ||
|
|
2fe3902d8d | ||
|
|
4dceda8251 | ||
|
|
09cf33f530 | ||
|
|
3e851a65e9 | ||
|
|
e8ec536a5a | ||
|
|
967be4451a | ||
|
|
bc65a18f3c | ||
|
|
1eb9c38aee | ||
|
|
ccaad1c305 | ||
|
|
963a22783f | ||
|
|
303a3690e8 | ||
|
|
29fa0818f6 | ||
|
|
1a21a3ed42 | ||
|
|
7baad04e39 | ||
|
|
273293479d | ||
|
|
37fb895d67 | ||
|
|
0dcdd252f5 | ||
|
|
d04d743520 | ||
|
|
63df16a369 | ||
|
|
13209c3236 | ||
|
|
29d1d49aca | ||
|
|
de96aae9a5 | ||
|
|
5f29ee9052 | ||
|
|
b3ecee749e | ||
|
|
1cee1abe00 | ||
|
|
558440168d | ||
|
|
d0cb7ab486 | ||
|
|
c317bc020a | ||
|
|
4065fb77da | ||
|
|
8351f38ee7 | ||
|
|
f3fc01b740 | ||
|
|
a201be5a01 | ||
|
|
ebf2035351 | ||
|
|
6e6e203f8a | ||
|
|
2192149b5a | ||
|
|
a4e19196a7 | ||
|
|
0c744c5444 | ||
|
|
69fc28d5d6 | ||
|
|
4107535b19 | ||
|
|
e0e5fb3d5a | ||
|
|
1125096e5a | ||
|
|
fc1d2269d0 | ||
|
|
cc033d5be7 | ||
|
|
7eee3de965 | ||
|
|
0c6245fe8e | ||
|
|
342ed382e3 | ||
|
|
aaf6c37871 | ||
|
|
65e1346a11 | ||
|
|
7f9307feec | ||
|
|
036eaf3bae | ||
|
|
2717d7d311 | ||
|
|
577b841ee0 | ||
|
|
857eb0517c | ||
|
|
ec50197b40 | ||
|
|
4ace7dd370 | ||
|
|
0eea7f8d4d | ||
|
|
80c7680d17 | ||
|
|
3edc0a7f53 | ||
|
|
29af14f588 | ||
|
|
5f2408b791 | ||
|
|
5b5e8a4fd5 | ||
|
|
71b0c2d83e | ||
|
|
363b7bc314 | ||
|
|
448032c5b7 | ||
|
|
2af1234cfd | ||
|
|
d258235430 | ||
|
|
c060d6ebb1 | ||
|
|
72dab2bc4e | ||
|
|
b0d2a22f62 | ||
|
|
bcda71cb25 | ||
|
|
d32e902d17 | ||
|
|
f91b719542 | ||
|
|
8bccab258a | ||
|
|
6443d8e2bf | ||
|
|
286759f232 | ||
|
|
0dba32fdf2 | ||
|
|
54c6757bc7 | ||
|
|
c91a6640ff | ||
|
|
80ef617949 | ||
|
|
72dd3f92f9 | ||
|
|
5330476dbe | ||
|
|
69fdc85c99 | ||
|
|
f7293508ff | ||
|
|
4aedce9668 | ||
|
|
9244fe5944 | ||
|
|
35710b17d1 | ||
|
|
fb78ce5679 | ||
|
|
749e7dbdf9 | ||
|
|
ccae58cb2f | ||
|
|
64199b91d5 | ||
|
|
c8218f6891 | ||
|
|
8e2f297839 | ||
|
|
0feb9661df | ||
|
|
1acceae81e | ||
|
|
a7ff690891 | ||
|
|
447b54fa4b | ||
|
|
5f5541ca12 | ||
|
|
f101e1b184 | ||
|
|
065417038c | ||
|
|
047c82791b | ||
|
|
f1672c7076 | ||
|
|
e7e57fa412 | ||
|
|
5536fcce00 | ||
|
|
8a3ce36c65 | ||
|
|
325812fe95 | ||
|
|
421a5d27dd | ||
|
|
27b43041f9 | ||
|
|
a7ea12d07d | ||
|
|
927f570283 | ||
|
|
66c1eff79f | ||
|
|
4cb1313a77 | ||
|
|
52bdde40a1 | ||
|
|
8295ed716b | ||
|
|
d84ee57354 | ||
|
|
0ae57b8b7b | ||
|
|
a4e68ea2d6 | ||
|
|
a48b4ccaa8 | ||
|
|
bcaf8e9912 | ||
|
|
ae438f1650 | ||
|
|
563d6bccd3 | ||
|
|
7220d752ac | ||
|
|
46beb21ba7 | ||
|
|
c972f0ac59 | ||
|
|
21c74fbcc8 | ||
|
|
1ca839ab26 | ||
|
|
34aefd32e8 | ||
|
|
fce32e70b9 | ||
|
|
0550c045c7 | ||
|
|
69b1c062f5 | ||
|
|
4713b2f079 | ||
|
|
6fe907a13d | ||
|
|
45ce4ac1ba |
@@ -26,14 +26,23 @@
|
||||
|
||||
# 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 DATABASE_URL
|
||||
PassEnv DEFAULT_LANG DEFAULT_TIMEZONE BASE_CURRENCY INSTANCE_NAME ALLOW_ATTACHMENT_DOWNLOADS USE_GRAVATAR MAX_ATTACHMENT_FILE_SIZE DEFAULT_URI
|
||||
PassEnv TRUSTED_PROXIES TRUSTED_HOSTS LOCK_DSN
|
||||
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 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
|
||||
PassEnv HISTORY_SAVE_CHANGED_FIELDS HISTORY_SAVE_CHANGED_DATA HISTORY_SAVE_REMOVED_DATA HISTORY_SAVE_NEW_DATA
|
||||
PassEnv ERROR_PAGE_ADMIN_EMAIL ERROR_PAGE_SHOW_HELP
|
||||
PassEnv DEMO_MODE NO_URL_REWRITE_AVAILABLE FIXER_API_KEY BANNER
|
||||
PassEnv SAML_ENABLED SAML_ROLE_MAPPING SAML_UPDATE_GROUP_ON_LOGIN SAML_IDP_ENTITY_ID SAML_IDP_SINGLE_SIGN_ON_SERVICE SAML_IDP_SINGLE_LOGOUT_SERVICE SAML_IDP_X509_CERT SAML_SP_ENTITY_ID SAML_SP_X509_CERT SAMLP_SP_PRIVATE_KEY
|
||||
# In old version the SAML sp private key env, was wrongly named SAMLP_SP_PRIVATE_KEY, keep it for backward compatibility
|
||||
PassEnv SAML_ENABLED SAML_BEHIND_PROXY SAML_ROLE_MAPPING SAML_UPDATE_GROUP_ON_LOGIN SAML_IDP_ENTITY_ID SAML_IDP_SINGLE_SIGN_ON_SERVICE SAML_IDP_SINGLE_LOGOUT_SERVICE SAML_IDP_X509_CERT SAML_SP_ENTITY_ID SAML_SP_X509_CERT SAML_SP_PRIVATE_KEY SAMLP_SP_PRIVATE_KEY
|
||||
PassEnv TABLE_DEFAULT_PAGE_SIZE TABLE_PARTS_DEFAULT_COLUMNS
|
||||
|
||||
PassEnv PROVIDER_DIGIKEY_CLIENT_ID PROVIDER_DIGIKEY_SECRET PROVIDER_DIGIKEY_CURRENCY PROVIDER_DIGIKEY_LANGUAGE PROVIDER_DIGIKEY_COUNTRY
|
||||
PassEnv PROVIDER_ELEMENT14_KEY PROVIDER_ELEMENT14_STORE_ID
|
||||
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_MOUSER_KEY PROVIDER_MOUSER_SEARCH_OPTION PROVIDER_MOUSER_SEARCH_LIMIT PROVIDER_MOUSER_SEARCH_WITH_SIGNUP_LANGUAGE
|
||||
PassEnv EDA_KICAD_CATEGORY_DEPTH
|
||||
|
||||
# For most configuration files from conf-available/, which are
|
||||
# enabled or disabled at a global level, it is possible to
|
||||
|
||||
115
.env
115
.env
@@ -14,6 +14,15 @@ DATABASE_URL="sqlite:///%kernel.project_dir%/var/app.db"
|
||||
# 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
|
||||
|
||||
# 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
|
||||
|
||||
###################################################################################
|
||||
# General settings
|
||||
###################################################################################
|
||||
@@ -29,16 +38,26 @@ INSTANCE_NAME="Part-DB"
|
||||
# Allow users to download attachments to the server by providing an URL
|
||||
# This could be a potential security issue, as the user can retrieve any file the server has access to (via internet)
|
||||
ALLOW_ATTACHMENT_DOWNLOADS=0
|
||||
# Set this to 1, if the "download external files" checkbox should be checked by default for new attachments
|
||||
ATTACHMENT_DOWNLOAD_BY_DEFAULT=0
|
||||
# Use gravatars for user avatars, when user has no own avatar defined
|
||||
USE_GRAVATAR=0
|
||||
# The maximum allowed size for attachment files in bytes (you can use M for megabytes and G for gigabytes)
|
||||
# Please note that the php.ini setting upload_max_filesize also limits the maximum size of uploaded files
|
||||
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!
|
||||
DEFAULT_URI="https://partdb.changeme.invalid/"
|
||||
|
||||
# With this option you can configure, where users are enforced to give a change reason, which will be logged
|
||||
# This is a comma separated list of values, see documentation for available values
|
||||
# Leave this empty, to make all change reasons optional
|
||||
ENFORCE_CHANGE_COMMENTS_FOR=""
|
||||
|
||||
# Disable that if you do not want that Part-DB connects to GitHub to check for available updates, or if your server can not connect to the internet
|
||||
CHECK_FOR_UPDATES=1
|
||||
|
||||
###################################################################################
|
||||
# Email settings
|
||||
###################################################################################
|
||||
@@ -66,6 +85,9 @@ HISTORY_SAVE_CHANGED_FIELDS=1
|
||||
HISTORY_SAVE_CHANGED_DATA=1
|
||||
# Save the data of an element that gets removed into log entry. This allows to undelete an element
|
||||
HISTORY_SAVE_REMOVED_DATA=1
|
||||
# Save the new data of an element that gets changed or added. This allows an easy comparison of the old and new data on the detail page
|
||||
# This option only becomes active when HISTORY_SAVE_CHANGED_DATA is set to 1
|
||||
HISTORY_SAVE_NEW_DATA=1
|
||||
|
||||
###################################################################################
|
||||
# Error pages settings
|
||||
@@ -76,12 +98,95 @@ ERROR_PAGE_ADMIN_EMAIL=''
|
||||
# If this is set to true, solutions to common problems are shown on error pages. Disable this, if you do not want your users to see them...
|
||||
ERROR_PAGE_SHOW_HELP=1
|
||||
|
||||
##################################################################################
|
||||
# Part table settings
|
||||
##################################################################################
|
||||
|
||||
# The default page size for the part table (set to -1 to show all parts on one page)
|
||||
TABLE_DEFAULT_PAGE_SIZE=50
|
||||
# Configure which columns will be visible by default in the parts table (and in which order).
|
||||
# This is a comma separated list of column names. See documentation for available values.
|
||||
TABLE_PARTS_DEFAULT_COLUMNS=name,description,category,footprint,manufacturer,storage_location,amount
|
||||
|
||||
##################################################################################
|
||||
# Info provider settings
|
||||
##################################################################################
|
||||
|
||||
# Digikey Provider:
|
||||
# You can get your client id and secret from https://developer.digikey.com/
|
||||
PROVIDER_DIGIKEY_CLIENT_ID=
|
||||
PROVIDER_DIGIKEY_SECRET=
|
||||
# The currency to get prices in
|
||||
PROVIDER_DIGIKEY_CURRENCY=EUR
|
||||
# The language to get results in (en, de, fr, it, es, zh, ja, ko)
|
||||
PROVIDER_DIGIKEY_LANGUAGE=en
|
||||
# The country to get results for
|
||||
PROVIDER_DIGIKEY_COUNTRY=DE
|
||||
|
||||
# Farnell Provider:
|
||||
# You can get your API key from https://partner.element14.com/
|
||||
PROVIDER_ELEMENT14_KEY=
|
||||
# Configure the store domain you want to use. This decides the language and currency of results. You can get a list of available stores from https://partner.element14.com/docs/Product_Search_API_REST__Description
|
||||
PROVIDER_ELEMENT14_STORE_ID=de.farnell.com
|
||||
|
||||
# TME Provider:
|
||||
# You can get your API key from https://developers.tme.eu/en/
|
||||
PROVIDER_TME_KEY=
|
||||
PROVIDER_TME_SECRET=
|
||||
# The currency to get prices in
|
||||
PROVIDER_TME_CURRENCY=EUR
|
||||
# The language to get results in (en, de, pl)
|
||||
PROVIDER_TME_LANGUAGE=en
|
||||
# The country to get results for
|
||||
PROVIDER_TME_COUNTRY=DE
|
||||
# Set this to 1 to get gross prices (including VAT) instead of net prices
|
||||
PROVIDER_TME_GET_GROSS_PRICES=1
|
||||
|
||||
# Octopart / Nexar Provider:
|
||||
# You can get your API key from https://nexar.com/api
|
||||
PROVIDER_OCTOPART_CLIENT_ID=
|
||||
PROVIDER_OCTOPART_SECRET=
|
||||
# The currency and country to get prices for (you have to set both to get meaningful results)
|
||||
# 3 letter ISO currency code (e.g. EUR, USD, GBP)
|
||||
PROVIDER_OCTOPART_CURRENCY=EUR
|
||||
# 2 letter ISO country code (e.g. DE, US, GB)
|
||||
PROVIDER_OCTOPART_COUNTRY=DE
|
||||
# The number of results to get from Octopart while searching (please note that this counts towards your API limits)
|
||||
PROVIDER_OCTOPART_SEARCH_LIMIT=10
|
||||
# Set to false to include non authorized offers in the results
|
||||
PROVIDER_OCTOPART_ONLY_AUTHORIZED_SELLERS=1
|
||||
|
||||
# Mouser Provider API V2:
|
||||
# You can get your API key from https://www.mouser.it/api-hub/
|
||||
PROVIDER_MOUSER_KEY=
|
||||
# Filter search results by RoHS compliance and stock availability:
|
||||
# Available options: None | Rohs | InStock | RohsAndInStock
|
||||
PROVIDER_MOUSER_SEARCH_OPTION='None'
|
||||
# The number of results to get from Mouser while searching (please note that this value is max 50)
|
||||
PROVIDER_MOUSER_SEARCH_LIMIT=50
|
||||
# It is recommended to leave this set to 'true'. The option is not really good doumented by Mouser:
|
||||
# Used when searching for keywords in the language specified when you signed up for Search API.
|
||||
PROVIDER_MOUSER_SEARCH_WITH_SIGNUP_LANGUAGE='true'
|
||||
|
||||
##################################################################################
|
||||
# EDA integration related settings
|
||||
##################################################################################
|
||||
|
||||
# This value determines the depth of the category tree, that is visible inside KiCad
|
||||
# 0 means that only the top level categories are visible. Set to a value > 0 to show more levels.
|
||||
# Set to -1, to show all parts of Part-DB inside a single category in KiCad
|
||||
EDA_KICAD_CATEGORY_DEPTH=0
|
||||
|
||||
###################################################################################
|
||||
# SAML Single sign on-settings
|
||||
###################################################################################
|
||||
# Set this to 1 to enable SAML single sign on
|
||||
# Be also sure to set the correct values for DEFAULT_URI
|
||||
SAML_ENABLED=0
|
||||
|
||||
# Set to 1, if your Part-DB installation is behind a reverse proxy and you want to use SAML
|
||||
SAML_BEHIND_PROXY=0
|
||||
|
||||
# A JSON encoded array of role mappings in the form { "saml_role": PARTDB_GROUP_ID, "*": PARTDB_GROUP_ID }
|
||||
# The first match is used, so the order is important! Put the group mapping with the most privileges first.
|
||||
# Please not to only use single quotes to enclose the JSON string
|
||||
@@ -108,7 +213,7 @@ SAML_SP_ENTITY_ID="https://partdb.changeme.invalid/sp"
|
||||
# The public certificate of the SAML SP
|
||||
SAML_SP_X509_CERT="MIIC..."
|
||||
# The private key of the SAML SP
|
||||
SAMLP_SP_PRIVATE_KEY="MIIE..."
|
||||
SAML_SP_PRIVATE_KEY="MIIE..."
|
||||
|
||||
|
||||
######################################################################################
|
||||
@@ -133,7 +238,7 @@ APP_SECRET=a03498528f5a5fc089273ec9ae5b2849
|
||||
|
||||
|
||||
# Set the trusted IPs here, when using an reverse proxy
|
||||
#TRUSTED_PROXIES=127.0.0.0/8,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
|
||||
#TRUSTED_HOSTS='^(localhost|example\.com)$'
|
||||
|
||||
|
||||
@@ -142,3 +247,7 @@ APP_SECRET=a03498528f5a5fc089273ec9ae5b2849
|
||||
# postgresql+advisory://db_user:db_password@localhost/db_name
|
||||
LOCK_DSN=flock
|
||||
###< symfony/lock ###
|
||||
|
||||
###> nelmio/cors-bundle ###
|
||||
CORS_ALLOW_ORIGIN='^https?://(localhost|127\.0\.0\.1)(:[0-9]+)?$'
|
||||
###< nelmio/cors-bundle ###
|
||||
|
||||
@@ -5,5 +5,9 @@ SYMFONY_DEPRECATIONS_HELPER=999999
|
||||
PANTHER_APP_ENV=panther
|
||||
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
|
||||
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
|
||||
2
.gitattributes
vendored
Normal file
2
.gitattributes
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
# For sh files, always use LF line endings
|
||||
*.sh text eol=lf
|
||||
752
.github/assets/legacy_import/db_jbtronics.sql
vendored
Normal file
752
.github/assets/legacy_import/db_jbtronics.sql
vendored
Normal file
@@ -0,0 +1,752 @@
|
||||
-- phpMyAdmin SQL Dump
|
||||
-- version 5.1.3
|
||||
-- https://www.phpmyadmin.net/
|
||||
--
|
||||
-- Host: 127.0.0.1
|
||||
-- Erstellungszeit: 07. Mai 2023 um 01:58
|
||||
-- Server-Version: 10.6.5-MariaDB-log
|
||||
-- PHP-Version: 8.1.2
|
||||
|
||||
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
|
||||
START TRANSACTION;
|
||||
SET time_zone = "+00:00";
|
||||
|
||||
|
||||
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
|
||||
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
|
||||
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
|
||||
/*!40101 SET NAMES utf8mb4 */;
|
||||
|
||||
--
|
||||
-- Datenbank: `partdb_demo`
|
||||
--
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Tabellenstruktur für Tabelle `attachements`
|
||||
--
|
||||
|
||||
CREATE TABLE `attachements` (
|
||||
`id` int(11) NOT NULL,
|
||||
`name` tinytext COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||
`class_name` varchar(255) COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||
`element_id` int(11) NOT NULL,
|
||||
`type_id` int(11) NOT NULL,
|
||||
`filename` mediumtext COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||
`show_in_table` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`last_modified` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00'
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci;
|
||||
|
||||
--
|
||||
-- Daten für Tabelle `attachements`
|
||||
--
|
||||
|
||||
INSERT INTO `attachements` (`id`, `name`, `class_name`, `element_id`, `type_id`, `filename`, `show_in_table`, `last_modified`) VALUES
|
||||
(1, 'BC547', 'Part', 2, 2, '%BASE%/data/media/bc547.pdf', 1, '0000-00-00 00:00:00');
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Tabellenstruktur für Tabelle `attachement_types`
|
||||
--
|
||||
|
||||
CREATE TABLE `attachement_types` (
|
||||
`id` int(11) NOT NULL,
|
||||
`name` tinytext COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||
`parent_id` int(11) DEFAULT NULL,
|
||||
`comment` text COLLATE utf8mb3_unicode_ci DEFAULT NULL,
|
||||
`datetime_added` timestamp NOT NULL DEFAULT current_timestamp(),
|
||||
`last_modified` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00'
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci;
|
||||
|
||||
--
|
||||
-- Daten für Tabelle `attachement_types`
|
||||
--
|
||||
|
||||
INSERT INTO `attachement_types` (`id`, `name`, `parent_id`, `comment`, `datetime_added`, `last_modified`) VALUES
|
||||
(1, 'Bilder', NULL, NULL, '2017-10-21 17:58:48', '0000-00-00 00:00:00'),
|
||||
(2, 'Datenblätter', NULL, NULL, '2017-10-21 17:58:48', '0000-00-00 00:00:00');
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Tabellenstruktur für Tabelle `categories`
|
||||
--
|
||||
|
||||
CREATE TABLE `categories` (
|
||||
`id` int(11) NOT NULL,
|
||||
`name` tinytext COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||
`parent_id` int(11) DEFAULT NULL,
|
||||
`disable_footprints` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`disable_manufacturers` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`disable_autodatasheets` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`disable_properties` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`partname_regex` text COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||
`partname_hint` text COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||
`default_description` text COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||
`default_comment` text COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||
`comment` text COLLATE utf8mb3_unicode_ci DEFAULT NULL,
|
||||
`datetime_added` timestamp NOT NULL DEFAULT current_timestamp(),
|
||||
`last_modified` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00'
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci;
|
||||
|
||||
--
|
||||
-- Daten für Tabelle `categories`
|
||||
--
|
||||
|
||||
INSERT INTO `categories` (`id`, `name`, `parent_id`, `disable_footprints`, `disable_manufacturers`, `disable_autodatasheets`, `disable_properties`, `partname_regex`, `partname_hint`, `default_description`, `default_comment`, `comment`, `datetime_added`, `last_modified`) VALUES
|
||||
(1, 'aktive Bauteile', NULL, 0, 0, 0, 0, '', '', '', '', NULL, '2017-10-21 17:58:49', '0000-00-00 00:00:00');
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Tabellenstruktur für Tabelle `devices`
|
||||
--
|
||||
|
||||
CREATE TABLE `devices` (
|
||||
`id` int(11) NOT NULL,
|
||||
`name` tinytext COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||
`parent_id` int(11) DEFAULT NULL,
|
||||
`order_quantity` int(11) NOT NULL DEFAULT 0,
|
||||
`order_only_missing_parts` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`datetime_added` timestamp NOT NULL DEFAULT current_timestamp(),
|
||||
`last_modified` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
`comment` text COLLATE utf8mb3_unicode_ci DEFAULT NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci;
|
||||
|
||||
--
|
||||
-- Daten für Tabelle `devices`
|
||||
--
|
||||
|
||||
INSERT INTO `devices` (`id`, `name`, `parent_id`, `order_quantity`, `order_only_missing_parts`, `datetime_added`, `last_modified`, `comment`) VALUES
|
||||
(1, 'Test', NULL, 0, 0, '2015-04-16 15:08:56', '0000-00-00 00:00:00', NULL);
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Tabellenstruktur für Tabelle `device_parts`
|
||||
--
|
||||
|
||||
CREATE TABLE `device_parts` (
|
||||
`id` int(11) NOT NULL,
|
||||
`id_part` int(11) NOT NULL DEFAULT 0,
|
||||
`id_device` int(11) NOT NULL DEFAULT 0,
|
||||
`quantity` int(11) NOT NULL DEFAULT 0,
|
||||
`mountnames` mediumtext COLLATE utf8mb3_unicode_ci NOT NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci;
|
||||
|
||||
--
|
||||
-- Daten für Tabelle `device_parts`
|
||||
--
|
||||
|
||||
INSERT INTO `device_parts` (`id`, `id_part`, `id_device`, `quantity`, `mountnames`) VALUES
|
||||
(1, 2, 1, 1, '');
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Tabellenstruktur für Tabelle `footprints`
|
||||
--
|
||||
|
||||
CREATE TABLE `footprints` (
|
||||
`id` int(11) NOT NULL,
|
||||
`name` tinytext COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||
`filename` mediumtext COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||
`filename_3d` mediumtext COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||
`parent_id` int(11) DEFAULT NULL,
|
||||
`comment` text COLLATE utf8mb3_unicode_ci DEFAULT NULL,
|
||||
`datetime_added` timestamp NOT NULL DEFAULT current_timestamp(),
|
||||
`last_modified` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00'
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci;
|
||||
|
||||
--
|
||||
-- Daten für Tabelle `footprints`
|
||||
--
|
||||
|
||||
INSERT INTO `footprints` (`id`, `name`, `filename`, `filename_3d`, `parent_id`, `comment`, `datetime_added`, `last_modified`) VALUES
|
||||
(1, 'LEDs', '%BASE%/img/footprints/Optik/LEDs/Bedrahtet/LED-GELB_3MM.png', '', NULL, NULL, '2017-10-21 17:58:49', '0000-00-00 00:00:00');
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Tabellenstruktur für Tabelle `groups`
|
||||
--
|
||||
|
||||
CREATE TABLE `groups` (
|
||||
`id` int(11) NOT NULL,
|
||||
`name` varchar(32) NOT NULL,
|
||||
`parent_id` int(11) DEFAULT NULL,
|
||||
`comment` mediumtext DEFAULT NULL,
|
||||
`perms_system` int(11) NOT NULL,
|
||||
`perms_groups` int(11) NOT NULL,
|
||||
`perms_users` int(11) NOT NULL,
|
||||
`perms_self` int(11) NOT NULL,
|
||||
`perms_system_config` int(11) NOT NULL,
|
||||
`perms_system_database` int(11) NOT NULL,
|
||||
`perms_parts` bigint(11) NOT NULL,
|
||||
`perms_parts_name` smallint(6) NOT NULL,
|
||||
`perms_parts_description` smallint(6) NOT NULL,
|
||||
`perms_parts_instock` smallint(6) NOT NULL,
|
||||
`perms_parts_mininstock` smallint(6) NOT NULL,
|
||||
`perms_parts_footprint` smallint(6) NOT NULL,
|
||||
`perms_parts_storelocation` smallint(6) NOT NULL,
|
||||
`perms_parts_manufacturer` smallint(6) NOT NULL,
|
||||
`perms_parts_comment` smallint(6) NOT NULL,
|
||||
`perms_parts_order` smallint(6) NOT NULL,
|
||||
`perms_parts_orderdetails` smallint(6) NOT NULL,
|
||||
`perms_parts_prices` smallint(6) NOT NULL,
|
||||
`perms_parts_attachements` smallint(6) NOT NULL,
|
||||
`perms_devices` int(11) NOT NULL,
|
||||
`perms_devices_parts` int(11) NOT NULL,
|
||||
`perms_storelocations` int(11) NOT NULL,
|
||||
`perms_footprints` int(11) NOT NULL,
|
||||
`perms_categories` int(11) NOT NULL,
|
||||
`perms_suppliers` int(11) NOT NULL,
|
||||
`perms_manufacturers` int(11) NOT NULL,
|
||||
`perms_attachement_types` int(11) NOT NULL,
|
||||
`perms_tools` int(11) NOT NULL,
|
||||
`perms_labels` smallint(6) NOT NULL,
|
||||
`datetime_added` timestamp NOT NULL DEFAULT current_timestamp(),
|
||||
`last_modified` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00'
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
|
||||
|
||||
--
|
||||
-- Daten für Tabelle `groups`
|
||||
--
|
||||
|
||||
INSERT INTO `groups` (`id`, `name`, `parent_id`, `comment`, `perms_system`, `perms_groups`, `perms_users`, `perms_self`, `perms_system_config`, `perms_system_database`, `perms_parts`, `perms_parts_name`, `perms_parts_description`, `perms_parts_instock`, `perms_parts_mininstock`, `perms_parts_footprint`, `perms_parts_storelocation`, `perms_parts_manufacturer`, `perms_parts_comment`, `perms_parts_order`, `perms_parts_orderdetails`, `perms_parts_prices`, `perms_parts_attachements`, `perms_devices`, `perms_devices_parts`, `perms_storelocations`, `perms_footprints`, `perms_categories`, `perms_suppliers`, `perms_manufacturers`, `perms_attachement_types`, `perms_tools`, `perms_labels`, `datetime_added`, `last_modified`) VALUES
|
||||
(1, 'admins', NULL, 'Users of this group can do everything: Read, Write and Administrative actions.', 21, 1365, 87381, 85, 85, 21, 1431655765, 5, 5, 5, 5, 5, 5, 5, 5, 5, 325, 325, 325, 5461, 325, 5461, 5461, 5461, 5461, 5461, 1365, 1365, 85, '2017-10-21 17:58:46', '2018-10-08 17:27:41'),
|
||||
(2, 'readonly', NULL, 'Users of this group can only read informations, use tools, and don\'t have access to administrative tools.', 2, 2730, 43690, 25, 170, 42, 2778027689, 9, 9, 9, 9, 9, 9, 9, 9, 9, 649, 649, 649, 1705, 649, 1705, 1705, 1705, 1705, 1705, 681, 1366, 165, '2017-10-21 17:58:46', '2018-10-08 17:28:35'),
|
||||
(3, 'users', NULL, 'Users of this group, can edit part informations, create new ones, etc. but are not allowed to use administrative tools. (But can read current configuration, and see Server status)', 42, 2730, 43689, 89, 105, 41, 1431655765, 5, 5, 5, 5, 5, 5, 5, 5, 5, 325, 325, 325, 5461, 325, 5461, 5461, 5461, 5461, 5461, 1365, 1365, 85, '2017-10-21 17:58:46', '2018-10-08 17:28:17');
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Tabellenstruktur für Tabelle `internal`
|
||||
--
|
||||
|
||||
CREATE TABLE `internal` (
|
||||
`keyName` char(30) CHARACTER SET ascii NOT NULL,
|
||||
`keyValue` varchar(255) COLLATE utf8mb3_unicode_ci DEFAULT NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci;
|
||||
|
||||
--
|
||||
-- Daten für Tabelle `internal`
|
||||
--
|
||||
|
||||
INSERT INTO `internal` (`keyName`, `keyValue`) VALUES
|
||||
('dbVersion', '26');
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Tabellenstruktur für Tabelle `log`
|
||||
--
|
||||
|
||||
CREATE TABLE `log` (
|
||||
`id` int(11) NOT NULL,
|
||||
`datetime` timestamp NOT NULL DEFAULT current_timestamp(),
|
||||
`id_user` int(11) NOT NULL,
|
||||
`level` tinyint(4) NOT NULL,
|
||||
`type` smallint(6) NOT NULL,
|
||||
`target_id` int(11) NOT NULL,
|
||||
`target_type` smallint(6) NOT NULL,
|
||||
`extra` mediumtext NOT NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Tabellenstruktur für Tabelle `manufacturers`
|
||||
--
|
||||
|
||||
CREATE TABLE `manufacturers` (
|
||||
`id` int(11) NOT NULL,
|
||||
`name` tinytext COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||
`parent_id` int(11) DEFAULT NULL,
|
||||
`address` mediumtext COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||
`phone_number` tinytext COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||
`fax_number` tinytext COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||
`email_address` tinytext COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||
`website` tinytext COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||
`auto_product_url` tinytext COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||
`datetime_added` timestamp NOT NULL DEFAULT current_timestamp(),
|
||||
`comment` text COLLATE utf8mb3_unicode_ci DEFAULT NULL,
|
||||
`last_modified` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00'
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci;
|
||||
|
||||
--
|
||||
-- Daten für Tabelle `manufacturers`
|
||||
--
|
||||
|
||||
INSERT INTO `manufacturers` (`id`, `name`, `parent_id`, `address`, `phone_number`, `fax_number`, `email_address`, `website`, `auto_product_url`, `datetime_added`, `comment`, `last_modified`) VALUES
|
||||
(1, 'Atmel', NULL, '', '', '', '', '', '', '2015-03-01 11:27:10', NULL, '0000-00-00 00:00:00');
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Tabellenstruktur für Tabelle `orderdetails`
|
||||
--
|
||||
|
||||
CREATE TABLE `orderdetails` (
|
||||
`id` int(11) NOT NULL,
|
||||
`part_id` int(11) NOT NULL,
|
||||
`id_supplier` int(11) NOT NULL DEFAULT 0,
|
||||
`supplierpartnr` tinytext COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||
`obsolete` tinyint(1) DEFAULT 0,
|
||||
`supplier_product_url` tinytext COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||
`datetime_added` timestamp NOT NULL DEFAULT current_timestamp()
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Tabellenstruktur für Tabelle `parts`
|
||||
--
|
||||
|
||||
CREATE TABLE `parts` (
|
||||
`id` int(11) NOT NULL,
|
||||
`id_category` int(11) NOT NULL DEFAULT 0,
|
||||
`name` mediumtext COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||
`description` mediumtext COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||
`instock` int(11) NOT NULL DEFAULT 0,
|
||||
`mininstock` int(11) NOT NULL DEFAULT 0,
|
||||
`comment` mediumtext COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||
`visible` tinyint(1) NOT NULL,
|
||||
`id_footprint` int(11) DEFAULT NULL,
|
||||
`id_storelocation` int(11) DEFAULT NULL,
|
||||
`order_orderdetails_id` int(11) DEFAULT NULL,
|
||||
`order_quantity` int(11) NOT NULL DEFAULT 1,
|
||||
`manual_order` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`id_manufacturer` int(11) DEFAULT NULL,
|
||||
`id_master_picture_attachement` int(11) DEFAULT NULL,
|
||||
`manufacturer_product_url` tinytext COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||
`datetime_added` timestamp NOT NULL DEFAULT current_timestamp(),
|
||||
`last_modified` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
`favorite` tinyint(1) NOT NULL DEFAULT 0
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci;
|
||||
|
||||
--
|
||||
-- Daten für Tabelle `parts`
|
||||
--
|
||||
|
||||
INSERT INTO `parts` (`id`, `id_category`, `name`, `description`, `instock`, `mininstock`, `comment`, `visible`, `id_footprint`, `id_storelocation`, `order_orderdetails_id`, `order_quantity`, `manual_order`, `id_manufacturer`, `id_master_picture_attachement`, `manufacturer_product_url`, `datetime_added`, `last_modified`, `favorite`) VALUES
|
||||
(2, 1, 'BC547C', 'NPN 45V 0,1A 0,5W', 59, 0, '', 0, 1, 1, NULL, 1, 0, NULL, NULL, '', '2015-03-01 10:40:31', '2016-12-26 10:48:49', 0);
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Tabellenstruktur für Tabelle `pricedetails`
|
||||
--
|
||||
|
||||
CREATE TABLE `pricedetails` (
|
||||
`id` int(11) NOT NULL,
|
||||
`orderdetails_id` int(11) NOT NULL,
|
||||
`price` decimal(11,5) DEFAULT NULL,
|
||||
`price_related_quantity` int(11) NOT NULL DEFAULT 1,
|
||||
`min_discount_quantity` int(11) NOT NULL DEFAULT 1,
|
||||
`manual_input` tinyint(1) NOT NULL DEFAULT 1,
|
||||
`last_modified` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp()
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Tabellenstruktur für Tabelle `storelocations`
|
||||
--
|
||||
|
||||
CREATE TABLE `storelocations` (
|
||||
`id` int(11) NOT NULL,
|
||||
`name` tinytext COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||
`parent_id` int(11) DEFAULT NULL,
|
||||
`is_full` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`datetime_added` timestamp NOT NULL DEFAULT current_timestamp(),
|
||||
`comment` text COLLATE utf8mb3_unicode_ci DEFAULT NULL,
|
||||
`last_modified` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00'
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci;
|
||||
|
||||
--
|
||||
-- Daten für Tabelle `storelocations`
|
||||
--
|
||||
|
||||
INSERT INTO `storelocations` (`id`, `name`, `parent_id`, `is_full`, `datetime_added`, `comment`, `last_modified`) VALUES
|
||||
(1, 'Halbleiter I', NULL, 0, '2015-03-01 11:26:37', NULL, '0000-00-00 00:00:00');
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Tabellenstruktur für Tabelle `suppliers`
|
||||
--
|
||||
|
||||
CREATE TABLE `suppliers` (
|
||||
`id` int(11) NOT NULL,
|
||||
`name` tinytext COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||
`parent_id` int(11) DEFAULT NULL,
|
||||
`address` mediumtext COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||
`phone_number` tinytext COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||
`fax_number` tinytext COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||
`email_address` tinytext COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||
`website` tinytext COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||
`auto_product_url` tinytext COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||
`datetime_added` timestamp NOT NULL DEFAULT current_timestamp(),
|
||||
`comment` text COLLATE utf8mb3_unicode_ci DEFAULT NULL,
|
||||
`last_modified` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00'
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci;
|
||||
|
||||
--
|
||||
-- Daten für Tabelle `suppliers`
|
||||
--
|
||||
|
||||
INSERT INTO `suppliers` (`id`, `name`, `parent_id`, `address`, `phone_number`, `fax_number`, `email_address`, `website`, `auto_product_url`, `datetime_added`, `comment`, `last_modified`) VALUES
|
||||
(1, 'Test', NULL, '', '', '', '', '', 'Test', '2015-03-01 10:37:23', NULL, '0000-00-00 00:00:00');
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Tabellenstruktur für Tabelle `users`
|
||||
--
|
||||
|
||||
CREATE TABLE `users` (
|
||||
`id` int(11) NOT NULL,
|
||||
`name` varchar(32) NOT NULL,
|
||||
`password` varchar(255) DEFAULT NULL,
|
||||
`first_name` tinytext DEFAULT NULL,
|
||||
`last_name` tinytext DEFAULT NULL,
|
||||
`department` tinytext DEFAULT NULL,
|
||||
`email` tinytext DEFAULT NULL,
|
||||
`need_pw_change` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`group_id` int(11) DEFAULT NULL,
|
||||
`config_language` tinytext DEFAULT NULL,
|
||||
`config_timezone` tinytext DEFAULT NULL,
|
||||
`config_theme` tinytext DEFAULT NULL,
|
||||
`config_currency` tinytext DEFAULT NULL,
|
||||
`config_image_path` text NOT NULL,
|
||||
`config_instock_comment_w` text NOT NULL,
|
||||
`config_instock_comment_a` text NOT NULL,
|
||||
`perms_system` int(11) NOT NULL,
|
||||
`perms_groups` int(11) NOT NULL,
|
||||
`perms_users` int(11) NOT NULL,
|
||||
`perms_self` int(11) NOT NULL,
|
||||
`perms_system_config` int(11) NOT NULL,
|
||||
`perms_system_database` int(11) NOT NULL,
|
||||
`perms_parts` bigint(11) NOT NULL,
|
||||
`perms_parts_name` smallint(6) NOT NULL,
|
||||
`perms_parts_description` smallint(6) NOT NULL,
|
||||
`perms_parts_instock` smallint(6) NOT NULL,
|
||||
`perms_parts_mininstock` smallint(6) NOT NULL,
|
||||
`perms_parts_footprint` smallint(6) NOT NULL,
|
||||
`perms_parts_storelocation` smallint(6) NOT NULL,
|
||||
`perms_parts_manufacturer` smallint(6) NOT NULL,
|
||||
`perms_parts_comment` smallint(6) NOT NULL,
|
||||
`perms_parts_order` smallint(6) NOT NULL,
|
||||
`perms_parts_orderdetails` smallint(6) NOT NULL,
|
||||
`perms_parts_prices` smallint(6) NOT NULL,
|
||||
`perms_parts_attachements` smallint(6) NOT NULL,
|
||||
`perms_devices` int(11) NOT NULL,
|
||||
`perms_devices_parts` int(11) NOT NULL,
|
||||
`perms_storelocations` int(11) NOT NULL,
|
||||
`perms_footprints` int(11) NOT NULL,
|
||||
`perms_categories` int(11) NOT NULL,
|
||||
`perms_suppliers` int(11) NOT NULL,
|
||||
`perms_manufacturers` int(11) NOT NULL,
|
||||
`perms_attachement_types` int(11) NOT NULL,
|
||||
`perms_tools` int(11) NOT NULL,
|
||||
`perms_labels` smallint(6) NOT NULL,
|
||||
`datetime_added` timestamp NOT NULL DEFAULT current_timestamp(),
|
||||
`last_modified` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00'
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
|
||||
|
||||
--
|
||||
-- Daten für Tabelle `users`
|
||||
--
|
||||
|
||||
INSERT INTO `users` (`id`, `name`, `password`, `first_name`, `last_name`, `department`, `email`, `need_pw_change`, `group_id`, `config_language`, `config_timezone`, `config_theme`, `config_currency`, `config_image_path`, `config_instock_comment_w`, `config_instock_comment_a`, `perms_system`, `perms_groups`, `perms_users`, `perms_self`, `perms_system_config`, `perms_system_database`, `perms_parts`, `perms_parts_name`, `perms_parts_description`, `perms_parts_instock`, `perms_parts_mininstock`, `perms_parts_footprint`, `perms_parts_storelocation`, `perms_parts_manufacturer`, `perms_parts_comment`, `perms_parts_order`, `perms_parts_orderdetails`, `perms_parts_prices`, `perms_parts_attachements`, `perms_devices`, `perms_devices_parts`, `perms_storelocations`, `perms_footprints`, `perms_categories`, `perms_suppliers`, `perms_manufacturers`, `perms_attachement_types`, `perms_tools`, `perms_labels`, `datetime_added`, `last_modified`) VALUES
|
||||
(1, 'anonymous', '', '', '', '', '', 0, 2, '', '', '', NULL, '', '', '', 21848, 20480, 0, 0, 0, 0, 0, 21840, 21840, 21840, 21840, 21840, 21840, 21840, 21840, 21840, 21520, 21520, 21520, 20480, 21520, 20480, 20480, 20480, 20480, 20480, 21504, 20480, 0, '2017-10-21 17:58:46', '2018-02-18 12:46:58'),
|
||||
(2, 'admin', '$2a$12$j0RKrKlx60bzX1DWMyXwjeaW.pe3bFjAK8ByIGnvjrRnET2JtsFoe', 'Admin', 'Ad', NULL, 'admin@ras.pi', 0, 1, '', '', '', NULL, '', '', '', 21845, 21845, 21845, 21, 85, 21, 349525, 21845, 21845, 21845, 21845, 21845, 21845, 21845, 21845, 21845, 21845, 21845, 21845, 21845, 21845, 21845, 21845, 21845, 21845, 21845, 21845, 21845, 0, '2017-10-21 17:58:46', '2017-12-23 11:04:48');
|
||||
|
||||
--
|
||||
-- Indizes der exportierten Tabellen
|
||||
--
|
||||
|
||||
--
|
||||
-- Indizes für die Tabelle `attachements`
|
||||
--
|
||||
ALTER TABLE `attachements`
|
||||
ADD PRIMARY KEY (`id`),
|
||||
ADD KEY `attachements_class_name_k` (`class_name`),
|
||||
ADD KEY `attachements_element_id_k` (`element_id`),
|
||||
ADD KEY `attachements_type_id_fk` (`type_id`);
|
||||
|
||||
--
|
||||
-- Indizes für die Tabelle `attachement_types`
|
||||
--
|
||||
ALTER TABLE `attachement_types`
|
||||
ADD PRIMARY KEY (`id`),
|
||||
ADD KEY `attachement_types_parent_id_k` (`parent_id`);
|
||||
|
||||
--
|
||||
-- Indizes für die Tabelle `categories`
|
||||
--
|
||||
ALTER TABLE `categories`
|
||||
ADD PRIMARY KEY (`id`),
|
||||
ADD KEY `categories_parent_id_k` (`parent_id`);
|
||||
|
||||
--
|
||||
-- Indizes für die Tabelle `devices`
|
||||
--
|
||||
ALTER TABLE `devices`
|
||||
ADD PRIMARY KEY (`id`),
|
||||
ADD KEY `devices_parent_id_k` (`parent_id`);
|
||||
|
||||
--
|
||||
-- Indizes für die Tabelle `device_parts`
|
||||
--
|
||||
ALTER TABLE `device_parts`
|
||||
ADD PRIMARY KEY (`id`),
|
||||
ADD UNIQUE KEY `device_parts_combination_uk` (`id_part`,`id_device`),
|
||||
ADD KEY `device_parts_id_part_k` (`id_part`),
|
||||
ADD KEY `device_parts_id_device_k` (`id_device`);
|
||||
|
||||
--
|
||||
-- Indizes für die Tabelle `footprints`
|
||||
--
|
||||
ALTER TABLE `footprints`
|
||||
ADD PRIMARY KEY (`id`),
|
||||
ADD KEY `footprints_parent_id_k` (`parent_id`);
|
||||
|
||||
--
|
||||
-- Indizes für die Tabelle `groups`
|
||||
--
|
||||
ALTER TABLE `groups`
|
||||
ADD PRIMARY KEY (`id`),
|
||||
ADD UNIQUE KEY `name` (`name`);
|
||||
|
||||
--
|
||||
-- Indizes für die Tabelle `internal`
|
||||
--
|
||||
ALTER TABLE `internal`
|
||||
ADD UNIQUE KEY `keyName` (`keyName`);
|
||||
|
||||
--
|
||||
-- Indizes für die Tabelle `log`
|
||||
--
|
||||
ALTER TABLE `log`
|
||||
ADD PRIMARY KEY (`id`),
|
||||
ADD KEY `id_user` (`id_user`);
|
||||
|
||||
--
|
||||
-- Indizes für die Tabelle `manufacturers`
|
||||
--
|
||||
ALTER TABLE `manufacturers`
|
||||
ADD PRIMARY KEY (`id`),
|
||||
ADD KEY `manufacturers_parent_id_k` (`parent_id`);
|
||||
|
||||
--
|
||||
-- Indizes für die Tabelle `orderdetails`
|
||||
--
|
||||
ALTER TABLE `orderdetails`
|
||||
ADD PRIMARY KEY (`id`),
|
||||
ADD KEY `orderdetails_part_id_k` (`part_id`),
|
||||
ADD KEY `orderdetails_id_supplier_k` (`id_supplier`);
|
||||
|
||||
--
|
||||
-- Indizes für die Tabelle `parts`
|
||||
--
|
||||
ALTER TABLE `parts`
|
||||
ADD PRIMARY KEY (`id`),
|
||||
ADD KEY `parts_id_category_k` (`id_category`),
|
||||
ADD KEY `parts_id_footprint_k` (`id_footprint`),
|
||||
ADD KEY `parts_id_storelocation_k` (`id_storelocation`),
|
||||
ADD KEY `parts_order_orderdetails_id_k` (`order_orderdetails_id`),
|
||||
ADD KEY `parts_id_manufacturer_k` (`id_manufacturer`),
|
||||
ADD KEY `favorite` (`favorite`);
|
||||
|
||||
--
|
||||
-- Indizes für die Tabelle `pricedetails`
|
||||
--
|
||||
ALTER TABLE `pricedetails`
|
||||
ADD PRIMARY KEY (`id`),
|
||||
ADD UNIQUE KEY `pricedetails_combination_uk` (`orderdetails_id`,`min_discount_quantity`),
|
||||
ADD KEY `pricedetails_orderdetails_id_k` (`orderdetails_id`);
|
||||
|
||||
--
|
||||
-- Indizes für die Tabelle `storelocations`
|
||||
--
|
||||
ALTER TABLE `storelocations`
|
||||
ADD PRIMARY KEY (`id`),
|
||||
ADD KEY `storelocations_parent_id_k` (`parent_id`);
|
||||
|
||||
--
|
||||
-- Indizes für die Tabelle `suppliers`
|
||||
--
|
||||
ALTER TABLE `suppliers`
|
||||
ADD PRIMARY KEY (`id`),
|
||||
ADD KEY `suppliers_parent_id_k` (`parent_id`);
|
||||
|
||||
--
|
||||
-- Indizes für die Tabelle `users`
|
||||
--
|
||||
ALTER TABLE `users`
|
||||
ADD PRIMARY KEY (`id`),
|
||||
ADD UNIQUE KEY `name` (`name`);
|
||||
|
||||
--
|
||||
-- AUTO_INCREMENT für exportierte Tabellen
|
||||
--
|
||||
|
||||
--
|
||||
-- AUTO_INCREMENT für Tabelle `attachements`
|
||||
--
|
||||
ALTER TABLE `attachements`
|
||||
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=201;
|
||||
|
||||
--
|
||||
-- AUTO_INCREMENT für Tabelle `attachement_types`
|
||||
--
|
||||
ALTER TABLE `attachement_types`
|
||||
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=3;
|
||||
|
||||
--
|
||||
-- AUTO_INCREMENT für Tabelle `categories`
|
||||
--
|
||||
ALTER TABLE `categories`
|
||||
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=123;
|
||||
|
||||
--
|
||||
-- AUTO_INCREMENT für Tabelle `devices`
|
||||
--
|
||||
ALTER TABLE `devices`
|
||||
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=2;
|
||||
|
||||
--
|
||||
-- AUTO_INCREMENT für Tabelle `device_parts`
|
||||
--
|
||||
ALTER TABLE `device_parts`
|
||||
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=12;
|
||||
|
||||
--
|
||||
-- AUTO_INCREMENT für Tabelle `footprints`
|
||||
--
|
||||
ALTER TABLE `footprints`
|
||||
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=82;
|
||||
|
||||
--
|
||||
-- AUTO_INCREMENT für Tabelle `groups`
|
||||
--
|
||||
ALTER TABLE `groups`
|
||||
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=4;
|
||||
|
||||
--
|
||||
-- AUTO_INCREMENT für Tabelle `log`
|
||||
--
|
||||
ALTER TABLE `log`
|
||||
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=218;
|
||||
|
||||
--
|
||||
-- AUTO_INCREMENT für Tabelle `manufacturers`
|
||||
--
|
||||
ALTER TABLE `manufacturers`
|
||||
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=2;
|
||||
|
||||
--
|
||||
-- AUTO_INCREMENT für Tabelle `orderdetails`
|
||||
--
|
||||
ALTER TABLE `orderdetails`
|
||||
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=650;
|
||||
|
||||
--
|
||||
-- AUTO_INCREMENT für Tabelle `parts`
|
||||
--
|
||||
ALTER TABLE `parts`
|
||||
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=1171;
|
||||
|
||||
--
|
||||
-- AUTO_INCREMENT für Tabelle `pricedetails`
|
||||
--
|
||||
ALTER TABLE `pricedetails`
|
||||
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=437;
|
||||
|
||||
--
|
||||
-- AUTO_INCREMENT für Tabelle `storelocations`
|
||||
--
|
||||
ALTER TABLE `storelocations`
|
||||
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=340;
|
||||
|
||||
--
|
||||
-- AUTO_INCREMENT für Tabelle `suppliers`
|
||||
--
|
||||
ALTER TABLE `suppliers`
|
||||
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=5;
|
||||
|
||||
--
|
||||
-- AUTO_INCREMENT für Tabelle `users`
|
||||
--
|
||||
ALTER TABLE `users`
|
||||
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=6;
|
||||
|
||||
--
|
||||
-- Constraints der exportierten Tabellen
|
||||
--
|
||||
|
||||
--
|
||||
-- Constraints der Tabelle `attachements`
|
||||
--
|
||||
ALTER TABLE `attachements`
|
||||
ADD CONSTRAINT `attachements_type_id_fk` FOREIGN KEY (`type_id`) REFERENCES `attachement_types` (`id`);
|
||||
|
||||
--
|
||||
-- Constraints der Tabelle `attachement_types`
|
||||
--
|
||||
ALTER TABLE `attachement_types`
|
||||
ADD CONSTRAINT `attachement_types_parent_id_fk` FOREIGN KEY (`parent_id`) REFERENCES `attachement_types` (`id`);
|
||||
|
||||
--
|
||||
-- Constraints der Tabelle `categories`
|
||||
--
|
||||
ALTER TABLE `categories`
|
||||
ADD CONSTRAINT `categories_parent_id_fk` FOREIGN KEY (`parent_id`) REFERENCES `categories` (`id`);
|
||||
|
||||
--
|
||||
-- Constraints der Tabelle `devices`
|
||||
--
|
||||
ALTER TABLE `devices`
|
||||
ADD CONSTRAINT `devices_parent_id_fk` FOREIGN KEY (`parent_id`) REFERENCES `devices` (`id`);
|
||||
|
||||
--
|
||||
-- Constraints der Tabelle `footprints`
|
||||
--
|
||||
ALTER TABLE `footprints`
|
||||
ADD CONSTRAINT `footprints_parent_id_fk` FOREIGN KEY (`parent_id`) REFERENCES `footprints` (`id`);
|
||||
|
||||
--
|
||||
-- Constraints der Tabelle `manufacturers`
|
||||
--
|
||||
ALTER TABLE `manufacturers`
|
||||
ADD CONSTRAINT `manufacturers_parent_id_fk` FOREIGN KEY (`parent_id`) REFERENCES `manufacturers` (`id`);
|
||||
|
||||
--
|
||||
-- Constraints der Tabelle `parts`
|
||||
--
|
||||
ALTER TABLE `parts`
|
||||
ADD CONSTRAINT `parts_id_footprint_fk` FOREIGN KEY (`id_footprint`) REFERENCES `footprints` (`id`),
|
||||
ADD CONSTRAINT `parts_id_manufacturer_fk` FOREIGN KEY (`id_manufacturer`) REFERENCES `manufacturers` (`id`),
|
||||
ADD CONSTRAINT `parts_id_storelocation_fk` FOREIGN KEY (`id_storelocation`) REFERENCES `storelocations` (`id`),
|
||||
ADD CONSTRAINT `parts_order_orderdetails_id_fk` FOREIGN KEY (`order_orderdetails_id`) REFERENCES `orderdetails` (`id`);
|
||||
|
||||
--
|
||||
-- Constraints der Tabelle `storelocations`
|
||||
--
|
||||
ALTER TABLE `storelocations`
|
||||
ADD CONSTRAINT `storelocations_parent_id_fk` FOREIGN KEY (`parent_id`) REFERENCES `storelocations` (`id`);
|
||||
|
||||
--
|
||||
-- Constraints der Tabelle `suppliers`
|
||||
--
|
||||
ALTER TABLE `suppliers`
|
||||
ADD CONSTRAINT `suppliers_parent_id_fk` FOREIGN KEY (`parent_id`) REFERENCES `suppliers` (`id`);
|
||||
COMMIT;
|
||||
|
||||
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
|
||||
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
|
||||
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
|
||||
736
.github/assets/legacy_import/db_minimal.sql
vendored
Normal file
736
.github/assets/legacy_import/db_minimal.sql
vendored
Normal file
@@ -0,0 +1,736 @@
|
||||
-- phpMyAdmin SQL Dump
|
||||
-- version 5.1.3
|
||||
-- https://www.phpmyadmin.net/
|
||||
--
|
||||
-- Host: 127.0.0.1
|
||||
-- Erstellungszeit: 07. Mai 2023 um 01:48
|
||||
-- Server-Version: 10.6.5-MariaDB-log
|
||||
-- PHP-Version: 8.1.2
|
||||
|
||||
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
|
||||
START TRANSACTION;
|
||||
SET time_zone = "+00:00";
|
||||
|
||||
|
||||
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
|
||||
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
|
||||
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
|
||||
/*!40101 SET NAMES utf8mb4 */;
|
||||
|
||||
--
|
||||
-- Datenbank: `partdb-legacy`
|
||||
--
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Tabellenstruktur für Tabelle `attachements`
|
||||
--
|
||||
|
||||
CREATE TABLE `attachements` (
|
||||
`id` int(11) NOT NULL,
|
||||
`name` tinytext COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||
`class_name` varchar(255) COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||
`element_id` int(11) NOT NULL,
|
||||
`type_id` int(11) NOT NULL,
|
||||
`filename` mediumtext COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||
`show_in_table` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`last_modified` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00'
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Tabellenstruktur für Tabelle `attachement_types`
|
||||
--
|
||||
|
||||
CREATE TABLE `attachement_types` (
|
||||
`id` int(11) NOT NULL,
|
||||
`name` tinytext COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||
`parent_id` int(11) DEFAULT NULL,
|
||||
`comment` text COLLATE utf8mb3_unicode_ci DEFAULT NULL,
|
||||
`datetime_added` timestamp NOT NULL DEFAULT current_timestamp(),
|
||||
`last_modified` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00'
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci;
|
||||
|
||||
--
|
||||
-- Daten für Tabelle `attachement_types`
|
||||
--
|
||||
|
||||
INSERT INTO `attachement_types` (`id`, `name`, `parent_id`, `comment`, `datetime_added`, `last_modified`) VALUES
|
||||
(1, 'Bilder', NULL, NULL, '2023-01-07 18:31:48', '0000-00-00 00:00:00'),
|
||||
(2, 'Datenblätter', NULL, NULL, '2023-01-07 18:31:48', '0000-00-00 00:00:00');
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Tabellenstruktur für Tabelle `categories`
|
||||
--
|
||||
|
||||
CREATE TABLE `categories` (
|
||||
`id` int(11) NOT NULL,
|
||||
`name` tinytext COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||
`parent_id` int(11) DEFAULT NULL,
|
||||
`disable_footprints` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`disable_manufacturers` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`disable_autodatasheets` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`disable_properties` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`partname_regex` text COLLATE utf8mb3_unicode_ci NOT NULL DEFAULT '',
|
||||
`partname_hint` text COLLATE utf8mb3_unicode_ci NOT NULL DEFAULT '',
|
||||
`default_description` text COLLATE utf8mb3_unicode_ci NOT NULL DEFAULT '',
|
||||
`default_comment` text COLLATE utf8mb3_unicode_ci NOT NULL DEFAULT '',
|
||||
`comment` text COLLATE utf8mb3_unicode_ci DEFAULT NULL,
|
||||
`datetime_added` timestamp NOT NULL DEFAULT current_timestamp(),
|
||||
`last_modified` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00'
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci;
|
||||
|
||||
--
|
||||
-- Daten für Tabelle `categories`
|
||||
--
|
||||
|
||||
INSERT INTO `categories` (`id`, `name`, `parent_id`, `disable_footprints`, `disable_manufacturers`, `disable_autodatasheets`, `disable_properties`, `partname_regex`, `partname_hint`, `default_description`, `default_comment`, `comment`, `datetime_added`, `last_modified`) VALUES
|
||||
(1, 'Test', NULL, 0, 0, 0, 0, '', '', '', '', '', '2023-01-07 18:32:29', '2023-01-07 18:32:29');
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Tabellenstruktur für Tabelle `devices`
|
||||
--
|
||||
|
||||
CREATE TABLE `devices` (
|
||||
`id` int(11) NOT NULL,
|
||||
`name` tinytext COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||
`parent_id` int(11) DEFAULT NULL,
|
||||
`order_quantity` int(11) NOT NULL DEFAULT 0,
|
||||
`order_only_missing_parts` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`datetime_added` timestamp NOT NULL DEFAULT current_timestamp(),
|
||||
`last_modified` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
`comment` text COLLATE utf8mb3_unicode_ci DEFAULT NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Tabellenstruktur für Tabelle `device_parts`
|
||||
--
|
||||
|
||||
CREATE TABLE `device_parts` (
|
||||
`id` int(11) NOT NULL,
|
||||
`id_part` int(11) NOT NULL DEFAULT 0,
|
||||
`id_device` int(11) NOT NULL DEFAULT 0,
|
||||
`quantity` int(11) NOT NULL DEFAULT 0,
|
||||
`mountnames` mediumtext COLLATE utf8mb3_unicode_ci NOT NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Tabellenstruktur für Tabelle `footprints`
|
||||
--
|
||||
|
||||
CREATE TABLE `footprints` (
|
||||
`id` int(11) NOT NULL,
|
||||
`name` tinytext COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||
`filename` mediumtext COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||
`filename_3d` mediumtext COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||
`parent_id` int(11) DEFAULT NULL,
|
||||
`comment` text COLLATE utf8mb3_unicode_ci DEFAULT NULL,
|
||||
`datetime_added` timestamp NOT NULL DEFAULT current_timestamp(),
|
||||
`last_modified` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00'
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Tabellenstruktur für Tabelle `groups`
|
||||
--
|
||||
|
||||
CREATE TABLE `groups` (
|
||||
`id` int(11) NOT NULL,
|
||||
`name` varchar(32) NOT NULL,
|
||||
`parent_id` int(11) DEFAULT NULL,
|
||||
`comment` mediumtext DEFAULT NULL,
|
||||
`perms_system` int(11) NOT NULL,
|
||||
`perms_groups` int(11) NOT NULL,
|
||||
`perms_users` int(11) NOT NULL,
|
||||
`perms_self` int(11) NOT NULL,
|
||||
`perms_system_config` int(11) NOT NULL,
|
||||
`perms_system_database` int(11) NOT NULL,
|
||||
`perms_parts` bigint(11) NOT NULL,
|
||||
`perms_parts_name` smallint(6) NOT NULL,
|
||||
`perms_parts_description` smallint(6) NOT NULL,
|
||||
`perms_parts_instock` smallint(6) NOT NULL,
|
||||
`perms_parts_mininstock` smallint(6) NOT NULL,
|
||||
`perms_parts_footprint` smallint(6) NOT NULL,
|
||||
`perms_parts_storelocation` smallint(6) NOT NULL,
|
||||
`perms_parts_manufacturer` smallint(6) NOT NULL,
|
||||
`perms_parts_comment` smallint(6) NOT NULL,
|
||||
`perms_parts_order` smallint(6) NOT NULL,
|
||||
`perms_parts_orderdetails` smallint(6) NOT NULL,
|
||||
`perms_parts_prices` smallint(6) NOT NULL,
|
||||
`perms_parts_attachements` smallint(6) NOT NULL,
|
||||
`perms_devices` int(11) NOT NULL,
|
||||
`perms_devices_parts` int(11) NOT NULL,
|
||||
`perms_storelocations` int(11) NOT NULL,
|
||||
`perms_footprints` int(11) NOT NULL,
|
||||
`perms_categories` int(11) NOT NULL,
|
||||
`perms_suppliers` int(11) NOT NULL,
|
||||
`perms_manufacturers` int(11) NOT NULL,
|
||||
`perms_attachement_types` int(11) NOT NULL,
|
||||
`perms_tools` int(11) NOT NULL,
|
||||
`perms_labels` smallint(6) NOT NULL,
|
||||
`datetime_added` timestamp NOT NULL DEFAULT current_timestamp(),
|
||||
`last_modified` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00'
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
|
||||
--
|
||||
-- Daten für Tabelle `groups`
|
||||
--
|
||||
|
||||
INSERT INTO `groups` (`id`, `name`, `parent_id`, `comment`, `perms_system`, `perms_groups`, `perms_users`, `perms_self`, `perms_system_config`, `perms_system_database`, `perms_parts`, `perms_parts_name`, `perms_parts_description`, `perms_parts_instock`, `perms_parts_mininstock`, `perms_parts_footprint`, `perms_parts_storelocation`, `perms_parts_manufacturer`, `perms_parts_comment`, `perms_parts_order`, `perms_parts_orderdetails`, `perms_parts_prices`, `perms_parts_attachements`, `perms_devices`, `perms_devices_parts`, `perms_storelocations`, `perms_footprints`, `perms_categories`, `perms_suppliers`, `perms_manufacturers`, `perms_attachement_types`, `perms_tools`, `perms_labels`, `datetime_added`, `last_modified`) VALUES
|
||||
(1, 'admins', NULL, 'Users of this group can do everything: Read, Write and Administrative actions.', 21, 1365, 87381, 85, 85, 21, 1431655765, 5, 5, 5, 5, 5, 5, 5, 5, 5, 325, 325, 325, 5461, 325, 5461, 5461, 5461, 5461, 5461, 1365, 1365, 85, '2023-01-07 18:31:48', '0000-00-00 00:00:00'),
|
||||
(2, 'readonly', NULL, 'Users of this group can only read informations, use tools, and don\'t have access to administrative tools.', 42, 2730, 174762, 154, 170, 42, -1516939607, 9, 9, 9, 9, 9, 9, 9, 9, 9, 649, 649, 649, 1705, 649, 1705, 1705, 1705, 1705, 1705, 681, 1366, 165, '2023-01-07 18:31:48', '0000-00-00 00:00:00'),
|
||||
(3, 'users', NULL, 'Users of this group, can edit part informations, create new ones, etc. but are not allowed to use administrative tools. (But can read current configuration, and see Server status)', 42, 2730, 109226, 89, 105, 41, 1431655765, 5, 5, 5, 5, 5, 5, 5, 5, 5, 325, 325, 325, 5461, 325, 5461, 5461, 5461, 5461, 5461, 1365, 1365, 85, '2023-01-07 18:31:48', '0000-00-00 00:00:00');
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Tabellenstruktur für Tabelle `internal`
|
||||
--
|
||||
|
||||
CREATE TABLE `internal` (
|
||||
`keyName` char(30) CHARACTER SET ascii NOT NULL,
|
||||
`keyValue` varchar(255) COLLATE utf8mb3_unicode_ci DEFAULT NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci;
|
||||
|
||||
--
|
||||
-- Daten für Tabelle `internal`
|
||||
--
|
||||
|
||||
INSERT INTO `internal` (`keyName`, `keyValue`) VALUES
|
||||
('dbVersion', '26');
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Tabellenstruktur für Tabelle `log`
|
||||
--
|
||||
|
||||
CREATE TABLE `log` (
|
||||
`id` int(11) NOT NULL,
|
||||
`datetime` timestamp NOT NULL DEFAULT current_timestamp(),
|
||||
`id_user` int(11) NOT NULL,
|
||||
`level` tinyint(4) NOT NULL,
|
||||
`type` smallint(6) NOT NULL,
|
||||
`target_id` int(11) NOT NULL,
|
||||
`target_type` smallint(6) NOT NULL,
|
||||
`extra` mediumtext NOT NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
|
||||
--
|
||||
-- Daten für Tabelle `log`
|
||||
--
|
||||
|
||||
INSERT INTO `log` (`id`, `datetime`, `id_user`, `level`, `type`, `target_id`, `target_type`, `extra`) VALUES
|
||||
(1, '2023-01-07 18:31:48', 1, 4, 10, 0, 0, '{\"o\":0,\"n\":26,\"s\":true}'),
|
||||
(2, '2023-01-07 18:32:13', 2, 6, 1, 2, 1, '{\"i\":\"::\"}'),
|
||||
(3, '2023-01-07 18:32:29', 2, 6, 6, 1, 4, '[]'),
|
||||
(4, '2023-01-07 18:32:53', 2, 6, 6, 1, 12, '[]'),
|
||||
(5, '2023-01-07 18:33:26', 2, 6, 6, 1, 10, '{\"i\":0}');
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Tabellenstruktur für Tabelle `manufacturers`
|
||||
--
|
||||
|
||||
CREATE TABLE `manufacturers` (
|
||||
`id` int(11) NOT NULL,
|
||||
`name` tinytext COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||
`parent_id` int(11) DEFAULT NULL,
|
||||
`address` mediumtext COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||
`phone_number` tinytext COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||
`fax_number` tinytext COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||
`email_address` tinytext COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||
`website` tinytext COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||
`auto_product_url` tinytext COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||
`datetime_added` timestamp NOT NULL DEFAULT current_timestamp(),
|
||||
`comment` text COLLATE utf8mb3_unicode_ci DEFAULT NULL,
|
||||
`last_modified` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00'
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Tabellenstruktur für Tabelle `orderdetails`
|
||||
--
|
||||
|
||||
CREATE TABLE `orderdetails` (
|
||||
`id` int(11) NOT NULL,
|
||||
`part_id` int(11) NOT NULL,
|
||||
`id_supplier` int(11) NOT NULL DEFAULT 0,
|
||||
`supplierpartnr` tinytext COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||
`obsolete` tinyint(1) DEFAULT 0,
|
||||
`supplier_product_url` tinytext COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||
`datetime_added` timestamp NOT NULL DEFAULT current_timestamp()
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci;
|
||||
|
||||
--
|
||||
-- Daten für Tabelle `orderdetails`
|
||||
--
|
||||
|
||||
INSERT INTO `orderdetails` (`id`, `part_id`, `id_supplier`, `supplierpartnr`, `obsolete`, `supplier_product_url`, `datetime_added`) VALUES
|
||||
(1, 1, 1, 'BC547', 0, '', '2023-01-07 18:45:59'),
|
||||
(2, 1, 1, 'Test', 0, '', '2023-01-07 18:46:09');
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Tabellenstruktur für Tabelle `parts`
|
||||
--
|
||||
|
||||
CREATE TABLE `parts` (
|
||||
`id` int(11) NOT NULL,
|
||||
`id_category` int(11) NOT NULL DEFAULT 0,
|
||||
`name` mediumtext COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||
`description` mediumtext COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||
`instock` int(11) NOT NULL DEFAULT 0,
|
||||
`mininstock` int(11) NOT NULL DEFAULT 0,
|
||||
`comment` mediumtext COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||
`visible` tinyint(1) NOT NULL,
|
||||
`id_footprint` int(11) DEFAULT NULL,
|
||||
`id_storelocation` int(11) DEFAULT NULL,
|
||||
`order_orderdetails_id` int(11) DEFAULT NULL,
|
||||
`order_quantity` int(11) NOT NULL DEFAULT 1,
|
||||
`manual_order` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`id_manufacturer` int(11) DEFAULT NULL,
|
||||
`id_master_picture_attachement` int(11) DEFAULT NULL,
|
||||
`manufacturer_product_url` tinytext COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||
`datetime_added` timestamp NOT NULL DEFAULT current_timestamp(),
|
||||
`last_modified` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
`favorite` tinyint(1) NOT NULL DEFAULT 0
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci;
|
||||
|
||||
--
|
||||
-- Daten für Tabelle `parts`
|
||||
--
|
||||
|
||||
INSERT INTO `parts` (`id`, `id_category`, `name`, `description`, `instock`, `mininstock`, `comment`, `visible`, `id_footprint`, `id_storelocation`, `order_orderdetails_id`, `order_quantity`, `manual_order`, `id_manufacturer`, `id_master_picture_attachement`, `manufacturer_product_url`, `datetime_added`, `last_modified`, `favorite`) VALUES
|
||||
(1, 1, 'BC547', '', 0, 0, '', 0, NULL, NULL, NULL, 1, 0, NULL, NULL, '', '2023-01-07 18:33:26', '2023-01-07 18:33:26', 0);
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Tabellenstruktur für Tabelle `pricedetails`
|
||||
--
|
||||
|
||||
CREATE TABLE `pricedetails` (
|
||||
`id` int(11) NOT NULL,
|
||||
`orderdetails_id` int(11) NOT NULL,
|
||||
`price` decimal(11,5) DEFAULT NULL,
|
||||
`price_related_quantity` int(11) NOT NULL DEFAULT 1,
|
||||
`min_discount_quantity` int(11) NOT NULL DEFAULT 1,
|
||||
`manual_input` tinyint(1) NOT NULL DEFAULT 1,
|
||||
`last_modified` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp()
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci;
|
||||
|
||||
--
|
||||
-- Daten für Tabelle `pricedetails`
|
||||
--
|
||||
|
||||
INSERT INTO `pricedetails` (`id`, `orderdetails_id`, `price`, `price_related_quantity`, `min_discount_quantity`, `manual_input`, `last_modified`) VALUES
|
||||
(1, 2, '3.55000', 1, 1, 1, '2023-01-07 18:46:19');
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Tabellenstruktur für Tabelle `storelocations`
|
||||
--
|
||||
|
||||
CREATE TABLE `storelocations` (
|
||||
`id` int(11) NOT NULL,
|
||||
`name` tinytext COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||
`parent_id` int(11) DEFAULT NULL,
|
||||
`is_full` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`datetime_added` timestamp NOT NULL DEFAULT current_timestamp(),
|
||||
`comment` text COLLATE utf8mb3_unicode_ci DEFAULT NULL,
|
||||
`last_modified` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00'
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Tabellenstruktur für Tabelle `suppliers`
|
||||
--
|
||||
|
||||
CREATE TABLE `suppliers` (
|
||||
`id` int(11) NOT NULL,
|
||||
`name` tinytext COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||
`parent_id` int(11) DEFAULT NULL,
|
||||
`address` mediumtext COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||
`phone_number` tinytext COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||
`fax_number` tinytext COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||
`email_address` tinytext COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||
`website` tinytext COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||
`auto_product_url` tinytext COLLATE utf8mb3_unicode_ci NOT NULL,
|
||||
`datetime_added` timestamp NOT NULL DEFAULT current_timestamp(),
|
||||
`comment` text COLLATE utf8mb3_unicode_ci DEFAULT NULL,
|
||||
`last_modified` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00'
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci;
|
||||
|
||||
--
|
||||
-- Daten für Tabelle `suppliers`
|
||||
--
|
||||
|
||||
INSERT INTO `suppliers` (`id`, `name`, `parent_id`, `address`, `phone_number`, `fax_number`, `email_address`, `website`, `auto_product_url`, `datetime_added`, `comment`, `last_modified`) VALUES
|
||||
(1, 'Reichelt', NULL, '', '', '', '', '', '', '2023-01-07 18:32:53', '', '2023-01-07 18:32:53');
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Tabellenstruktur für Tabelle `users`
|
||||
--
|
||||
|
||||
CREATE TABLE `users` (
|
||||
`id` int(11) NOT NULL,
|
||||
`name` varchar(32) NOT NULL,
|
||||
`password` varchar(255) DEFAULT NULL,
|
||||
`first_name` tinytext DEFAULT NULL,
|
||||
`last_name` tinytext DEFAULT NULL,
|
||||
`department` tinytext DEFAULT NULL,
|
||||
`email` tinytext DEFAULT NULL,
|
||||
`need_pw_change` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`group_id` int(11) DEFAULT NULL,
|
||||
`config_language` tinytext DEFAULT NULL,
|
||||
`config_timezone` tinytext DEFAULT NULL,
|
||||
`config_theme` tinytext DEFAULT NULL,
|
||||
`config_currency` tinytext DEFAULT NULL,
|
||||
`config_image_path` text NOT NULL,
|
||||
`config_instock_comment_w` text NOT NULL,
|
||||
`config_instock_comment_a` text NOT NULL,
|
||||
`perms_system` int(11) NOT NULL,
|
||||
`perms_groups` int(11) NOT NULL,
|
||||
`perms_users` int(11) NOT NULL,
|
||||
`perms_self` int(11) NOT NULL,
|
||||
`perms_system_config` int(11) NOT NULL,
|
||||
`perms_system_database` int(11) NOT NULL,
|
||||
`perms_parts` bigint(11) NOT NULL,
|
||||
`perms_parts_name` smallint(6) NOT NULL,
|
||||
`perms_parts_description` smallint(6) NOT NULL,
|
||||
`perms_parts_instock` smallint(6) NOT NULL,
|
||||
`perms_parts_mininstock` smallint(6) NOT NULL,
|
||||
`perms_parts_footprint` smallint(6) NOT NULL,
|
||||
`perms_parts_storelocation` smallint(6) NOT NULL,
|
||||
`perms_parts_manufacturer` smallint(6) NOT NULL,
|
||||
`perms_parts_comment` smallint(6) NOT NULL,
|
||||
`perms_parts_order` smallint(6) NOT NULL,
|
||||
`perms_parts_orderdetails` smallint(6) NOT NULL,
|
||||
`perms_parts_prices` smallint(6) NOT NULL,
|
||||
`perms_parts_attachements` smallint(6) NOT NULL,
|
||||
`perms_devices` int(11) NOT NULL,
|
||||
`perms_devices_parts` int(11) NOT NULL,
|
||||
`perms_storelocations` int(11) NOT NULL,
|
||||
`perms_footprints` int(11) NOT NULL,
|
||||
`perms_categories` int(11) NOT NULL,
|
||||
`perms_suppliers` int(11) NOT NULL,
|
||||
`perms_manufacturers` int(11) NOT NULL,
|
||||
`perms_attachement_types` int(11) NOT NULL,
|
||||
`perms_tools` int(11) NOT NULL,
|
||||
`perms_labels` smallint(6) NOT NULL,
|
||||
`datetime_added` timestamp NOT NULL DEFAULT current_timestamp(),
|
||||
`last_modified` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00'
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
|
||||
--
|
||||
-- Daten für Tabelle `users`
|
||||
--
|
||||
|
||||
INSERT INTO `users` (`id`, `name`, `password`, `first_name`, `last_name`, `department`, `email`, `need_pw_change`, `group_id`, `config_language`, `config_timezone`, `config_theme`, `config_currency`, `config_image_path`, `config_instock_comment_w`, `config_instock_comment_a`, `perms_system`, `perms_groups`, `perms_users`, `perms_self`, `perms_system_config`, `perms_system_database`, `perms_parts`, `perms_parts_name`, `perms_parts_description`, `perms_parts_instock`, `perms_parts_mininstock`, `perms_parts_footprint`, `perms_parts_storelocation`, `perms_parts_manufacturer`, `perms_parts_comment`, `perms_parts_order`, `perms_parts_orderdetails`, `perms_parts_prices`, `perms_parts_attachements`, `perms_devices`, `perms_devices_parts`, `perms_storelocations`, `perms_footprints`, `perms_categories`, `perms_suppliers`, `perms_manufacturers`, `perms_attachement_types`, `perms_tools`, `perms_labels`, `datetime_added`, `last_modified`) VALUES
|
||||
(1, 'anonymous', '', '', '', '', '', 0, 2, NULL, NULL, NULL, NULL, '', '', '', 21844, 20480, 0, 0, 0, 0, 0, 21840, 21840, 21840, 21840, 21840, 21840, 21840, 21840, 21840, 21520, 21520, 21520, 20480, 21520, 20480, 20480, 20480, 20480, 20480, 21504, 20480, 0, '2023-01-07 18:31:48', '0000-00-00 00:00:00'),
|
||||
(2, 'admin', '$2a$12$j0RKrKlx60bzX1DWMyXwjeaW.pe3bFjAK8ByIGnvjrRnET2JtsFoe$2a$12$j0RKrKlx60bzX1DWMyXwjeaW.pe3bFjAK8ByIGnvjrRnET2JtsFoe', '', '', '', '', 1, 1, NULL, NULL, NULL, NULL, '', '', '', 21845, 21845, 21845, 21, 85, 21, 349525, 21845, 21845, 21845, 21845, 21845, 21845, 21845, 21845, 21845, 21845, 21845, 21845, 21845, 21845, 21845, 21845, 21845, 21845, 21845, 21845, 21845, 0, '2023-01-07 18:31:48', '0000-00-00 00:00:00');
|
||||
|
||||
--
|
||||
-- Indizes der exportierten Tabellen
|
||||
--
|
||||
|
||||
--
|
||||
-- Indizes für die Tabelle `attachements`
|
||||
--
|
||||
ALTER TABLE `attachements`
|
||||
ADD PRIMARY KEY (`id`),
|
||||
ADD KEY `attachements_class_name_k` (`class_name`),
|
||||
ADD KEY `attachements_element_id_k` (`element_id`),
|
||||
ADD KEY `attachements_type_id_fk` (`type_id`);
|
||||
|
||||
--
|
||||
-- Indizes für die Tabelle `attachement_types`
|
||||
--
|
||||
ALTER TABLE `attachement_types`
|
||||
ADD PRIMARY KEY (`id`),
|
||||
ADD KEY `attachement_types_parent_id_k` (`parent_id`);
|
||||
|
||||
--
|
||||
-- Indizes für die Tabelle `categories`
|
||||
--
|
||||
ALTER TABLE `categories`
|
||||
ADD PRIMARY KEY (`id`),
|
||||
ADD KEY `categories_parent_id_k` (`parent_id`);
|
||||
|
||||
--
|
||||
-- Indizes für die Tabelle `devices`
|
||||
--
|
||||
ALTER TABLE `devices`
|
||||
ADD PRIMARY KEY (`id`),
|
||||
ADD KEY `devices_parent_id_k` (`parent_id`);
|
||||
|
||||
--
|
||||
-- Indizes für die Tabelle `device_parts`
|
||||
--
|
||||
ALTER TABLE `device_parts`
|
||||
ADD PRIMARY KEY (`id`),
|
||||
ADD UNIQUE KEY `device_parts_combination_uk` (`id_part`,`id_device`),
|
||||
ADD KEY `device_parts_id_part_k` (`id_part`),
|
||||
ADD KEY `device_parts_id_device_k` (`id_device`);
|
||||
|
||||
--
|
||||
-- Indizes für die Tabelle `footprints`
|
||||
--
|
||||
ALTER TABLE `footprints`
|
||||
ADD PRIMARY KEY (`id`),
|
||||
ADD KEY `footprints_parent_id_k` (`parent_id`);
|
||||
|
||||
--
|
||||
-- Indizes für die Tabelle `groups`
|
||||
--
|
||||
ALTER TABLE `groups`
|
||||
ADD PRIMARY KEY (`id`),
|
||||
ADD UNIQUE KEY `name` (`name`);
|
||||
|
||||
--
|
||||
-- Indizes für die Tabelle `internal`
|
||||
--
|
||||
ALTER TABLE `internal`
|
||||
ADD UNIQUE KEY `keyName` (`keyName`);
|
||||
|
||||
--
|
||||
-- Indizes für die Tabelle `log`
|
||||
--
|
||||
ALTER TABLE `log`
|
||||
ADD PRIMARY KEY (`id`),
|
||||
ADD KEY `id_user` (`id_user`);
|
||||
|
||||
--
|
||||
-- Indizes für die Tabelle `manufacturers`
|
||||
--
|
||||
ALTER TABLE `manufacturers`
|
||||
ADD PRIMARY KEY (`id`),
|
||||
ADD KEY `manufacturers_parent_id_k` (`parent_id`);
|
||||
|
||||
--
|
||||
-- Indizes für die Tabelle `orderdetails`
|
||||
--
|
||||
ALTER TABLE `orderdetails`
|
||||
ADD PRIMARY KEY (`id`),
|
||||
ADD KEY `orderdetails_part_id_k` (`part_id`),
|
||||
ADD KEY `orderdetails_id_supplier_k` (`id_supplier`);
|
||||
|
||||
--
|
||||
-- Indizes für die Tabelle `parts`
|
||||
--
|
||||
ALTER TABLE `parts`
|
||||
ADD PRIMARY KEY (`id`),
|
||||
ADD KEY `parts_id_category_k` (`id_category`),
|
||||
ADD KEY `parts_id_footprint_k` (`id_footprint`),
|
||||
ADD KEY `parts_id_storelocation_k` (`id_storelocation`),
|
||||
ADD KEY `parts_order_orderdetails_id_k` (`order_orderdetails_id`),
|
||||
ADD KEY `parts_id_manufacturer_k` (`id_manufacturer`),
|
||||
ADD KEY `favorite` (`favorite`);
|
||||
|
||||
--
|
||||
-- Indizes für die Tabelle `pricedetails`
|
||||
--
|
||||
ALTER TABLE `pricedetails`
|
||||
ADD PRIMARY KEY (`id`),
|
||||
ADD UNIQUE KEY `pricedetails_combination_uk` (`orderdetails_id`,`min_discount_quantity`),
|
||||
ADD KEY `pricedetails_orderdetails_id_k` (`orderdetails_id`);
|
||||
|
||||
--
|
||||
-- Indizes für die Tabelle `storelocations`
|
||||
--
|
||||
ALTER TABLE `storelocations`
|
||||
ADD PRIMARY KEY (`id`),
|
||||
ADD KEY `storelocations_parent_id_k` (`parent_id`);
|
||||
|
||||
--
|
||||
-- Indizes für die Tabelle `suppliers`
|
||||
--
|
||||
ALTER TABLE `suppliers`
|
||||
ADD PRIMARY KEY (`id`),
|
||||
ADD KEY `suppliers_parent_id_k` (`parent_id`);
|
||||
|
||||
--
|
||||
-- Indizes für die Tabelle `users`
|
||||
--
|
||||
ALTER TABLE `users`
|
||||
ADD PRIMARY KEY (`id`),
|
||||
ADD UNIQUE KEY `name` (`name`);
|
||||
|
||||
--
|
||||
-- AUTO_INCREMENT für exportierte Tabellen
|
||||
--
|
||||
|
||||
--
|
||||
-- AUTO_INCREMENT für Tabelle `attachements`
|
||||
--
|
||||
ALTER TABLE `attachements`
|
||||
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
|
||||
|
||||
--
|
||||
-- AUTO_INCREMENT für Tabelle `attachement_types`
|
||||
--
|
||||
ALTER TABLE `attachement_types`
|
||||
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=3;
|
||||
|
||||
--
|
||||
-- AUTO_INCREMENT für Tabelle `categories`
|
||||
--
|
||||
ALTER TABLE `categories`
|
||||
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=2;
|
||||
|
||||
--
|
||||
-- AUTO_INCREMENT für Tabelle `devices`
|
||||
--
|
||||
ALTER TABLE `devices`
|
||||
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
|
||||
|
||||
--
|
||||
-- AUTO_INCREMENT für Tabelle `device_parts`
|
||||
--
|
||||
ALTER TABLE `device_parts`
|
||||
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
|
||||
|
||||
--
|
||||
-- AUTO_INCREMENT für Tabelle `footprints`
|
||||
--
|
||||
ALTER TABLE `footprints`
|
||||
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
|
||||
|
||||
--
|
||||
-- AUTO_INCREMENT für Tabelle `groups`
|
||||
--
|
||||
ALTER TABLE `groups`
|
||||
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=4;
|
||||
|
||||
--
|
||||
-- AUTO_INCREMENT für Tabelle `log`
|
||||
--
|
||||
ALTER TABLE `log`
|
||||
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=6;
|
||||
|
||||
--
|
||||
-- AUTO_INCREMENT für Tabelle `manufacturers`
|
||||
--
|
||||
ALTER TABLE `manufacturers`
|
||||
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
|
||||
|
||||
--
|
||||
-- AUTO_INCREMENT für Tabelle `orderdetails`
|
||||
--
|
||||
ALTER TABLE `orderdetails`
|
||||
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=3;
|
||||
|
||||
--
|
||||
-- AUTO_INCREMENT für Tabelle `parts`
|
||||
--
|
||||
ALTER TABLE `parts`
|
||||
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=2;
|
||||
|
||||
--
|
||||
-- AUTO_INCREMENT für Tabelle `pricedetails`
|
||||
--
|
||||
ALTER TABLE `pricedetails`
|
||||
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=2;
|
||||
|
||||
--
|
||||
-- AUTO_INCREMENT für Tabelle `storelocations`
|
||||
--
|
||||
ALTER TABLE `storelocations`
|
||||
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
|
||||
|
||||
--
|
||||
-- AUTO_INCREMENT für Tabelle `suppliers`
|
||||
--
|
||||
ALTER TABLE `suppliers`
|
||||
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=2;
|
||||
|
||||
--
|
||||
-- AUTO_INCREMENT für Tabelle `users`
|
||||
--
|
||||
ALTER TABLE `users`
|
||||
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=3;
|
||||
|
||||
--
|
||||
-- Constraints der exportierten Tabellen
|
||||
--
|
||||
|
||||
--
|
||||
-- Constraints der Tabelle `attachements`
|
||||
--
|
||||
ALTER TABLE `attachements`
|
||||
ADD CONSTRAINT `attachements_type_id_fk` FOREIGN KEY (`type_id`) REFERENCES `attachement_types` (`id`);
|
||||
|
||||
--
|
||||
-- Constraints der Tabelle `attachement_types`
|
||||
--
|
||||
ALTER TABLE `attachement_types`
|
||||
ADD CONSTRAINT `attachement_types_parent_id_fk` FOREIGN KEY (`parent_id`) REFERENCES `attachement_types` (`id`);
|
||||
|
||||
--
|
||||
-- Constraints der Tabelle `categories`
|
||||
--
|
||||
ALTER TABLE `categories`
|
||||
ADD CONSTRAINT `categories_parent_id_fk` FOREIGN KEY (`parent_id`) REFERENCES `categories` (`id`);
|
||||
|
||||
--
|
||||
-- Constraints der Tabelle `devices`
|
||||
--
|
||||
ALTER TABLE `devices`
|
||||
ADD CONSTRAINT `devices_parent_id_fk` FOREIGN KEY (`parent_id`) REFERENCES `devices` (`id`);
|
||||
|
||||
--
|
||||
-- Constraints der Tabelle `footprints`
|
||||
--
|
||||
ALTER TABLE `footprints`
|
||||
ADD CONSTRAINT `footprints_parent_id_fk` FOREIGN KEY (`parent_id`) REFERENCES `footprints` (`id`);
|
||||
|
||||
--
|
||||
-- Constraints der Tabelle `manufacturers`
|
||||
--
|
||||
ALTER TABLE `manufacturers`
|
||||
ADD CONSTRAINT `manufacturers_parent_id_fk` FOREIGN KEY (`parent_id`) REFERENCES `manufacturers` (`id`);
|
||||
|
||||
--
|
||||
-- Constraints der Tabelle `parts`
|
||||
--
|
||||
ALTER TABLE `parts`
|
||||
ADD CONSTRAINT `parts_id_footprint_fk` FOREIGN KEY (`id_footprint`) REFERENCES `footprints` (`id`),
|
||||
ADD CONSTRAINT `parts_id_manufacturer_fk` FOREIGN KEY (`id_manufacturer`) REFERENCES `manufacturers` (`id`),
|
||||
ADD CONSTRAINT `parts_id_storelocation_fk` FOREIGN KEY (`id_storelocation`) REFERENCES `storelocations` (`id`),
|
||||
ADD CONSTRAINT `parts_order_orderdetails_id_fk` FOREIGN KEY (`order_orderdetails_id`) REFERENCES `orderdetails` (`id`);
|
||||
|
||||
--
|
||||
-- Constraints der Tabelle `storelocations`
|
||||
--
|
||||
ALTER TABLE `storelocations`
|
||||
ADD CONSTRAINT `storelocations_parent_id_fk` FOREIGN KEY (`parent_id`) REFERENCES `storelocations` (`id`);
|
||||
|
||||
--
|
||||
-- Constraints der Tabelle `suppliers`
|
||||
--
|
||||
ALTER TABLE `suppliers`
|
||||
ADD CONSTRAINT `suppliers_parent_id_fk` FOREIGN KEY (`parent_id`) REFERENCES `suppliers` (`id`);
|
||||
COMMIT;
|
||||
|
||||
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
|
||||
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
|
||||
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
|
||||
54
.github/assets/legacy_import/test_legacy_import.sh
vendored
Normal file
54
.github/assets/legacy_import/test_legacy_import.sh
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
#
|
||||
# This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||
#
|
||||
# Copyright (C) 2019 - 2023 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/>.
|
||||
#
|
||||
|
||||
#!/bin/bash
|
||||
|
||||
# This script is used to test the legacy import of Part-DB
|
||||
|
||||
SQL_FILES_TO_TEST=("db_minimal.sql" "db_jbtronics.sql")
|
||||
|
||||
DB_NAME="legacy_db_test"
|
||||
DB_USER="root"
|
||||
DB_PASSWORD="root"
|
||||
|
||||
# Iterate over all given SQL files and import them into the mysql database with the given name, drop the database if it already exists before
|
||||
for SQL_FILE in "${SQL_FILES_TO_TEST[@]}"
|
||||
do
|
||||
echo "Testing for $SQL_FILE"
|
||||
mysql -u $DB_USER --password=$DB_PASSWORD -e "DROP DATABASE IF EXISTS $DB_NAME; CREATE DATABASE $DB_NAME;"
|
||||
# If the last command failed, exit the script
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Failed to create database $DB_NAME"
|
||||
exit 1
|
||||
fi
|
||||
# Import the SQL file into the database. The file pathes are relative to the current script location
|
||||
mysql -u $DB_USER --password=$DB_PASSWORD $DB_NAME < .github/assets/legacy_import/$SQL_FILE
|
||||
# If the last command failed, exit the script
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Failed to import $SQL_FILE into database $DB_NAME"
|
||||
exit 1
|
||||
fi
|
||||
# Run doctrine migrations, this will migrate the database to the current version. This process should not fail
|
||||
php bin/console doctrine:migrations:migrate -n
|
||||
# If the last command failed, exit the script
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Failed to migrate database $DB_NAME"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
16
.github/workflows/assets_artifact_build.yml
vendored
16
.github/workflows/assets_artifact_build.yml
vendored
@@ -19,7 +19,15 @@ jobs:
|
||||
APP_ENV: prod
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: '8.2'
|
||||
coverage: none
|
||||
ini-values: xdebug.max_nesting_level=1000
|
||||
extensions: mbstring, intl, gd, xsl, gmp, bcmath, :php-psr
|
||||
|
||||
- name: Get Composer Cache Directory
|
||||
id: composer-cache
|
||||
@@ -49,7 +57,7 @@ jobs:
|
||||
${{ runner.os }}-yarn-
|
||||
|
||||
- name: Setup node
|
||||
uses: actions/setup-node@v3
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '18'
|
||||
|
||||
@@ -69,13 +77,13 @@ jobs:
|
||||
run: zip -r /tmp/partdb_assets.zip public/build/ vendor/
|
||||
|
||||
- name: Upload assets artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: Only dependencies and built assets
|
||||
path: /tmp/partdb_assets.zip
|
||||
|
||||
- name: Upload full artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: Full Part-DB including dependencies and built assets
|
||||
path: /tmp/partdb_with_assets.zip
|
||||
|
||||
54
.github/workflows/codeql-analysis.yml
vendored
54
.github/workflows/codeql-analysis.yml
vendored
@@ -1,54 +0,0 @@
|
||||
name: "CodeQL"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [master, ]
|
||||
pull_request:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches: [master]
|
||||
schedule:
|
||||
- cron: '0 14 * * 3'
|
||||
|
||||
jobs:
|
||||
analyse:
|
||||
name: Analyse
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
# We must fetch at least the immediate parents so that if this is
|
||||
# a pull request then we can checkout the head.
|
||||
fetch-depth: 2
|
||||
|
||||
# If this run was triggered by a pull request event, then checkout
|
||||
# the head of the pull request instead of the merge commit.
|
||||
- run: git checkout HEAD^2
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
# Override language selection by uncommenting this and choosing your languages
|
||||
# with:
|
||||
# languages: go, javascript, csharp, python, cpp, java
|
||||
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v2
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 https://git.io/JvXDl
|
||||
|
||||
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
|
||||
# and modify them (or add more) to build your code if your project
|
||||
# uses a compiled language
|
||||
|
||||
#- run: |
|
||||
# make bootstrap
|
||||
# make release
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v2
|
||||
12
.github/workflows/docker_build.yml
vendored
12
.github/workflows/docker_build.yml
vendored
@@ -17,11 +17,11 @@ jobs:
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
-
|
||||
name: Docker meta
|
||||
id: docker_meta
|
||||
uses: docker/metadata-action@v4
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
# list of Docker images to use as base name for tags
|
||||
images: |
|
||||
@@ -49,23 +49,23 @@ jobs:
|
||||
|
||||
-
|
||||
name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
uses: docker/setup-qemu-action@v3
|
||||
with:
|
||||
platforms: 'arm64,arm'
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
uses: docker/setup-buildx-action@v3
|
||||
-
|
||||
name: Login to DockerHub
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/login-action@v2
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
-
|
||||
name: Build and push
|
||||
uses: docker/build-push-action@v4
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: .
|
||||
platforms: linux/amd64,linux/arm64,linux/arm/v7
|
||||
|
||||
22
.github/workflows/static_analysis.yml
vendored
22
.github/workflows/static_analysis.yml
vendored
@@ -16,7 +16,15 @@ jobs:
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: '8.2'
|
||||
coverage: none
|
||||
ini-values: xdebug.max_nesting_level=1000
|
||||
extensions: mbstring, intl, gd, xsl, gmp, bcmath, :php-psr
|
||||
|
||||
- name: Get Composer Cache Directory
|
||||
id: composer-cache
|
||||
@@ -38,18 +46,20 @@ jobs:
|
||||
|
||||
- name: Lint twig templates
|
||||
run: ./bin/console lint:twig templates --env=prod
|
||||
|
||||
- name: Lint translations
|
||||
run: ./bin/console lint:xliff translations
|
||||
|
||||
# This causes problems with emtpy language files
|
||||
#- name: Lint translations
|
||||
# run: ./bin/console lint:xliff translations
|
||||
|
||||
- name: Check dependencies for security
|
||||
uses: symfonycorp/security-checker-action@v5
|
||||
|
||||
- name: Check doctrine mapping
|
||||
run: ./bin/console doctrine:schema:validate --skip-sync -vvv --no-interaction
|
||||
|
||||
|
||||
# Use the -d option to raise the max nesting level
|
||||
- name: Generate dev container
|
||||
run: ./bin/console cache:clear --env dev
|
||||
run: php -d xdebug.max_nesting_level=1000 ./bin/console cache:clear --env dev
|
||||
|
||||
- name: Run PHPstan
|
||||
run: composer phpstan
|
||||
|
||||
26
.github/workflows/tests.yml
vendored
26
.github/workflows/tests.yml
vendored
@@ -13,12 +13,11 @@ on:
|
||||
jobs:
|
||||
phpunit:
|
||||
name: PHPUnit and coverage Test (PHP ${{ matrix.php-versions }}, ${{ matrix.db-type }})
|
||||
# Ubuntu 20.04 ships MySQL 8.0 which causes problems with login, so we just use ubuntu 18.04 for now...
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
php-versions: [ '7.4', '8.0', '8.1', '8.2' ]
|
||||
php-versions: [ '8.1', '8.2', '8.3' ]
|
||||
db-type: [ 'mysql', 'sqlite' ]
|
||||
|
||||
env:
|
||||
@@ -27,6 +26,7 @@ jobs:
|
||||
SYMFONY_DEPRECATIONS_HELPER: disabled
|
||||
PHP_VERSION: ${{ matrix.php-versions }}
|
||||
DB_TYPE: ${{ matrix.db-type }}
|
||||
CHECK_FOR_UPDATES: false # Disable update checks for tests
|
||||
|
||||
steps:
|
||||
- name: Set Database env for MySQL
|
||||
@@ -38,14 +38,15 @@ jobs:
|
||||
if: matrix.db-type == 'sqlite'
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: ${{ matrix.php-versions }}
|
||||
coverage: pcov
|
||||
extensions: mbstring, intl, gd, xsl, gmp, bcmath
|
||||
ini-values: xdebug.max_nesting_level=1000
|
||||
extensions: mbstring, intl, gd, xsl, gmp, bcmath, :php-psr
|
||||
|
||||
- name: Start MySQL
|
||||
run: sudo systemctl start mysql.service
|
||||
@@ -86,7 +87,7 @@ jobs:
|
||||
run: composer install --prefer-dist --no-progress
|
||||
|
||||
- name: Setup node
|
||||
uses: actions/setup-node@v3
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '18'
|
||||
|
||||
@@ -107,9 +108,10 @@ jobs:
|
||||
|
||||
- name: Do migrations
|
||||
run: php bin/console --env test doctrine:migrations:migrate -n
|
||||
|
||||
|
||||
# Use our own custom fixtures loading command to circumvent some problems with reset the autoincrement values
|
||||
- name: Load fixtures
|
||||
run: php bin/console --env test doctrine:fixtures:load -n --purger reset_autoincrement_purger
|
||||
run: php bin/console --env test partdb:fixtures:load -n
|
||||
|
||||
- name: Run PHPunit and generate coverage
|
||||
run: ./bin/phpunit --coverage-clover=coverage.xml
|
||||
@@ -118,6 +120,8 @@ jobs:
|
||||
uses: codecov/codecov-action@v3
|
||||
with:
|
||||
env_vars: PHP_VERSION,DB_TYPE
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
fail_ci_if_error: true
|
||||
|
||||
- name: Test app:clean-attachments
|
||||
run: php bin/console partdb:attachments:clean-unused -n
|
||||
@@ -130,4 +134,12 @@ jobs:
|
||||
|
||||
- name: Test check-requirements command
|
||||
run: php bin/console partdb:check-requirements -n
|
||||
|
||||
- name: Test legacy Part-DB import
|
||||
run: bash .github/assets/legacy_import/test_legacy_import.sh
|
||||
if: matrix.db-type == 'mysql' && matrix.php-versions == '8.2'
|
||||
env:
|
||||
DATABASE_URL: mysql://root:root@localhost:3306/legacy_db
|
||||
|
||||
|
||||
|
||||
|
||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -43,3 +43,7 @@ yarn-error.log
|
||||
/phpunit.xml
|
||||
.phpunit.result.cache
|
||||
###< phpunit/phpunit ###
|
||||
|
||||
###> phpstan/phpstan ###
|
||||
phpstan.neon
|
||||
###< phpstan/phpstan ###
|
||||
|
||||
15
Dockerfile
15
Dockerfile
@@ -34,12 +34,25 @@ RUN sed -ri 's/^export ([^=]+)=(.*)$/: ${\1:=\2}\nexport \1/' "$APACHE_ENVVARS"
|
||||
ln -sfT /dev/stderr "$APACHE_LOG_DIR/error.log"; \
|
||||
ln -sfT /dev/stdout "$APACHE_LOG_DIR/access.log"; \
|
||||
ln -sfT /dev/stdout "$APACHE_LOG_DIR/other_vhosts_access.log"; \
|
||||
ln -sfT /dev/stderr /var/log/php8.1-fpm.log; \
|
||||
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
|
||||
|
||||
# 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 also disable the clear_env option to allow the use of environment variables in php-fpm
|
||||
RUN { \
|
||||
echo '[global]'; \
|
||||
echo 'error_log = /proc/1/fd/1'; \
|
||||
echo; \
|
||||
echo '[www]'; \
|
||||
echo 'access.log = /proc/1/fd/1'; \
|
||||
echo 'catch_workers_output = yes'; \
|
||||
echo 'decorate_workers_output = no'; \
|
||||
echo 'clear_env = no'; \
|
||||
} | tee "/etc/php/8.1/fpm/pool.d/zz-docker.conf"
|
||||
|
||||
# PHP files should be handled by PHP, and should be preferred over any other file type
|
||||
RUN { \
|
||||
echo '<FilesMatch \.php$>'; \
|
||||
|
||||
135
README.md
135
README.md
@@ -1,57 +1,70 @@
|
||||
[](https://scrutinizer-ci.com/g/Part-DB/Part-DB-symfony/?branch=master)
|
||||

|
||||

|
||||
[](https://codecov.io/gh/Part-DB/Part-DB-server)
|
||||
[](https://codecov.io/gh/Part-DB/Part-DB-server)
|
||||

|
||||

|
||||

|
||||
|
||||

|
||||

|
||||
[](https://part-db.crowdin.com/part-db)
|
||||
|
||||
**[Documentation](https://docs.part-db.de/)** | **[Demo](https://part-db.herokuapp.com)** | **[Docker Image](https://hub.docker.com/r/jbtronics/part-db1)**
|
||||
**[Documentation](https://docs.part-db.de/)** | **[Demo](https://demo.part-db.de/)** | **[Docker Image](https://hub.docker.com/r/jbtronics/part-db1)**
|
||||
|
||||
# Part-DB
|
||||
Part-DB is an Open-Source inventory managment system for your electronic components.
|
||||
|
||||
Part-DB is an Open-Source inventory management system for your electronic components.
|
||||
It is installed on a web server and so can be accessed with any browser without the need to install additional software.
|
||||
|
||||
The version in this Repository is a complete rewrite of the legacy [Part-DB](https://github.com/Part-DB/Part-DB) (Version < 1.0) based on a modern framework.
|
||||
Currently, it is still missing some (minor) features from the old version (see [UPGRADE.md](https://docs.part-db.de/upgrade_legacy.html)) for more details, but also many huge improvements and advantages compared to the old version.
|
||||
If you start completely new with Part-DB it is recommended that you use the version from this repository, as it is actively developed.
|
||||
The version in this repository is a complete rewrite of the legacy [Part-DB](https://github.com/Part-DB/Part-DB)
|
||||
(Version < 1.0) based on a modern framework and is the recommended version to use.
|
||||
|
||||
If you find a bug, please open an [Issue on Github](https://github.com/Part-DB/Part-DB-server/issues) so it can be fixed for everybody.
|
||||
If you find a bug, please open an [Issue on GitHub,](https://github.com/Part-DB/Part-DB-server/issues) so it can be fixed
|
||||
for everybody.
|
||||
|
||||
## Demo
|
||||
If you want to test Part-DB without installing it, you can use [this](https://part-db.herokuapp.com) Heroku instance.
|
||||
(Or this link for the [German Version](https://part-db.herokuapp.com/de/)).
|
||||
|
||||
If you want to test Part-DB without installing it, you can use [this](https://demo.part-db.de/) Heroku instance.
|
||||
(Or this link for the [German Version](https://demo.part-db.de/de/)).
|
||||
|
||||
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
|
||||
maybe not completely stable. Please mind, that the free Heroku instance is used, so it can take some time when loading the page
|
||||
maybe not completely stable. Please mind, that the free Heroku instance is used, so it can take some time when loading
|
||||
the page
|
||||
for the first time.
|
||||
|
||||
<img src="https://github.com/Part-DB/Part-DB-server/raw/master/docs/assets/readme/part_info.png">
|
||||
<img src="https://github.com/Part-DB/Part-DB-server/raw/master/docs/assets/readme/parts_list.png">
|
||||
|
||||
## Features
|
||||
* 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 like datasheets or pictures with the parts.
|
||||
|
||||
* 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
|
||||
like datasheets or pictures with the parts.
|
||||
* 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
|
||||
* 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. Password reset via email can be setuped.
|
||||
* Optional support for single sign-on (SSO) via SAML (using an intermediate service like [Keycloak](https://www.keycloak.org/) you can connect Part-DB to an existing LDAP or Active Directory server)
|
||||
* 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.
|
||||
Password reset via email can be setup.
|
||||
* Optional support for single sign-on (SSO) via SAML (using an intermediate service
|
||||
like [Keycloak](https://www.keycloak.org/) you can connect Part-DB to an existing LDAP or Active Directory server)
|
||||
* Import/Export system for parts and datastructure. 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 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 versions.
|
||||
* 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
|
||||
* Event log: Track what changes happens to your inventory, track which user does what. Revert your parts to older
|
||||
versions.
|
||||
* 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
|
||||
* Support for rich text descriptions and comments in parts
|
||||
* 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)
|
||||
* Automatic thumbnail generation for pictures
|
||||
|
||||
* Use cloud providers (like Octopart, Digikey, farnell or TME) to automatically get part information, datasheets and
|
||||
prices for parts
|
||||
* 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
|
||||
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,
|
||||
or makerspaces, where many users have should have (controlled) access to the shared inventory.
|
||||
@@ -59,69 +72,93 @@ or makerspaces, where many users have should have (controlled) access to the sha
|
||||
Part-DB is also used by small companies and universities for managing their inventory.
|
||||
|
||||
## Requirements
|
||||
* A **web server** (like Apache2 or nginx) that is capable of running [Symfony 5](https://symfony.com/doc/current/reference/requirements.html),
|
||||
this includes a minimum PHP version of **PHP 7.4**
|
||||
* A **MySQL** (at least 5.7) /**MariaDB** (at least 10.2.2) database server if you do not want to use SQLite.
|
||||
* Shell access to your server is highly suggested!
|
||||
* For building the client side assets **yarn** and **nodejs** is needed.
|
||||
|
||||
|
||||
* A **web server** (like Apache2 or nginx) that is capable of
|
||||
running [Symfony 5](https://symfony.com/doc/current/reference/requirements.html),
|
||||
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.
|
||||
* Shell access to your server is highly suggested!
|
||||
* For building the client side assets **yarn** and **nodejs** (>= 18.0) is needed.
|
||||
|
||||
## Installation
|
||||
If you want to upgrade your legacy (< 1.0.0) version of Part-DB to this version, please 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 up Part-DB via docker is described [here](https://docs.part-db.de/installation/installation_docker.html).
|
||||
If you want to upgrade your legacy (< 1.0.0) version of Part-DB to this version, please
|
||||
read [this](https://docs.part-db.de/upgrade_legacy.html) first.
|
||||
|
||||
**Below you find some very rough outline of the installation process, see [here](https://docs.part-db.de/installation/) for a detailed guide how to install Part-DB.**
|
||||
*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).
|
||||
|
||||
**Below you find some very rough outline of the installation process, see [here](https://docs.part-db.de/installation/)
|
||||
for a detailed guide how to install Part-DB.**
|
||||
|
||||
1. Copy or clone this repository into a folder on your server.
|
||||
2. Configure your webserver to serve from the `public/` folder. See [here](https://symfony.com/doc/current/setup/web_server_configuration.html)
|
||||
for additional information.
|
||||
2. Configure your webserver to serve from the `public/` folder.
|
||||
See [here](https://symfony.com/doc/current/setup/web_server_configuration.html)
|
||||
for additional information.
|
||||
3. Copy the global config file `cp .env .env.local` and edit `.env.local`:
|
||||
* Change the line `APP_ENV=dev` to `APP_ENV=prod`
|
||||
* If you do not want to use SQLite, change the value of `DATABASE_URL=` to your needs (see [here](http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/configuration.html#connecting-using-a-url)) for the format.
|
||||
In bigger instances with concurrent accesses, MySQL is more performant. This can not be changed easily later, so choose wisely.
|
||||
* If you do not want to use SQLite, change the value of `DATABASE_URL=` to your needs (
|
||||
see [here](http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/configuration.html#connecting-using-a-url))
|
||||
for the format.
|
||||
In bigger instances with concurrent accesses, MySQL is more performant. This can not be changed easily later, so
|
||||
choose wisely.
|
||||
4. Install composer dependencies and generate autoload files: `composer install -o --no-dev`
|
||||
5. If you have put Part-DB into a sub-directory on your server (like `part-db/`), you have to edit the file
|
||||
`webpack.config.js` and uncomment the lines (remove the `//` before the lines) `.setPublicPath('/part-db/build')` (line 43) and
|
||||
`.setManifestKeyPrefix('build/')` (line 44). You have to replace `/part-db` with your own path on line 44.
|
||||
6. Install client side dependencies and build it: `yarn install` and `yarn build`
|
||||
7. _Optional_ (speeds up first load): Warmup cache: `php bin/console cache:warmup`
|
||||
8. 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**: This steps tamper with your database and could potentially destroy it. So make sure to make a backup of your database.
|
||||
9. 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 changed after creating price informations).
|
||||
5. Install client side dependencies and build it: `yarn install` and `yarn build`
|
||||
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
|
||||
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
|
||||
database.
|
||||
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
|
||||
changed after creating price information).
|
||||
Run `php bin/console cache:clear` when you changed something.
|
||||
10. Access Part-DB in your browser (under the URL you put it) and login with user *admin*. Password is the one outputted 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 new users with the admin user and start using Part-DB.
|
||||
9. Access Part-DB in your browser (under the URL you put it) and login with user *admin*. Password is the one outputted
|
||||
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
|
||||
new users with the admin user and start using Part-DB.
|
||||
|
||||
When you want to upgrade to a newer version, then just copy the new files into the folder
|
||||
and repeat the steps 4. to 7.
|
||||
|
||||
Normally a random password is generated when the admin user is created during inital database creation,
|
||||
however you can set the inital admin password, by setting the `INITIAL_ADMIN_PW` env var.
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
### Reverse proxy
|
||||
If you are using a reverse proxy, you have to ensure that the proxies sets the `X-Forwarded-*` headers correctly, or you 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 the `TRUSTED_PROXIES` env variable to match your reverse proxies IP-address (or IP block). You can do this in your `.env.local` or (when using docker) in your `docker-compose.yml` file.
|
||||
|
||||
If you are using a reverse proxy, you have to ensure that the proxies sets the `X-Forwarded-*` headers correctly, or you
|
||||
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
|
||||
the `TRUSTED_PROXIES` env variable to match your reverse proxies IP-address (or IP block). You can do this in
|
||||
your `.env.local` or (when using docker) in your `docker-compose.yml` file.
|
||||
|
||||
## 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).
|
||||
There you will find various methods to support development on a monthly or a one time base.
|
||||
|
||||
## Built with
|
||||
|
||||
* [Symfony 5](https://symfony.com/): The main framework used for the serverside PHP
|
||||
* [Bootstrap 5](https://getbootstrap.com/) and [Bootswatch](https://bootswatch.com/): Used as website theme
|
||||
* [Fontawesome](https://fontawesome.com/): Used as icon set
|
||||
* [Hotwire Stimulus](https://stimulus.hotwired.dev/) and [Hotwire Turbo](https://turbo.hotwired.dev/): Frontend Javascript
|
||||
* [Hotwire Stimulus](https://stimulus.hotwired.dev/) and [Hotwire Turbo](https://turbo.hotwired.dev/): Frontend
|
||||
Javascript
|
||||
|
||||
## Authors
|
||||
* **Jan Böhmer** - *Inital work* - [Github](https://github.com/jbtronics/)
|
||||
|
||||
See also the list of [contributors](https://github.com/Part-DB/Part-DB-server/graphs/contributors) who participated in this project.
|
||||
* **Jan Böhmer** - *Initial work* - [GitHub](https://github.com/jbtronics/)
|
||||
|
||||
See also the list of [contributors](https://github.com/Part-DB/Part-DB-server/graphs/contributors) who participated in
|
||||
this project.
|
||||
|
||||
Based on the original Part-DB by Christoph Lechner and K. Jacobs
|
||||
|
||||
## License
|
||||
|
||||
Part-DB is licensed under the GNU Affero General Public License v3.0 (or at your opinion any later).
|
||||
This mostly means that you can use Part-DB for whatever you want (even use it commercially)
|
||||
as long as you publish the source code for every change you make under the AGPL, too.
|
||||
|
||||
3
assets/bootstrap.js
vendored
3
assets/bootstrap.js
vendored
@@ -4,8 +4,7 @@ import { startStimulusApp } from '@symfony/stimulus-bridge';
|
||||
export const app = startStimulusApp(require.context(
|
||||
'@symfony/stimulus-bridge/lazy-controller-loader!./controllers',
|
||||
true,
|
||||
/\.(j|t)sx?$/
|
||||
/\.[jt]sx?$/
|
||||
));
|
||||
|
||||
// register any custom, 3rd party controllers here
|
||||
// app.register('some_controller_name', SomeImportedController);
|
||||
|
||||
@@ -181,7 +181,8 @@ Editor.defaultConfig = {
|
||||
'DejaVu Serif, serif',
|
||||
'Helvetica, Arial, sans-serif',
|
||||
'Times New Roman, Times, serif',
|
||||
'Courier New, Courier, monospace'
|
||||
'Courier New, Courier, monospace',
|
||||
'Unifont, monospace',
|
||||
],
|
||||
supportAllValues: true
|
||||
},
|
||||
|
||||
@@ -76,6 +76,7 @@ const PLACEHOLDERS = [
|
||||
['[[FOOTPRINT_FULL]]', 'Footprint (Full path)'],
|
||||
['[[MASS]]', 'Mass'],
|
||||
['[[MPN]]', 'Manufacturer Product Number (MPN)'],
|
||||
['[[IPN]]', 'Internal Part Number (IPN)'],
|
||||
['[[TAGS]]', 'Tags'],
|
||||
['[[M_STATUS]]', 'Manufacturing status'],
|
||||
['[[DESCRIPTION]]', 'Description'],
|
||||
@@ -84,6 +85,9 @@ const PLACEHOLDERS = [
|
||||
['[[COMMENT_T]]', 'Comment (plain text)'],
|
||||
['[[LAST_MODIFIED]]', 'Last modified datetime'],
|
||||
['[[CREATION_DATE]]', 'Creation datetime'],
|
||||
['[[IPN_BARCODE_QR]]', 'IPN as QR code'],
|
||||
['[[IPN_BARCODE_C128]]', 'IPN as Code 128 barcode'],
|
||||
['[[IPN_BARCODE_C39]]', 'IPN as Code 39 barcode'],
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -96,6 +100,8 @@ const PLACEHOLDERS = [
|
||||
['[[AMOUNT]]', 'Lot amount'],
|
||||
['[[LOCATION]]', 'Storage location'],
|
||||
['[[LOCATION_FULL]]', 'Storage location (Full path)'],
|
||||
['[[OWNER]]', 'Full name of the lot owner'],
|
||||
['[[OWNER_USERNAME]]', 'Username of the lot owner'],
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -110,6 +116,8 @@ const PLACEHOLDERS = [
|
||||
['[[COMMENT_T]]', 'Comment (plain text)'],
|
||||
['[[LAST_MODIFIED]]', 'Last modified datetime'],
|
||||
['[[CREATION_DATE]]', 'Creation datetime'],
|
||||
['[[OWNER]]', 'Full name of the location owner'],
|
||||
['[[OWNER_USERNAME]]', 'Username of the location owner'],
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@@ -39,6 +39,7 @@ Object.assign( window.CKEDITOR_TRANSLATIONS[ 'de' ].dictionary, {
|
||||
'Footprint (Full path)': 'Footprint (Vollständiger Pfad)',
|
||||
'Mass': 'Gewicht',
|
||||
'Manufacturer Product Number (MPN)': 'Hersteller Produktnummer (MPN)',
|
||||
'Internal Part Number (IPN)': 'Internal Part Number (IPN)',
|
||||
'Tags': 'Tags',
|
||||
'Manufacturing status': 'Herstellungsstatus',
|
||||
'Description': 'Beschreibung',
|
||||
@@ -47,6 +48,9 @@ Object.assign( window.CKEDITOR_TRANSLATIONS[ 'de' ].dictionary, {
|
||||
'Comment (plain text)': 'Kommentar (Nur-Text)',
|
||||
'Last modified datetime': 'Zuletzt geändert',
|
||||
'Creation datetime': 'Erstellt',
|
||||
'IPN as QR code': 'IPN als QR Code',
|
||||
'IPN as Code 128 barcode': 'IPN als Code 128 Barcode',
|
||||
'IPN as Code 39 barcode': 'IPN als Code 39 Barcode',
|
||||
|
||||
'Lot ID': 'Lot ID',
|
||||
'Lot name': 'Lot Name',
|
||||
@@ -55,6 +59,8 @@ Object.assign( window.CKEDITOR_TRANSLATIONS[ 'de' ].dictionary, {
|
||||
'Lot amount': 'Lot Menge',
|
||||
'Storage location': 'Lagerort',
|
||||
'Storage location (Full path)': 'Lagerort (Vollständiger Pfad)',
|
||||
'Full name of the lot owner': 'Name des Besitzers des Lots',
|
||||
'Username of the lot owner': 'Benutzername des Besitzers des Lots',
|
||||
|
||||
|
||||
'Barcodes': 'Barcodes',
|
||||
@@ -69,6 +75,8 @@ Object.assign( window.CKEDITOR_TRANSLATIONS[ 'de' ].dictionary, {
|
||||
'Full path': 'Vollständiger Pfad',
|
||||
'Parent name': 'Name des Übergeordneten Elements',
|
||||
'Parent full path': 'Ganzer Pfad des Übergeordneten Elements',
|
||||
'Full name of the location owner': 'Name des Besitzers des Lagerorts',
|
||||
'Username of the location owner': 'Benutzername des Besitzers des Lagerorts',
|
||||
|
||||
'Username': 'Benutzername',
|
||||
'Username (including name)': 'Benutzername (inklusive Name)',
|
||||
|
||||
@@ -30,9 +30,73 @@ export default class SpecialCharactersEmoji extends Plugin {
|
||||
const editor = this.editor;
|
||||
const specialCharsPlugin = editor.plugins.get('SpecialCharacters');
|
||||
|
||||
//Add greek characters to special characters
|
||||
specialCharsPlugin.addItems('Greek', this.getGreek());
|
||||
|
||||
//Add Emojis to special characters
|
||||
specialCharsPlugin.addItems('Emoji', this.getEmojis());
|
||||
}
|
||||
|
||||
getGreek() {
|
||||
return [
|
||||
{ title: 'Alpha', character: 'Α' },
|
||||
{ title: 'Beta', character: 'Β' },
|
||||
{ title: 'Gamma', character: 'Γ' },
|
||||
{ title: 'Delta', character: 'Δ' },
|
||||
{ title: 'Epsilon', character: 'Ε' },
|
||||
{ title: 'Zeta', character: 'Ζ' },
|
||||
{ title: 'Eta', character: 'Η' },
|
||||
{ title: 'Theta', character: 'Θ' },
|
||||
{ title: 'Iota', character: 'Ι' },
|
||||
{ title: 'Kappa', character: 'Κ' },
|
||||
{ title: 'Lambda', character: 'Λ' },
|
||||
{ title: 'Mu', character: 'Μ' },
|
||||
{ title: 'Nu', character: 'Ν' },
|
||||
{ title: 'Xi', character: 'Ξ' },
|
||||
{ title: 'Omicron', character: 'Ο' },
|
||||
{ title: 'Pi', character: 'Π' },
|
||||
{ title: 'Rho', character: 'Ρ' },
|
||||
{ title: 'Sigma', character: 'Σ' },
|
||||
{ title: 'Tau', character: 'Τ' },
|
||||
{ title: 'Upsilon', character: 'Υ' },
|
||||
{ title: 'Phi', character: 'Φ' },
|
||||
{ title: 'Chi', character: 'Χ' },
|
||||
{ title: 'Psi', character: 'Ψ' },
|
||||
{ title: 'Omega', character: 'Ω' },
|
||||
{ title: 'alpha', character: 'α' },
|
||||
{ title: 'beta', character: 'β' },
|
||||
{ title: 'gamma', character: 'γ' },
|
||||
{ title: 'delta', character: 'δ' },
|
||||
{ title: 'epsilon', character: 'ε' },
|
||||
{ title: 'zeta', character: 'ζ' },
|
||||
{ title: 'eta', character: 'η' },
|
||||
{ title: 'theta', character: 'θ' },
|
||||
{ title: 'alternate theta', character: 'ϑ' },
|
||||
{ title: 'iota', character: 'ι' },
|
||||
{ title: 'kappa', character: 'κ' },
|
||||
{ title: 'lambda', character: 'λ' },
|
||||
{ title: 'mu', character: 'μ' },
|
||||
{ title: 'nu', character: 'ν' },
|
||||
{ title: 'xi', character: 'ξ' },
|
||||
{ title: 'omicron', character: 'ο' },
|
||||
{ title: 'pi', character: 'π' },
|
||||
{ title: 'rho', character: 'ρ' },
|
||||
{ title: 'sigma', character: 'σ' },
|
||||
{ title: 'tau', character: 'τ' },
|
||||
{ title: 'upsilon', character: 'υ' },
|
||||
{ title: 'phi', character: 'φ' },
|
||||
{ title: 'chi', character: 'χ' },
|
||||
{ title: 'psi', character: 'ψ' },
|
||||
{ title: 'omega', character: 'ω' },
|
||||
{ title: 'digamma', character: 'Ϝ' },
|
||||
{ title: 'stigma', character: 'Ϛ' },
|
||||
{ title: 'heta', character: 'Ͱ' },
|
||||
{ title: 'sampi', character: 'Ϡ' },
|
||||
{ title: 'koppa', character: 'Ϟ' },
|
||||
{ title: 'san', character: 'Ϻ' },
|
||||
];
|
||||
}
|
||||
|
||||
getEmojis() {
|
||||
//Map our emoji data to the format the plugin expects
|
||||
return emoji.map(emoji => {
|
||||
|
||||
@@ -18,43 +18,118 @@
|
||||
*/
|
||||
|
||||
import {Controller} from "@hotwired/stimulus";
|
||||
import Darkmode from "darkmode-js/src";
|
||||
import "darkmode-js"
|
||||
|
||||
export default class extends Controller {
|
||||
|
||||
_darkmode;
|
||||
|
||||
connect() {
|
||||
if (typeof window.getComputedStyle(document.body).mixBlendMode == 'undefined') {
|
||||
console.warn("The browser does not support mix blend mode. Darkmode will not work.");
|
||||
this.setMode(this.getMode());
|
||||
document.querySelectorAll('input[name="darkmode"]').forEach((radio) => {
|
||||
radio.addEventListener('change', this._radioChanged.bind(this));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Event listener for the change of radio buttons
|
||||
* @private
|
||||
*/
|
||||
_radioChanged(event) {
|
||||
const new_mode = this.getSelectedMode();
|
||||
this.setMode(new_mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current mode from the local storage
|
||||
* @return {'dark', 'light', 'auto'}
|
||||
*/
|
||||
getMode() {
|
||||
return localStorage.getItem('darkmode') ?? 'auto';
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the mode in the local storage and apply it and change the state of the radio buttons
|
||||
* @param mode
|
||||
*/
|
||||
setMode(mode) {
|
||||
if (mode !== 'dark' && mode !== 'light' && mode !== 'auto') {
|
||||
console.warn('Invalid darkmode mode: ' + mode);
|
||||
mode = 'auto';
|
||||
}
|
||||
|
||||
localStorage.setItem('darkmode', mode);
|
||||
|
||||
this.setButtonMode(mode);
|
||||
|
||||
if (mode === 'auto') {
|
||||
this._setDarkmodeAuto();
|
||||
} else if (mode === 'dark') {
|
||||
this._enableDarkmode();
|
||||
} else if (mode === 'light') {
|
||||
this._disableDarkmode();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the selected mode via the radio buttons
|
||||
* @return {'dark', 'light', 'auto'}
|
||||
*/
|
||||
getSelectedMode() {
|
||||
return document.querySelector('input[name="darkmode"]:checked').value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the state of the radio buttons
|
||||
* @param mode
|
||||
*/
|
||||
setButtonMode(mode) {
|
||||
document.querySelector('input[name="darkmode"][value="' + mode + '"]').checked = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable darkmode by adding the data-bs-theme="dark" to the html tag
|
||||
* @private
|
||||
*/
|
||||
_enableDarkmode() {
|
||||
//Add data-bs-theme="dark" to the html tag
|
||||
document.documentElement.setAttribute('data-bs-theme', 'dark');
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable darkmode by adding the data-bs-theme="light" to the html tag
|
||||
* @private
|
||||
*/
|
||||
_disableDarkmode() {
|
||||
//Set data-bs-theme to light
|
||||
document.documentElement.setAttribute('data-bs-theme', 'light');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the darkmode to auto and enable/disable it depending on the system settings, also add
|
||||
* an event listener to change the darkmode if the system settings change
|
||||
* @private
|
||||
*/
|
||||
_setDarkmodeAuto() {
|
||||
if (this.getMode() !== 'auto') {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const darkmode = new Darkmode();
|
||||
this._darkmode = darkmode;
|
||||
|
||||
//Unhide darkmode button
|
||||
this._showWidget();
|
||||
|
||||
//Set the switch according to our current darkmode state
|
||||
const toggler = document.getElementById("toggleDarkmode");
|
||||
toggler.checked = darkmode.isActivated();
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
console.error(e);
|
||||
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
|
||||
this._enableDarkmode();
|
||||
} else {
|
||||
this._disableDarkmode();
|
||||
}
|
||||
|
||||
|
||||
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', event => {
|
||||
console.log('Prefered color scheme changed to ' + event.matches ? 'dark' : 'light');
|
||||
this._setDarkmodeAuto();
|
||||
});
|
||||
}
|
||||
|
||||
_showWidget() {
|
||||
this.element.classList.remove('hidden');
|
||||
}
|
||||
|
||||
toggleDarkmode() {
|
||||
this._darkmode.toggle();
|
||||
/**
|
||||
* Check if darkmode is activated
|
||||
* @return {boolean}
|
||||
*/
|
||||
isDarkmodeActivated() {
|
||||
return document.documentElement.getAttribute('data-bs-theme') === 'dark';
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,8 @@
|
||||
|
||||
import { Controller } from '@hotwired/stimulus';
|
||||
import { marked } from "marked";
|
||||
import { mangle } from "marked-mangle";
|
||||
import { gfmHeadingId } from "marked-gfm-heading-id";
|
||||
import DOMPurify from 'dompurify';
|
||||
|
||||
import "../../css/app/markdown.css";
|
||||
@@ -81,6 +83,10 @@ export default class extends Controller {
|
||||
*/
|
||||
configureMarked()
|
||||
{
|
||||
marked.use(mangle());
|
||||
marked.use(gfmHeadingId({
|
||||
}));
|
||||
|
||||
marked.setOptions({
|
||||
gfm: true,
|
||||
});
|
||||
|
||||
@@ -61,7 +61,7 @@ export default class extends Controller {
|
||||
|
||||
if(!prototype) {
|
||||
console.warn("Prototype is not set, we cannot create a new element. This is most likely due to missing permissions.");
|
||||
bootbox.alert("You do not have the permsissions to create a new element. (No protoype element is set)");
|
||||
bootbox.alert("You do not have the permissions to create a new element. (No protoype element is set)");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -65,12 +65,19 @@ export default class extends Controller {
|
||||
localStorage.setItem( this.getStateSaveKey(), JSON.stringify(data) );
|
||||
}
|
||||
|
||||
stateLoadCallback(settings) {
|
||||
const data = JSON.parse( localStorage.getItem(this.getStateSaveKey()) );
|
||||
stateLoadCallback() {
|
||||
const json = localStorage.getItem(this.getStateSaveKey());
|
||||
if(json === null || json === undefined) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const data = JSON.parse(json);
|
||||
|
||||
if (data) {
|
||||
//Do not save the start value (current page), as we want to always start at the first page on a page reload
|
||||
data.start = 0;
|
||||
delete data.start;
|
||||
//Reset the data length to the default value by deleting the length property
|
||||
delete data.length;
|
||||
}
|
||||
|
||||
return data;
|
||||
@@ -88,6 +95,19 @@ export default class extends Controller {
|
||||
//Add url info, as the one available in the history is not enough, as Turbo may have not changed it yet
|
||||
settings.url = this.element.dataset.dtUrl;
|
||||
|
||||
//Add initial_order info to the settings, so that the order on the initial page load is the one saved in the state
|
||||
const saved_state = this.stateLoadCallback();
|
||||
if (saved_state !== null) {
|
||||
const raw_order = saved_state.order;
|
||||
|
||||
settings.initial_order = raw_order.map((order) => {
|
||||
return {
|
||||
column: order[0],
|
||||
dir: order[1]
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
let options = {
|
||||
colReorder: true,
|
||||
responsive: true,
|
||||
@@ -97,7 +117,7 @@ export default class extends Controller {
|
||||
},
|
||||
buttons: [{
|
||||
"extend": 'colvis',
|
||||
'className': 'mr-2 btn-light',
|
||||
'className': 'mr-2 btn-outline-secondary',
|
||||
'columns': ':not(.no-colvis)',
|
||||
"text": "<i class='fa fa-cog'></i>"
|
||||
}],
|
||||
@@ -123,6 +143,22 @@ export default class extends Controller {
|
||||
console.error("Error initializing datatables: " + err);
|
||||
});
|
||||
|
||||
//Fix height of the length selector
|
||||
promise.then((dt) => {
|
||||
//Find all length selectors (select with name dt_length), which are inside a label
|
||||
const lengthSelectors = document.querySelectorAll('label select[name="dt_length"]');
|
||||
//And remove the surrounding label, while keeping the select with all event handlers
|
||||
lengthSelectors.forEach((selector) => {
|
||||
selector.parentElement.replaceWith(selector);
|
||||
});
|
||||
|
||||
//Find all column visibility buttons (button with buttons-colvis class) and remove the btn-secondary class
|
||||
const colVisButtons = document.querySelectorAll('button.buttons-colvis');
|
||||
colVisButtons.forEach((button) => {
|
||||
button.classList.remove('btn-secondary');
|
||||
});
|
||||
});
|
||||
|
||||
//Dispatch an event to let others know that the datatables has been loaded
|
||||
promise.then((dt) => {
|
||||
const event = new CustomEvent(EVENT_DT_LOADED, {bubbles: true});
|
||||
@@ -203,4 +239,16 @@ export default class extends Controller {
|
||||
return this.element.dataset.select ?? false;
|
||||
}
|
||||
|
||||
invertSelection() {
|
||||
//Do nothing if the datatable is not selectable
|
||||
if(!this.isSelectable()) {
|
||||
return;
|
||||
}
|
||||
|
||||
//Invert the selected rows on the datatable
|
||||
const selected_rows = this._dt.rows({selected: true});
|
||||
this._dt.rows().select();
|
||||
selected_rows.deselect();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -29,62 +29,47 @@ export default class extends Controller
|
||||
this._confirmed = false;
|
||||
}
|
||||
|
||||
click(event) {
|
||||
//If a user has not already confirmed the deletion, just let turbo do its work
|
||||
if(this._confirmed) {
|
||||
this._confirmed = false;
|
||||
return;
|
||||
}
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
const message = this.element.dataset.deleteMessage;
|
||||
const title = this.element.dataset.deleteTitle;
|
||||
|
||||
const that = this;
|
||||
|
||||
const confirm = bootbox.confirm({
|
||||
message: message, title: title, callback: function (result) {
|
||||
//If the dialog was confirmed, then submit the form.
|
||||
if (result) {
|
||||
that._confirmed = true;
|
||||
event.target.click();
|
||||
} else {
|
||||
that._confirmed = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
submit(event) {
|
||||
//If a user has not already confirmed the deletion, just let turbo do its work
|
||||
if(this._confirmed) {
|
||||
if (this._confirmed) {
|
||||
this._confirmed = false;
|
||||
return;
|
||||
}
|
||||
|
||||
//Prevent turbo from doing its work
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
const message = this.element.dataset.deleteMessage;
|
||||
const title = this.element.dataset.deleteTitle;
|
||||
|
||||
const form = this.element;
|
||||
//Use event target, to find the form, where the submit button was clicked
|
||||
const form = event.target;
|
||||
const submitter = event.submitter;
|
||||
const that = this;
|
||||
|
||||
//Create a clone of the event with the same submitter, so we can redispatch it if needed
|
||||
//We need to do this that way, as we need the submitter info, just calling form.submit() would not work
|
||||
this._our_event = new SubmitEvent('submit', {
|
||||
submitter: event.submitter,
|
||||
bubbles: true, //This line is important, otherwise Turbo will not receive the event
|
||||
});
|
||||
|
||||
const confirm = bootbox.confirm({
|
||||
message: message, title: title, callback: function (result) {
|
||||
//If the dialog was confirmed, then submit the form.
|
||||
if (result) {
|
||||
//Set a flag to prevent the dialog from popping up again and allowing turbo to submit the form
|
||||
that._confirmed = true;
|
||||
form.dispatchEvent(that._our_event);
|
||||
|
||||
//Create a submit button in the form and click it to submit the form
|
||||
//Before a submit event was dispatched, but this caused weird issues on Firefox causing the delete request being posted twice (and the second time was returning 404). See https://github.com/Part-DB/Part-DB-server/issues/273
|
||||
const submit_btn = document.createElement('button');
|
||||
submit_btn.type = 'submit';
|
||||
submit_btn.style.display = 'none';
|
||||
|
||||
//If the clicked button has a value, set it on the submit button
|
||||
if (submitter.value) {
|
||||
submit_btn.value = submitter.value;
|
||||
}
|
||||
if (submitter.name) {
|
||||
submit_btn.name = submitter.name;
|
||||
}
|
||||
form.appendChild(submit_btn);
|
||||
submit_btn.click();
|
||||
} else {
|
||||
that._confirmed = false;
|
||||
}
|
||||
|
||||
40
assets/controllers/elements/json_formatter_controller.js
Normal file
40
assets/controllers/elements/json_formatter_controller.js
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||
*
|
||||
* Copyright (C) 2019 - 2023 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 JSONFormatter from 'json-formatter-js';
|
||||
|
||||
/**
|
||||
* This controller implements an element that renders a JSON object as a collapsible tree.
|
||||
* The JSON object is passed as a data attribute.
|
||||
* You have to apply the controller to a div element or similar block element which can contain other elements.
|
||||
*/
|
||||
export default class extends Controller {
|
||||
connect() {
|
||||
const depth_to_open = this.element.dataset.depthToOpen ?? 0;
|
||||
const json_string = this.element.dataset.json;
|
||||
const json_object = JSON.parse(json_string);
|
||||
|
||||
const formatter = new JSONFormatter(json_object, depth_to_open);
|
||||
|
||||
this.element.appendChild(formatter.render());
|
||||
}
|
||||
}
|
||||
72
assets/controllers/elements/link_confirm_controller.js
Normal file
72
assets/controllers/elements/link_confirm_controller.js
Normal file
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||
*
|
||||
* Copyright (C) 2019 - 2022 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 * as bootbox from "bootbox";
|
||||
import "../../css/components/bootbox_extensions.css";
|
||||
|
||||
export default class extends Controller
|
||||
{
|
||||
|
||||
static values = {
|
||||
message: String,
|
||||
title: String
|
||||
}
|
||||
|
||||
|
||||
|
||||
connect()
|
||||
{
|
||||
this._confirmed = false;
|
||||
|
||||
this.element.addEventListener('click', this._onClick.bind(this));
|
||||
}
|
||||
|
||||
_onClick(event)
|
||||
{
|
||||
|
||||
//If a user has not already confirmed the deletion, just let turbo do its work
|
||||
if (this._confirmed) {
|
||||
this._confirmed = false;
|
||||
return;
|
||||
}
|
||||
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
const that = this;
|
||||
|
||||
bootbox.confirm({
|
||||
title: this.titleValue,
|
||||
message: this.messageValue,
|
||||
callback: (result) => {
|
||||
if (result) {
|
||||
//Set a flag to prevent the dialog from popping up again and allowing turbo to submit the form
|
||||
that._confirmed = true;
|
||||
|
||||
//Click the link
|
||||
that.element.click();
|
||||
} else {
|
||||
that._confirmed = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||
*
|
||||
* Copyright (C) 2019 - 2023 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";
|
||||
|
||||
export default class extends Controller
|
||||
{
|
||||
static values = {
|
||||
id: String
|
||||
}
|
||||
|
||||
connect() {
|
||||
this.loadState()
|
||||
this.element.addEventListener('change', () => {
|
||||
this.saveState()
|
||||
});
|
||||
}
|
||||
|
||||
loadState() {
|
||||
let storageKey = this.getStorageKey();
|
||||
let value = localStorage.getItem(storageKey);
|
||||
if (value === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (value === 'true') {
|
||||
this.element.checked = true
|
||||
}
|
||||
if (value === 'false') {
|
||||
this.element.checked = false
|
||||
}
|
||||
}
|
||||
|
||||
saveState() {
|
||||
let storageKey = this.getStorageKey();
|
||||
|
||||
if (this.element.checked) {
|
||||
localStorage.setItem(storageKey, 'true');
|
||||
} else {
|
||||
localStorage.setItem(storageKey, 'false');
|
||||
}
|
||||
}
|
||||
|
||||
getStorageKey() {
|
||||
if (this.hasIdValue) {
|
||||
return 'persistent_checkbox_' + this.idValue
|
||||
}
|
||||
|
||||
return 'persistent_checkbox_' + this.element.id;
|
||||
}
|
||||
}
|
||||
@@ -27,7 +27,7 @@ export default class extends Controller {
|
||||
}
|
||||
|
||||
let tmp = '<div class="row m-0">' +
|
||||
"<div class='col-2 p-0 d-flex align-items-center'>" +
|
||||
"<div class='col-2 p-0 d-flex align-items-center' style='max-width: 80px;'>" +
|
||||
(data.image ? "<img class='typeahead-image' src='" + data.image + "'/>" : "") +
|
||||
"</div>" +
|
||||
"<div class='col-10'>" +
|
||||
|
||||
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||
*
|
||||
* Copyright (C) 2019 - 2023 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 { zxcvbn, zxcvbnOptions } from '@zxcvbn-ts/core';
|
||||
import * as zxcvbnCommonPackage from '@zxcvbn-ts/language-common';
|
||||
import * as zxcvbnEnPackage from '@zxcvbn-ts/language-en';
|
||||
import * as zxcvbnDePackage from '@zxcvbn-ts/language-de';
|
||||
import * as zxcvbnFrPackage from '@zxcvbn-ts/language-fr';
|
||||
import * as zxcvbnJaPackage from '@zxcvbn-ts/language-ja';
|
||||
import {trans, USER_PASSWORD_STRENGTH_VERY_WEAK, USER_PASSWORD_STRENGTH_WEAK, USER_PASSWORD_STRENGTH_MEDIUM,
|
||||
USER_PASSWORD_STRENGTH_STRONG, USER_PASSWORD_STRENGTH_VERY_STRONG} from '../../translator.js';
|
||||
|
||||
/* stimulusFetch: 'lazy' */
|
||||
export default class extends Controller {
|
||||
|
||||
_passwordInput;
|
||||
|
||||
static targets = ["badge", "warning"]
|
||||
|
||||
_getTranslations() {
|
||||
//Get the current locale
|
||||
const locale = document.documentElement.lang;
|
||||
if (locale.includes('de')) {
|
||||
return zxcvbnDePackage.translations;
|
||||
} else if (locale.includes('fr')) {
|
||||
return zxcvbnFrPackage.translations;
|
||||
} else if (locale.includes('ja')) {
|
||||
return zxcvbnJaPackage.translations;
|
||||
}
|
||||
|
||||
//Fallback to english
|
||||
return zxcvbnEnPackage.translations;
|
||||
}
|
||||
|
||||
connect() {
|
||||
//Find the password input field
|
||||
this._passwordInput = this.element.querySelector('input[type="password"]');
|
||||
|
||||
//Configure zxcvbn
|
||||
const options = {
|
||||
graphs: zxcvbnCommonPackage.adjacencyGraphs,
|
||||
dictionary: {
|
||||
...zxcvbnCommonPackage.dictionary,
|
||||
// We could use the english dictionary here too, but it is very big. So we just use the common words
|
||||
//...zxcvbnEnPackage.dictionary,
|
||||
},
|
||||
translations: this._getTranslations(),
|
||||
};
|
||||
zxcvbnOptions.setOptions(options);
|
||||
|
||||
//Add event listener to the password input field
|
||||
this._passwordInput.addEventListener('input', this._onPasswordInput.bind(this));
|
||||
}
|
||||
|
||||
_onPasswordInput() {
|
||||
//Retrieve the password
|
||||
const password = this._passwordInput.value;
|
||||
|
||||
//Estimate the password strength
|
||||
const result = zxcvbn(password);
|
||||
|
||||
//Update the badge
|
||||
this.badgeTarget.parentElement.classList.remove("d-none");
|
||||
this._setBadgeToLevel(result.score);
|
||||
|
||||
this.warningTarget.innerHTML = result.feedback.warning;
|
||||
}
|
||||
|
||||
_setBadgeToLevel(level) {
|
||||
let text, classes;
|
||||
|
||||
switch (level) {
|
||||
case 0:
|
||||
text = trans(USER_PASSWORD_STRENGTH_VERY_WEAK);
|
||||
classes = "bg-danger badge-danger";
|
||||
break;
|
||||
case 1:
|
||||
text = trans(USER_PASSWORD_STRENGTH_WEAK);
|
||||
classes = "bg-warning badge-warning";
|
||||
break;
|
||||
case 2:
|
||||
text = trans(USER_PASSWORD_STRENGTH_MEDIUM)
|
||||
classes = "bg-info badge-info";
|
||||
break;
|
||||
case 3:
|
||||
text = trans(USER_PASSWORD_STRENGTH_STRONG);
|
||||
classes = "bg-primary badge-primary";
|
||||
break;
|
||||
case 4:
|
||||
text = trans(USER_PASSWORD_STRENGTH_VERY_STRONG);
|
||||
classes = "bg-success badge-success";
|
||||
break;
|
||||
default:
|
||||
text = "???";
|
||||
classes = "bg-secondary badge-secondary";
|
||||
}
|
||||
|
||||
this.badgeTarget.innerHTML = text;
|
||||
//Remove all classes
|
||||
this.badgeTarget.className = '';
|
||||
//Re-add the classes
|
||||
this.badgeTarget.classList.add("badge");
|
||||
this.badgeTarget.classList.add(...classes.split(" "));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||
*
|
||||
* Copyright (C) 2019 - 2023 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 "tom-select/dist/css/tom-select.bootstrap5.css";
|
||||
import '../../css/components/tom-select_extensions.css';
|
||||
import TomSelect from "tom-select";
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* The file is just a list of strings, one per line, which will be used as the autocomplete options.
|
||||
* Lines starting with # will be ignored.
|
||||
*/
|
||||
export default class extends Controller {
|
||||
_tomSelect;
|
||||
|
||||
connect() {
|
||||
|
||||
let settings = {
|
||||
persistent: false,
|
||||
create: true,
|
||||
maxItems: 1,
|
||||
maxOptions: 100,
|
||||
createOnBlur: true,
|
||||
selectOnTab: true,
|
||||
valueField: 'text',
|
||||
searchField: 'text',
|
||||
orderField: 'text',
|
||||
|
||||
//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'
|
||||
};
|
||||
|
||||
if (this.element.dataset.url) {
|
||||
const url = this.element.dataset.url;
|
||||
settings.load = (query, callback) => {
|
||||
const self = this;
|
||||
if (self.loading > 1) {
|
||||
callback();
|
||||
return;
|
||||
}
|
||||
|
||||
fetch(url)
|
||||
.then(response => response.text())
|
||||
.then(text => {
|
||||
// Convert the text file to array
|
||||
let lines = text.split("\n");
|
||||
//Remove all lines beginning with #
|
||||
lines = lines.filter(x => !x.startsWith("#"));
|
||||
|
||||
//Convert the array to an object, where each line is in the text field
|
||||
lines = lines.map(x => {
|
||||
return {text: x};
|
||||
});
|
||||
|
||||
|
||||
//Unset the load function to prevent endless recursion
|
||||
self._tomSelect.settings.load = null;
|
||||
|
||||
callback(lines);
|
||||
}).catch(() => {
|
||||
callback();
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
this._tomSelect = new TomSelect(this.element, settings);
|
||||
}
|
||||
|
||||
disconnect() {
|
||||
super.disconnect();
|
||||
//Destroy the TomSelect instance
|
||||
this._tomSelect.destroy();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -22,6 +22,8 @@ import '../../css/components/tom-select_extensions.css';
|
||||
import TomSelect from "tom-select";
|
||||
import {Controller} from "@hotwired/stimulus";
|
||||
|
||||
import {trans, ENTITY_SELECT_GROUP_NEW_NOT_ADDED_TO_DB} from '../../translator.js'
|
||||
|
||||
|
||||
export default class extends Controller {
|
||||
_tomSelect;
|
||||
@@ -40,8 +42,7 @@ export default class extends Controller {
|
||||
allowEmptyOption: true,
|
||||
selectOnTab: true,
|
||||
maxOptions: null,
|
||||
create: allowAdd,
|
||||
createFilter: /\D/, //Must contain a non-digit character, otherwise they would be recognized as DB ID
|
||||
create: allowAdd ? this.createItem.bind(this) : false,
|
||||
|
||||
searchField: [
|
||||
{field: "text", weight : 2},
|
||||
@@ -57,10 +58,39 @@ export default class extends Controller {
|
||||
'<small class="text-muted float-end">(' + addHint +')</small>' +
|
||||
'</div>';
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
//Add callbacks to update validity
|
||||
onInitialize: this.updateValidity.bind(this),
|
||||
onChange: this.updateValidity.bind(this),
|
||||
};
|
||||
|
||||
this._tomSelect = new TomSelect(this.element, settings);
|
||||
//Do not do a sync here as this breaks the initial rendering of the empty option
|
||||
//this._tomSelect.sync();
|
||||
}
|
||||
|
||||
createItem(input, callback) {
|
||||
callback({
|
||||
//$%$ is a special value prefix, that is used to identify items, that are not yet in the DB
|
||||
value: '$%$' + input,
|
||||
text: input,
|
||||
not_in_db_yet: true,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
updateValidity() {
|
||||
//Mark this input as invalid, if the selected option is disabled
|
||||
|
||||
const input = this.element;
|
||||
const selectedOption = input.options[input.selectedIndex];
|
||||
|
||||
if (selectedOption && selectedOption.disabled) {
|
||||
input.setCustomValidity("This option was disabled. Please select another option.");
|
||||
} else {
|
||||
input.setCustomValidity("");
|
||||
}
|
||||
}
|
||||
|
||||
getTomSelect() {
|
||||
@@ -78,14 +108,27 @@ export default class extends Controller {
|
||||
}
|
||||
|
||||
if (data.short) {
|
||||
return '<div><b>' + escape(data.short) + '</b></div>';
|
||||
let short = escape(data.short)
|
||||
|
||||
//Make text italic, if the item is not yet in the DB
|
||||
if (data.not_in_db_yet) {
|
||||
short = '<i>' + short + '</i>';
|
||||
}
|
||||
|
||||
return '<div><b>' + short + '</b></div>';
|
||||
}
|
||||
|
||||
let name = "";
|
||||
if (data.parent) {
|
||||
name += escape(data.parent) + " → ";
|
||||
}
|
||||
name += "<b>" + escape(data.text) + "</b>";
|
||||
|
||||
if (data.not_in_db_yet) {
|
||||
//Not yet added items are shown italic and with a badge
|
||||
name += "<i><b>" + escape(data.text) + "</b></i>" + "<span class='ms-3 badge bg-info badge-info'>" + trans(ENTITY_SELECT_GROUP_NEW_NOT_ADDED_TO_DB) + "</span>";
|
||||
} else {
|
||||
name += "<b>" + escape(data.text) + "</b>";
|
||||
}
|
||||
|
||||
return '<div>' + (data.image ? "<img class='structural-entity-select-image' style='margin-right: 5px;' ' src='" + data.image + "'/>" : "") + name + '</div>';
|
||||
}
|
||||
|
||||
@@ -81,6 +81,14 @@ export default class extends Controller {
|
||||
this._tree.remove();
|
||||
}
|
||||
|
||||
const BS53Theme = {
|
||||
getOptions() {
|
||||
return {
|
||||
onhoverColor: 'var(--bs-secondary-bg)',
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
this._tree = new BSTreeView(this.treeTarget, {
|
||||
levels: 1,
|
||||
showTags: this._showTags,
|
||||
@@ -93,7 +101,7 @@ export default class extends Controller {
|
||||
}
|
||||
},
|
||||
//onNodeContextmenu: contextmenu_handler,
|
||||
}, [BS5Theme, FAIconTheme]);
|
||||
}, [BS5Theme, BS53Theme, FAIconTheme]);
|
||||
|
||||
this.treeTarget.addEventListener(EVENT_INITIALIZED, (event) => {
|
||||
/** @type {BSTreeView} */
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||
*
|
||||
* Copyright (C) 2019 - 2023 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";
|
||||
|
||||
export default class extends Controller {
|
||||
|
||||
static targets = [ "display", "select" ]
|
||||
|
||||
connect()
|
||||
{
|
||||
this.update();
|
||||
this.selectTarget.addEventListener('change', this.update.bind(this));
|
||||
}
|
||||
|
||||
update()
|
||||
{
|
||||
//If the select value is 0, then we show the input field
|
||||
if( this.selectTarget.value === '0')
|
||||
{
|
||||
this.displayTarget.classList.remove('d-none');
|
||||
}
|
||||
else
|
||||
{
|
||||
this.displayTarget.classList.add('d-none');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||
*
|
||||
* Copyright (C) 2019 - 2022 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";
|
||||
|
||||
/**
|
||||
* This controller is used on a checkbox, which toggles the max value of all number input fields
|
||||
*/
|
||||
export default class extends Controller {
|
||||
|
||||
_checkbox;
|
||||
|
||||
getCheckbox() {
|
||||
if (this._checkbox) {
|
||||
return this._checkbox;
|
||||
}
|
||||
|
||||
//Find the checkbox inside the controller element
|
||||
this._checkbox = this.element.querySelector('input[type="checkbox"]');
|
||||
return this._checkbox;
|
||||
}
|
||||
|
||||
connect() {
|
||||
//Add event listener to the checkbox
|
||||
this.getCheckbox().addEventListener('change', this.toggleInputLimits.bind(this));
|
||||
}
|
||||
|
||||
toggleInputLimits() {
|
||||
//Find all input fields with the data-toggle-input-limits-target="max"
|
||||
const inputFields = document.querySelectorAll("input[type='number']");
|
||||
|
||||
inputFields.forEach((inputField) => {
|
||||
//Ensure that the input field has either a max or a data-max attribute
|
||||
if (!inputField.hasAttribute('max') && !inputField.hasAttribute('data-max')) {
|
||||
return;
|
||||
}
|
||||
|
||||
//If the checkbox is checked, rename the max attribute to data-max
|
||||
if (this.getCheckbox().checked) {
|
||||
inputField.setAttribute('data-max', inputField.getAttribute('max'));
|
||||
inputField.removeAttribute('max');
|
||||
} else {
|
||||
//If the checkbox is not checked, rename the data-max attribute back to max
|
||||
inputField.setAttribute('max', inputField.getAttribute('data-max'));
|
||||
inputField.removeAttribute('data-max');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
68
assets/controllers/pages/part_merge_modal_controller.js
Normal file
68
assets/controllers/pages/part_merge_modal_controller.js
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||
*
|
||||
* Copyright (C) 2019 - 2023 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";
|
||||
|
||||
export default class extends Controller
|
||||
{
|
||||
static targets = ['link', 'mode', 'otherSelect'];
|
||||
static values = {
|
||||
targetId: Number,
|
||||
};
|
||||
|
||||
connect() {
|
||||
}
|
||||
|
||||
update() {
|
||||
const link = this.linkTarget;
|
||||
const other_select = this.otherSelectTarget;
|
||||
|
||||
//Extract the mode using the mode radio buttons (we filter the array to get the checked one)
|
||||
const mode = (this.modeTargets.filter((e)=>e.checked))[0].value;
|
||||
|
||||
if (other_select.value === '') {
|
||||
link.classList.add('disabled');
|
||||
return;
|
||||
}
|
||||
|
||||
//Extract href template from data attribute on link target
|
||||
let href = link.getAttribute('data-href-template');
|
||||
|
||||
let target, other;
|
||||
if (mode === '1') {
|
||||
target = this.targetIdValue;
|
||||
other = other_select.value;
|
||||
} else if (mode === '2') {
|
||||
target = other_select.value;
|
||||
other = this.targetIdValue;
|
||||
} else {
|
||||
throw 'Invalid mode';
|
||||
}
|
||||
|
||||
//Replace placeholder with actual target id
|
||||
href = href.replace('__target__', target);
|
||||
//Replace placeholder with selected value of the select (the event sender)
|
||||
href = href.replace('__other__', other);
|
||||
|
||||
//Assign new href to link
|
||||
link.setAttribute('href', href);
|
||||
//Make link clickable
|
||||
link.classList.remove('disabled');
|
||||
}
|
||||
}
|
||||
@@ -99,10 +99,25 @@ label:not(.form-check-label, .custom-control-label) {
|
||||
|
||||
form .col-form-label.required:after, form label.required:after {
|
||||
bottom: 4px;
|
||||
color: var(--bs-dark);
|
||||
color: var(--bs-secondary-color);
|
||||
content: "\2022";
|
||||
filter: opacity(75%);
|
||||
position: relative;
|
||||
right: -2px;
|
||||
z-index: 700;
|
||||
}
|
||||
|
||||
/****************************************
|
||||
* HTML diff styling
|
||||
****************************************/
|
||||
|
||||
/* Insertations are marked with green background and bold */
|
||||
ins {
|
||||
background-color: #95f095;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
del {
|
||||
background-color: #f09595;
|
||||
font-weight: bold;
|
||||
}
|
||||
@@ -67,7 +67,6 @@ ul.structural_link {
|
||||
padding-bottom: 7px;
|
||||
padding-left: 0;
|
||||
list-style: none;
|
||||
background-color: inherit;
|
||||
}
|
||||
|
||||
/* Display list items side by side */
|
||||
@@ -79,7 +78,7 @@ ul.structural_link li {
|
||||
/* Add a slash symbol (/) before/behind each list item */
|
||||
ul.structural_link li+li:before {
|
||||
padding: 2px;
|
||||
color: grey;
|
||||
color: var(--bs-tertiary-color);
|
||||
/*content: "/\00a0";*/
|
||||
font-family: "Font Awesome 5 Free";
|
||||
font-weight: 900;
|
||||
@@ -89,13 +88,13 @@ ul.structural_link li+li:before {
|
||||
|
||||
/* Add a color to all links inside the list */
|
||||
ul.structural_link li a {
|
||||
color: #0275d8;
|
||||
color: var(--bs-link-color);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/* Add a color on mouse-over */
|
||||
ul.structural_link li a:hover {
|
||||
color: #01447e;
|
||||
color: var(--bs-link-hover-color);
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
|
||||
@@ -78,8 +78,6 @@ body {
|
||||
overflow: -moz-scrollbars-none;
|
||||
/* Use standard version for hiding the scrollbar */
|
||||
scrollbar-width: none;
|
||||
|
||||
background-color: var(--light);
|
||||
}
|
||||
|
||||
#sidebar-container {
|
||||
|
||||
@@ -91,7 +91,7 @@ th.select-checkbox {
|
||||
/** Fix datatables select-checkbox position */
|
||||
table.dataTable tr.selected td.select-checkbox:after
|
||||
{
|
||||
margin-top: -28px !important;
|
||||
margin-top: -20px !important;
|
||||
}
|
||||
|
||||
|
||||
@@ -116,23 +116,33 @@ table.dataTable > thead > tr > th.select-checkbox:before,
|
||||
table.dataTable > thead > tr > th.select-checkbox:after {
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: 1.2em;
|
||||
top: 0.9em;
|
||||
left: 50%;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
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: 1px solid black;
|
||||
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: -23px;
|
||||
margin-top: -20px;
|
||||
margin-left: -6px;
|
||||
text-align: center;
|
||||
/*text-shadow: 1px 1px #B0BED9, -1px -1px #B0BED9, 1px -1px #B0BED9, -1px 1px #B0BED9; */
|
||||
|
||||
@@ -36,3 +36,42 @@
|
||||
.ck-html-label .ck-content hr {
|
||||
margin: 2px;
|
||||
}
|
||||
|
||||
/***********************************************
|
||||
* Hide CKEditor powered by message
|
||||
***********************************************/
|
||||
.ck-powered-by {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/***********************************************
|
||||
* Use Bootstrap color vars for CKEditor
|
||||
***********************************************/
|
||||
:root {
|
||||
--ck-color-base-foreground: var(--bs-secondary-bg);
|
||||
--ck-color-base-background: var(--bs-body-bg);
|
||||
--ck-color-base-border: var(--bs-border-color);
|
||||
--ck-color-base-action: var(--bs-success);
|
||||
--ck-color-base-focus: var(--bs-primary-border-subtle);
|
||||
--ck-color-base-text: var(--bs-body-color);
|
||||
--ck-color-base-active: var(--bs-primary-bg-subtle);
|
||||
--ck-color-base-active-focus: var(--bs-primary);
|
||||
--ck-color-base-error: var(--bs-danger);
|
||||
|
||||
/* Improve contrast between text and toolbar */
|
||||
--ck-color-toolbar-background: var(--bs-tertiary-bg);
|
||||
|
||||
/* Buttons */
|
||||
--ck-color-button-default-hover-background: var(--bs-secondary-bg);
|
||||
--ck-color-button-default-active-background: var(--bs-secondary-bg);
|
||||
|
||||
--ck-color-button-on-background: var(--bs-body-bg);
|
||||
--ck-color-button-on-hover-background: var(--bs-secondary-bg);
|
||||
--ck-color-button-on-active-background: var(--bs-secondary-bg);
|
||||
--ck-color-button-on-disabled-background: var(--bs-secondary-bg);
|
||||
--ck-color-button-on-color: var(--bs-primary)
|
||||
|
||||
}
|
||||
@@ -18,6 +18,29 @@
|
||||
*/
|
||||
|
||||
.tagsinput.ts-wrapper.multi .ts-control > div {
|
||||
background: var(--bs-secondary);
|
||||
color: var(--bs-white);
|
||||
}
|
||||
background: var(--bs-secondary-bg);
|
||||
color: var(--bs-body-color);
|
||||
}
|
||||
|
||||
/*********
|
||||
* BS 5.3 compatible dark mode
|
||||
***************/
|
||||
|
||||
.ts-dropdown .active {
|
||||
background-color: var(--bs-secondary-bg) !important;
|
||||
color: var(--bs-body-color) !important;
|
||||
}
|
||||
|
||||
.ts-dropdown, .ts-control, .ts-control input {
|
||||
color: var(--bs-body-color) !important;
|
||||
}
|
||||
|
||||
.ts-dropdown, .ts-dropdown.form-control, .ts-dropdown.form-select {
|
||||
background: var(--bs-body-bg);
|
||||
}
|
||||
|
||||
.ts-dropdown .optgroup-header {
|
||||
color: var(--bs-tertiary-color);
|
||||
background: var(--bs-body-bg);
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
3
assets/fonts/dompdf/.gitignore
vendored
Normal file
3
assets/fonts/dompdf/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
# Ignore font files
|
||||
*.otf
|
||||
*.ttf
|
||||
1
assets/fonts/dompdf/README.md
Normal file
1
assets/fonts/dompdf/README.md
Normal file
@@ -0,0 +1 @@
|
||||
Put your font ttf files in this folder to make them available to the label generator.
|
||||
@@ -22,7 +22,6 @@
|
||||
|
||||
import '../css/app/layout.css';
|
||||
import '../css/app/helpers.css';
|
||||
import '../css/app/darkmode.css';
|
||||
import '../css/app/tables.css';
|
||||
import '../css/app/bs-overrides.css';
|
||||
import '../css/app/treeview.css';
|
||||
|
||||
@@ -27,7 +27,9 @@ class ErrorHandlerHelper {
|
||||
constructor() {
|
||||
console.log('Error Handler registered');
|
||||
|
||||
const content = document.getElementById('content');
|
||||
//const content = document.getElementById('content');
|
||||
//It seems that the content element is unreliable for these events, so we use the document instead
|
||||
const content = document;
|
||||
//content.addEventListener('turbo:before-fetch-response', (event) => this.handleError(event));
|
||||
content.addEventListener('turbo:fetch-request-error', (event) => this.handleError(event));
|
||||
content.addEventListener('turbo:frame-missing', (event) => this.handleError(event));
|
||||
@@ -37,6 +39,55 @@ class ErrorHandlerHelper {
|
||||
|
||||
_showAlert(statusText, statusCode, location, responseHTML)
|
||||
{
|
||||
const httpStatusToText = {
|
||||
'200': 'OK',
|
||||
'201': 'Created',
|
||||
'202': 'Accepted',
|
||||
'203': 'Non-Authoritative Information',
|
||||
'204': 'No Content',
|
||||
'205': 'Reset Content',
|
||||
'206': 'Partial Content',
|
||||
'300': 'Multiple Choices',
|
||||
'301': 'Moved Permanently',
|
||||
'302': 'Found',
|
||||
'303': 'See Other',
|
||||
'304': 'Not Modified',
|
||||
'305': 'Use Proxy',
|
||||
'306': 'Unused',
|
||||
'307': 'Temporary Redirect',
|
||||
'400': 'Bad Request',
|
||||
'401': 'Unauthorized',
|
||||
'402': 'Payment Required',
|
||||
'403': 'Forbidden',
|
||||
'404': 'Not Found',
|
||||
'405': 'Method Not Allowed',
|
||||
'406': 'Not Acceptable',
|
||||
'407': 'Proxy Authentication Required',
|
||||
'408': 'Request Timeout',
|
||||
'409': 'Conflict',
|
||||
'410': 'Gone',
|
||||
'411': 'Length Required',
|
||||
'412': 'Precondition Required',
|
||||
'413': 'Request Entry Too Large',
|
||||
'414': 'Request-URI Too Long',
|
||||
'415': 'Unsupported Media Type',
|
||||
'416': 'Requested Range Not Satisfiable',
|
||||
'417': 'Expectation Failed',
|
||||
'418': 'I\'m a teapot',
|
||||
'429': 'Too Many Requests',
|
||||
'500': 'Internal Server Error',
|
||||
'501': 'Not Implemented',
|
||||
'502': 'Bad Gateway',
|
||||
'503': 'Service Unavailable',
|
||||
'504': 'Gateway Timeout',
|
||||
'505': 'HTTP Version Not Supported',
|
||||
};
|
||||
|
||||
//If the statusText is empty, we use the status code as text
|
||||
if (!statusText) {
|
||||
statusText = httpStatusToText[statusCode];
|
||||
}
|
||||
|
||||
//Create error text
|
||||
const title = statusText + ' (Status ' + statusCode + ')';
|
||||
|
||||
@@ -104,6 +155,12 @@ class ErrorHandlerHelper {
|
||||
return;
|
||||
}
|
||||
|
||||
//Skip 404 errors, on admin pages (as this causes a popup on deletion in firefox)
|
||||
if (response.status == 404 && event.target.id === 'admin-content-frame') {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if(!response.ok) {
|
||||
response.text().then(responseHTML => {
|
||||
this._showAlert(response.statusText, response.status, response.url, responseHTML);
|
||||
|
||||
@@ -47,7 +47,8 @@
|
||||
method: config.method,
|
||||
data: {
|
||||
_dt: config.name,
|
||||
_init: true
|
||||
_init: true,
|
||||
order: config.initial_order ?? undefined,
|
||||
}
|
||||
}).done(function(data) {
|
||||
var baseState;
|
||||
@@ -72,6 +73,17 @@
|
||||
}
|
||||
} else {
|
||||
request._dt = config.name;
|
||||
|
||||
//Try to resolve the original column index when the column was reordered (using the ColReorder plugin)
|
||||
//Only do this when _ColReorder_iOrigCol is available
|
||||
if (settings.aoColumns && settings.aoColumns.length && settings.aoColumns[0]._ColReorder_iOrigCol !== undefined) {
|
||||
if (request.order && request.order.length) {
|
||||
request.order.forEach(function (order) {
|
||||
order.column = settings.aoColumns[order.column]._ColReorder_iOrigCol;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
$.ajax(typeof config.url === 'function' ? config.url(dt) : config.url, {
|
||||
method: config.method,
|
||||
data: request
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
'use strict';
|
||||
|
||||
import {Dropdown} from "bootstrap";
|
||||
import ClipboardJS from "clipboard";
|
||||
|
||||
class RegisterEventHelper {
|
||||
constructor() {
|
||||
@@ -27,6 +28,11 @@ class RegisterEventHelper {
|
||||
this.configureDropdowns();
|
||||
this.registerSpecialCharInput();
|
||||
|
||||
//Initialize ClipboardJS
|
||||
this.registerLoadHandler(() => {
|
||||
new ClipboardJS('.btn');
|
||||
})
|
||||
|
||||
this.registerModalDropRemovalOnFormSubmit();
|
||||
}
|
||||
|
||||
@@ -59,76 +65,239 @@ class RegisterEventHelper {
|
||||
}
|
||||
|
||||
registerTooltips() {
|
||||
this.registerLoadHandler(() => {
|
||||
const handler = () => {
|
||||
$(".tooltip").remove();
|
||||
//Exclude dropdown buttons from tooltips, otherwise we run into endless errors from bootstrap (bootstrap.esm.js:614 Bootstrap doesn't allow more than one instance per element. Bound instance: bs.dropdown.)
|
||||
$('a[title], button[title]:not([data-bs-toggle="dropdown"]), p[title], span[title], h6[title], h3[title], i.fas[title]')
|
||||
$('a[title], label[title], button[title]:not([data-bs-toggle="dropdown"]), p[title], span[title], h6[title], h3[title], i[title], small[title]')
|
||||
//@ts-ignore
|
||||
.tooltip("hide").tooltip({container: "body", placement: "auto", boundary: 'window'});
|
||||
});
|
||||
};
|
||||
|
||||
this.registerLoadHandler(handler);
|
||||
document.addEventListener('dt:loaded', handler);
|
||||
}
|
||||
|
||||
registerSpecialCharInput() {
|
||||
this.registerLoadHandler(() => {
|
||||
//@ts-ignore
|
||||
$("input[type=text], input[type=search]").unbind("keydown").keydown(function (event) {
|
||||
let greek = event.altKey;
|
||||
let use_special_char = event.altKey;
|
||||
|
||||
let greek_char = "";
|
||||
if (greek){
|
||||
if (use_special_char){
|
||||
//Use the key property to determine the greek letter (as it is independent of the keyboard layout)
|
||||
switch(event.key) {
|
||||
case "w": //Omega
|
||||
greek_char = '\u2126';
|
||||
break;
|
||||
case "u":
|
||||
case "m": //Micro
|
||||
greek_char = "\u00B5";
|
||||
break;
|
||||
case "p": //Phi
|
||||
greek_char = "\u03C6";
|
||||
break;
|
||||
case "a": //Alpha
|
||||
//Greek letters
|
||||
case "a": //Alpha (lowercase)
|
||||
greek_char = "\u03B1";
|
||||
break;
|
||||
case "b": //Beta
|
||||
case "A": //Alpha (uppercase)
|
||||
greek_char = "\u0391";
|
||||
break;
|
||||
case "b": //Beta (lowercase)
|
||||
greek_char = "\u03B2";
|
||||
break;
|
||||
case "c": //Gamma
|
||||
case "B": //Beta (uppercase)
|
||||
greek_char = "\u0392";
|
||||
break;
|
||||
case "g": //Gamma (lowercase)
|
||||
greek_char = "\u03B3";
|
||||
break;
|
||||
case "d": //Delta
|
||||
case "G": //Gamma (uppercase)
|
||||
greek_char = "\u0393";
|
||||
break;
|
||||
case "d": //Delta (lowercase)
|
||||
greek_char = "\u03B4";
|
||||
break;
|
||||
case "l": //Pound
|
||||
greek_char = "\u00A3";
|
||||
case "D": //Delta (uppercase)
|
||||
greek_char = "\u0394";
|
||||
break;
|
||||
case "y": //Yen
|
||||
greek_char = "\u00A5";
|
||||
case "e": //Epsilon (lowercase)
|
||||
greek_char = "\u03B5";
|
||||
break;
|
||||
case "o": //Yen
|
||||
greek_char = "\u00A4";
|
||||
case "E": //Epsilon (uppercase)
|
||||
greek_char = "\u0395";
|
||||
break;
|
||||
case "1": //Sum symbol
|
||||
greek_char = "\u2211";
|
||||
case "z": //Zeta (lowercase)
|
||||
greek_char = "\u03B6";
|
||||
break;
|
||||
case "2": //Integral
|
||||
greek_char = "\u222B";
|
||||
case "Z": //Zeta (uppercase)
|
||||
greek_char = "\u0396";
|
||||
break;
|
||||
case "3": //Less-than or equal
|
||||
greek_char = "\u2264";
|
||||
case "h": //Eta (lowercase)
|
||||
greek_char = "\u03B7";
|
||||
break;
|
||||
case "4": //Greater than or equal
|
||||
greek_char = "\u2265";
|
||||
case "H": //Eta (uppercase)
|
||||
greek_char = "\u0397";
|
||||
break;
|
||||
case "5": //PI
|
||||
greek_char = "\u03c0";
|
||||
case "q": //Theta (lowercase)
|
||||
greek_char = "\u03B8";
|
||||
break;
|
||||
case "q": //Copyright
|
||||
greek_char = "\u00A9";
|
||||
case "Q": //Theta (uppercase)
|
||||
greek_char = "\u0398";
|
||||
break;
|
||||
case "e": //Euro
|
||||
greek_char = "\u20AC";
|
||||
case "i": //Iota (lowercase)
|
||||
greek_char = "\u03B9";
|
||||
break;
|
||||
case "I": //Iota (uppercase)
|
||||
greek_char = "\u0399";
|
||||
break;
|
||||
case "k": //Kappa (lowercase)
|
||||
greek_char = "\u03BA";
|
||||
break;
|
||||
case "K": //Kappa (uppercase)
|
||||
greek_char = "\u039A";
|
||||
break;
|
||||
case "l": //Lambda (lowercase)
|
||||
greek_char = "\u03BB";
|
||||
break;
|
||||
case "L": //Lambda (uppercase)
|
||||
greek_char = "\u039B";
|
||||
break;
|
||||
case "m": //Mu (lowercase)
|
||||
greek_char = "\u03BC";
|
||||
break;
|
||||
case "M": //Mu (uppercase)
|
||||
greek_char = "\u039C";
|
||||
break;
|
||||
case "n": //Nu (lowercase)
|
||||
greek_char = "\u03BD";
|
||||
break;
|
||||
case "N": //Nu (uppercase)
|
||||
greek_char = "\u039D";
|
||||
break;
|
||||
case "x": //Xi (lowercase)
|
||||
greek_char = "\u03BE";
|
||||
break;
|
||||
case "X": //Xi (uppercase)
|
||||
greek_char = "\u039E";
|
||||
break;
|
||||
case "o": //Omicron (lowercase)
|
||||
greek_char = "\u03BF";
|
||||
break;
|
||||
case "O": //Omicron (uppercase)
|
||||
greek_char = "\u039F";
|
||||
break;
|
||||
case "p": //Pi (lowercase)
|
||||
greek_char = "\u03C0";
|
||||
break;
|
||||
case "P": //Pi (uppercase)
|
||||
greek_char = "\u03A0";
|
||||
break;
|
||||
case "r": //Rho (lowercase)
|
||||
greek_char = "\u03C1";
|
||||
break;
|
||||
case "R": //Rho (uppercase)
|
||||
greek_char = "\u03A1";
|
||||
break;
|
||||
case "s": //Sigma (lowercase)
|
||||
greek_char = "\u03C3";
|
||||
break;
|
||||
case "S": //Sigma (uppercase)
|
||||
greek_char = "\u03A3";
|
||||
break;
|
||||
case "t": //Tau (lowercase)
|
||||
greek_char = "\u03C4";
|
||||
break;
|
||||
case "T": //Tau (uppercase)
|
||||
greek_char = "\u03A4";
|
||||
break;
|
||||
case "u": //Upsilon (lowercase)
|
||||
greek_char = "\u03C5";
|
||||
break;
|
||||
case "U": //Upsilon (uppercase)
|
||||
greek_char = "\u03A5";
|
||||
break;
|
||||
case "f": //Phi (lowercase)
|
||||
greek_char = "\u03C6";
|
||||
break;
|
||||
case "F": //Phi (uppercase)
|
||||
greek_char = "\u03A6";
|
||||
break;
|
||||
case "c": //Chi (lowercase)
|
||||
greek_char = "\u03C7";
|
||||
break;
|
||||
case "C": //Chi (uppercase)
|
||||
greek_char = "\u03A7";
|
||||
break;
|
||||
case "y": //Psi (lowercase)
|
||||
greek_char = "\u03C8";
|
||||
break;
|
||||
case "Y": //Psi (uppercase)
|
||||
greek_char = "\u03A8";
|
||||
break;
|
||||
case "w": //Omega (lowercase)
|
||||
greek_char = "\u03C9";
|
||||
break;
|
||||
case "W": //Omega (uppercase)
|
||||
greek_char = "\u03A9";
|
||||
break;
|
||||
}
|
||||
|
||||
//Use keycodes for special characters as the shift char on the number keys are layout dependent
|
||||
switch (event.keyCode) {
|
||||
case 49: //1 key
|
||||
//Product symbol on shift, sum on no shift
|
||||
greek_char = event.shiftKey ? "\u220F" : "\u2211";
|
||||
break;
|
||||
case 50: //2 key
|
||||
//Integral on no shift, partial derivative on shift
|
||||
greek_char = event.shiftKey ? "\u2202" : "\u222B";
|
||||
break;
|
||||
case 51: //3 key
|
||||
//Less than or equal on no shift, greater than or equal on shift
|
||||
greek_char = event.shiftKey ? "\u2265" : "\u2264";
|
||||
break;
|
||||
case 52: //4 key
|
||||
//Empty set on shift, infinity on no shift
|
||||
greek_char = event.shiftKey ? "\u2205" : "\u221E";
|
||||
break;
|
||||
case 53: //5 key
|
||||
//Not equal on shift, approx equal on no shift
|
||||
greek_char = event.shiftKey ? "\u2260" : "\u2248";
|
||||
break;
|
||||
case 54: //6 key
|
||||
//Element of on no shift, not element of on shift
|
||||
greek_char = event.shiftKey ? "\u2209" : "\u2208";
|
||||
break;
|
||||
case 55: //7 key
|
||||
//And on shift, or on no shift
|
||||
greek_char = event.shiftKey ? "\u2227" : "\u2228";
|
||||
break;
|
||||
case 56: //8 key
|
||||
//Proportional to on shift, angle on no shift
|
||||
greek_char = event.shiftKey ? "\u221D" : "\u2220";
|
||||
break;
|
||||
case 57: //9 key
|
||||
//Cube root on shift, square root on no shift
|
||||
greek_char = event.shiftKey ? "\u221B" : "\u221A";
|
||||
break;
|
||||
case 48: //0 key
|
||||
//Minus-Plus on shift, plus-minus on no shift
|
||||
greek_char = event.shiftKey ? "\u2213" : "\u00B1";
|
||||
break;
|
||||
|
||||
//Special characters
|
||||
case 219: //hyphen (or ß on german layout)
|
||||
//Copyright on no shift, TM on shift
|
||||
greek_char = event.shiftKey ? "\u2122" : "\u00A9";
|
||||
break;
|
||||
case 191: //forward slash (or # on german layout)
|
||||
//Generic currency on no shift, paragraph on shift
|
||||
greek_char = event.shiftKey ? "\u00B6" : "\u00A4";
|
||||
break;
|
||||
|
||||
//Currency symbols
|
||||
case 192: //: or (ö on german layout)
|
||||
//Euro on no shift, pound on shift
|
||||
greek_char = event.shiftKey ? "\u00A3" : "\u20AC";
|
||||
break;
|
||||
case 221: //; or (ä on german layout)
|
||||
//Yen on no shift, dollar on shift
|
||||
greek_char = event.shiftKey ? "\u0024" : "\u00A5";
|
||||
break;
|
||||
|
||||
|
||||
}
|
||||
|
||||
if(greek_char=="") return;
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
import {Tab} from "bootstrap";
|
||||
import {Tab, Dropdown, Collapse} from "bootstrap";
|
||||
import tab from "bootstrap/js/src/tab";
|
||||
|
||||
/**
|
||||
@@ -54,6 +54,7 @@ class TabRememberHelper {
|
||||
const first_element = merged[0] ?? null;
|
||||
if(first_element) {
|
||||
this.revealElementOnTab(first_element);
|
||||
this.revealElementInCollapse(first_element);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,7 +63,27 @@ class TabRememberHelper {
|
||||
* @param event
|
||||
*/
|
||||
onInvalid(event) {
|
||||
this.revealElementInCollapse(event.target);
|
||||
this.revealElementOnTab(event.target);
|
||||
this.revealElementInDropdown(event.target);
|
||||
}
|
||||
|
||||
revealElementInCollapse(element) {
|
||||
let collapse = element.closest('.collapse');
|
||||
|
||||
if(collapse) {
|
||||
let bs_collapse = Collapse.getOrCreateInstance(collapse);
|
||||
bs_collapse.show();
|
||||
}
|
||||
}
|
||||
|
||||
revealElementInDropdown(element) {
|
||||
let dropdown = element.closest('.dropdown-menu');
|
||||
|
||||
if(dropdown) {
|
||||
let bs_dropdown = Dropdown.getOrCreateInstance(dropdown);
|
||||
bs_dropdown.show();
|
||||
}
|
||||
}
|
||||
|
||||
revealElementOnTab(element) {
|
||||
|
||||
@@ -21,8 +21,13 @@
|
||||
|
||||
class WebauthnTFA {
|
||||
|
||||
// Decodes a Base64Url string
|
||||
_base64UrlDecode = (input) => {
|
||||
_b64UrlSafeEncode = (str) => {
|
||||
const b64 = btoa(str);
|
||||
return b64.replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '');
|
||||
}
|
||||
|
||||
// Decodes a Base64Url string
|
||||
_b64UrlSafeDecode = (input) => {
|
||||
input = input
|
||||
.replace(/-/g, '+')
|
||||
.replace(/_/g, '/');
|
||||
@@ -39,13 +44,16 @@ class WebauthnTFA {
|
||||
};
|
||||
|
||||
// Converts an array of bytes into a Base64Url string
|
||||
_arrayToBase64String = (a) => btoa(String.fromCharCode(...a));
|
||||
_arrayToBase64String = (a) => {
|
||||
const str = String.fromCharCode(...a);
|
||||
return this._b64UrlSafeEncode(str);
|
||||
}
|
||||
|
||||
// Prepares the public key options object returned by the Webauthn Framework
|
||||
_preparePublicKeyOptions = publicKey => {
|
||||
//Convert challenge from Base64Url string to Uint8Array
|
||||
publicKey.challenge = Uint8Array.from(
|
||||
this._base64UrlDecode(publicKey.challenge),
|
||||
this._b64UrlSafeDecode(publicKey.challenge),
|
||||
c => c.charCodeAt(0)
|
||||
);
|
||||
|
||||
@@ -67,7 +75,7 @@ class WebauthnTFA {
|
||||
return {
|
||||
...data,
|
||||
id: Uint8Array.from(
|
||||
this._base64UrlDecode(data.id),
|
||||
this._b64UrlSafeDecode(data.id),
|
||||
c => c.charCodeAt(0)
|
||||
),
|
||||
};
|
||||
@@ -81,7 +89,7 @@ class WebauthnTFA {
|
||||
return {
|
||||
...data,
|
||||
id: Uint8Array.from(
|
||||
this._base64UrlDecode(data.id),
|
||||
this._b64UrlSafeDecode(data.id),
|
||||
c => c.charCodeAt(0)
|
||||
),
|
||||
};
|
||||
|
||||
16
assets/translator.js
Normal file
16
assets/translator.js
Normal file
@@ -0,0 +1,16 @@
|
||||
import { localeFallbacks } from '../var/translations/configuration';
|
||||
import { trans, getLocale, setLocale, setLocaleFallbacks } from '@symfony/ux-translator';
|
||||
/*
|
||||
* This file is part of the Symfony UX Translator package.
|
||||
*
|
||||
* If folder "../var/translations" does not exist, or some translations are missing,
|
||||
* you must warmup your Symfony cache to refresh JavaScript translations.
|
||||
*
|
||||
* If you use TypeScript, you can rename this file to "translator.ts" to take advantage of types checking.
|
||||
*/
|
||||
|
||||
setLocaleFallbacks(localeFallbacks);
|
||||
|
||||
export { trans };
|
||||
|
||||
export * from '../var/translations';
|
||||
@@ -4,6 +4,13 @@
|
||||
use App\Kernel;
|
||||
use Symfony\Bundle\FrameworkBundle\Console\Application;
|
||||
|
||||
//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
|
||||
if (extension_loaded('xdebug') && ((int) ini_get('xdebug.max_nesting_level')) <= 256) {
|
||||
//Increase xdebug.max_nesting_level to 1000
|
||||
ini_set('xdebug.max_nesting_level', '1000');
|
||||
}
|
||||
|
||||
if (!is_file(dirname(__DIR__).'/vendor/autoload_runtime.php')) {
|
||||
throw new LogicException('Symfony Runtime is missing. Try running "composer require symfony/runtime".');
|
||||
}
|
||||
|
||||
10
bin/phpunit
10
bin/phpunit
@@ -6,9 +6,13 @@ if (!ini_get('date.timezone')) {
|
||||
}
|
||||
|
||||
if (is_file(dirname(__DIR__).'/vendor/phpunit/phpunit/phpunit')) {
|
||||
define('PHPUNIT_COMPOSER_INSTALL', dirname(__DIR__).'/vendor/autoload.php');
|
||||
require PHPUNIT_COMPOSER_INSTALL;
|
||||
PHPUnit\TextUI\Command::main();
|
||||
if (PHP_VERSION_ID >= 80000) {
|
||||
require dirname(__DIR__).'/vendor/phpunit/phpunit/phpunit';
|
||||
} else {
|
||||
define('PHPUNIT_COMPOSER_INSTALL', dirname(__DIR__).'/vendor/autoload.php');
|
||||
require PHPUNIT_COMPOSER_INSTALL;
|
||||
PHPUnit\TextUI\Command::main();
|
||||
}
|
||||
} else {
|
||||
if (!is_file(dirname(__DIR__).'/vendor/symfony/phpunit-bridge/bin/simple-phpunit.php')) {
|
||||
echo "Unable to find the `simple-phpunit.php` script in `vendor/symfony/phpunit-bridge/bin/`.\n";
|
||||
|
||||
@@ -5,4 +5,5 @@ coverage:
|
||||
status:
|
||||
project:
|
||||
default:
|
||||
threshold: 5%
|
||||
threshold: 10%
|
||||
target: 40%
|
||||
|
||||
125
composer.json
125
composer.json
@@ -2,101 +2,116 @@
|
||||
"type": "project",
|
||||
"license": "AGPL-3.0-or-later",
|
||||
"require": {
|
||||
"php": "^7.4 || ^8.0",
|
||||
"php": "^8.1",
|
||||
"ext-ctype": "*",
|
||||
"ext-dom": "*",
|
||||
"ext-gd": "*",
|
||||
"ext-iconv": "*",
|
||||
"ext-intl": "*",
|
||||
"ext-json": "*",
|
||||
"ext-mbstring": "*",
|
||||
"api-platform/core": "^3.1",
|
||||
"beberlei/doctrineextensions": "^1.2",
|
||||
"brick/math": "^0.8.15",
|
||||
"composer/package-versions-deprecated": "1.11.99.4",
|
||||
"doctrine/annotations": "^1.6",
|
||||
"brick/math": "0.12.1 as 0.11.0",
|
||||
"composer/ca-bundle": "^1.3",
|
||||
"composer/package-versions-deprecated": "^1.11.99.5",
|
||||
"doctrine/annotations": "1.14.3",
|
||||
"doctrine/data-fixtures": "^1.6.6",
|
||||
"doctrine/dbal": "^3.4.6",
|
||||
"doctrine/doctrine-bundle": "^2.0",
|
||||
"doctrine/doctrine-migrations-bundle": "^3.0",
|
||||
"doctrine/orm": "^2.9",
|
||||
"dompdf/dompdf": "^2.0.0",
|
||||
"doctrine/orm": "^2.16",
|
||||
"dompdf/dompdf": "dev-master#c9cf4be933e2406a51990bd4eb9e70612e790cc0 as v2.0.4",
|
||||
"erusev/parsedown": "^1.7",
|
||||
"florianv/swap": "^4.0",
|
||||
"florianv/swap-bundle": "dev-master",
|
||||
"gregwar/captcha-bundle": "^2.1.0",
|
||||
"hslavich/oneloginsaml-bundle": "^2.10",
|
||||
"jbtronics/2fa-webauthn": "^1.0.0",
|
||||
"jbtronics/2fa-webauthn": "^v2.2.0",
|
||||
"jbtronics/dompdf-font-loader-bundle": "^1.0.0",
|
||||
"jfcherng/php-diff": "^6.14",
|
||||
"knpuniversity/oauth2-client-bundle": "^2.15",
|
||||
"league/csv": "^9.8.0",
|
||||
"league/html-to-markdown": "^5.0.1",
|
||||
"liip/imagine-bundle": "^2.2",
|
||||
"nbgrp/onelogin-saml-bundle": "^1.3",
|
||||
"nelexa/zip": "^4.0",
|
||||
"nelmio/cors-bundle": "^2.3",
|
||||
"nelmio/security-bundle": "^3.0",
|
||||
"nyholm/psr7": "^1.1",
|
||||
"ocramius/proxy-manager": "2.2.*",
|
||||
"omines/datatables-bundle": "^0.5.0",
|
||||
"php-translation/symfony-bundle": "^0.12.0",
|
||||
"omines/datatables-bundle": "^0.8.0",
|
||||
"part-db/label-fonts": "^1.0",
|
||||
"php-translation/symfony-bundle": "^0.14.0",
|
||||
"phpdocumentor/reflection-docblock": "^5.2",
|
||||
"phpstan/phpdoc-parser": "^1.23",
|
||||
"s9e/text-formatter": "^2.1",
|
||||
"scheb/2fa-backup-code": "^5.13",
|
||||
"scheb/2fa-bundle": "^5.13",
|
||||
"scheb/2fa-google-authenticator": "^5.13",
|
||||
"scheb/2fa-trusted-device": "^5.13",
|
||||
"sensio/framework-extra-bundle": "^6.1.1",
|
||||
"scheb/2fa-backup-code": "^6.8.0",
|
||||
"scheb/2fa-bundle": "^6.8.0",
|
||||
"scheb/2fa-google-authenticator": "^6.8.0",
|
||||
"scheb/2fa-trusted-device": "^6.8.0",
|
||||
"shivas/versioning-bundle": "^4.0",
|
||||
"spatie/db-dumper": "^2.21",
|
||||
"spatie/db-dumper": "^3.3.1",
|
||||
"symfony/apache-pack": "^1.0",
|
||||
"symfony/asset": "5.4.*",
|
||||
"symfony/console": "5.4.*",
|
||||
"symfony/dotenv": "5.4.*",
|
||||
"symfony/expression-language": "5.4.*",
|
||||
"symfony/flex": "^1.1",
|
||||
"symfony/form": "5.4.*",
|
||||
"symfony/framework-bundle": "5.4.*",
|
||||
"symfony/http-client": "5.4.*",
|
||||
"symfony/http-kernel": "5.4.*",
|
||||
"symfony/mailer": "5.4.*",
|
||||
"symfony/asset": "6.4.*",
|
||||
"symfony/console": "6.4.*",
|
||||
"symfony/dotenv": "6.4.*",
|
||||
"symfony/expression-language": "6.4.*",
|
||||
"symfony/flex": "^v2.3.1",
|
||||
"symfony/form": "6.4.*",
|
||||
"symfony/framework-bundle": "6.4.*",
|
||||
"symfony/http-client": "6.4.*",
|
||||
"symfony/http-kernel": "6.4.*",
|
||||
"symfony/mailer": "6.4.*",
|
||||
"symfony/monolog-bundle": "^3.1",
|
||||
"symfony/process": "5.4.*",
|
||||
"symfony/property-access": "5.4.*",
|
||||
"symfony/property-info": "5.4.*",
|
||||
"symfony/proxy-manager-bridge": "5.4.*",
|
||||
"symfony/rate-limiter": "5.4.*",
|
||||
"symfony/runtime": "5.4.*",
|
||||
"symfony/security-bundle": "5.4.*",
|
||||
"symfony/serializer": "5.4.*",
|
||||
"symfony/translation": "5.4.*",
|
||||
"symfony/twig-bundle": "5.4.*",
|
||||
"symfony/polyfill-php82": "^1.28",
|
||||
"symfony/process": "6.4.*",
|
||||
"symfony/property-access": "6.4.*",
|
||||
"symfony/property-info": "6.4.*",
|
||||
"symfony/proxy-manager-bridge": "6.4.*",
|
||||
"symfony/rate-limiter": "6.4.*",
|
||||
"symfony/runtime": "6.4.*",
|
||||
"symfony/security-bundle": "6.4.*",
|
||||
"symfony/serializer": "6.4.*",
|
||||
"symfony/string": "6.4.*",
|
||||
"symfony/translation": "6.4.*",
|
||||
"symfony/twig-bundle": "6.4.*",
|
||||
"symfony/ux-translator": "^2.10",
|
||||
"symfony/ux-turbo": "^2.0",
|
||||
"symfony/validator": "5.4.*",
|
||||
"symfony/web-link": "5.4.*",
|
||||
"symfony/webpack-encore-bundle": "^1.1",
|
||||
"symfony/yaml": "5.4.*",
|
||||
"tecnickcom/tc-lib-barcode": "^1.15",
|
||||
"symfony/validator": "6.4.*",
|
||||
"symfony/web-link": "6.4.*",
|
||||
"symfony/webpack-encore-bundle": "^v2.0.1",
|
||||
"symfony/yaml": "6.4.*",
|
||||
"tecnickcom/tc-lib-barcode": "^2.1.4",
|
||||
"twig/cssinliner-extra": "^3.0",
|
||||
"twig/extra-bundle": "^3.0",
|
||||
"twig/html-extra": "^3.0",
|
||||
"twig/inky-extra": "^3.0",
|
||||
"twig/intl-extra": "^3.0",
|
||||
"twig/markdown-extra": "^3.0",
|
||||
"web-auth/webauthn-symfony-bundle": "^3.3",
|
||||
"web-auth/webauthn-symfony-bundle": "^4.0.0",
|
||||
"webmozart/assert": "^1.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"dama/doctrine-test-bundle": "^7.0",
|
||||
"dama/doctrine-test-bundle": "^v8.0.0",
|
||||
"doctrine/doctrine-fixtures-bundle": "^3.2",
|
||||
"ekino/phpstan-banned-code": "^v1.0.0",
|
||||
"phpstan/extension-installer": "^1.0",
|
||||
"phpstan/phpstan": "^1.4.7",
|
||||
"phpstan/phpstan-doctrine": "^1.2.11",
|
||||
"phpstan/phpstan-strict-rules": "^1.5",
|
||||
"phpstan/phpstan-symfony": "^1.1.7",
|
||||
"phpunit/phpunit": "^9.5",
|
||||
"psalm/plugin-symfony": "^v5.0.1",
|
||||
"rector/rector": "^0.18.0",
|
||||
"roave/security-advisories": "dev-latest",
|
||||
"symfony/browser-kit": "^5.2",
|
||||
"symfony/css-selector": "^5.2",
|
||||
"symfony/debug-bundle": "^5.2",
|
||||
"symfony/browser-kit": "6.4.*",
|
||||
"symfony/css-selector": "6.4.*",
|
||||
"symfony/debug-bundle": "6.4.*",
|
||||
"symfony/maker-bundle": "^1.13",
|
||||
"symfony/phpunit-bridge": "5.4.*",
|
||||
"symfony/stopwatch": "^5.2",
|
||||
"symfony/web-profiler-bundle": "^5.2",
|
||||
"symplify/easy-coding-standard": "^11.0",
|
||||
"symfony/phpunit-bridge": "6.4.*",
|
||||
"symfony/stopwatch": "6.4.*",
|
||||
"symfony/web-profiler-bundle": "6.4.*",
|
||||
"symplify/easy-coding-standard": "^12.0",
|
||||
"vimeo/psalm": "^5.6.0"
|
||||
},
|
||||
"suggest": {
|
||||
@@ -108,7 +123,7 @@
|
||||
"*": "dist"
|
||||
},
|
||||
"platform": {
|
||||
"php": "7.4.0"
|
||||
"php": "8.1.0"
|
||||
},
|
||||
"sort-packages": true,
|
||||
"allow-plugins": {
|
||||
@@ -140,7 +155,7 @@
|
||||
"post-update-cmd": [
|
||||
"@auto-scripts"
|
||||
],
|
||||
"phpstan": "vendor/bin/phpstan analyse src --level 2 --memory-limit 1G"
|
||||
"phpstan": "vendor/bin/phpstan analyse src --level 5 --memory-limit 1G"
|
||||
},
|
||||
"conflict": {
|
||||
"symfony/symfony": "*"
|
||||
@@ -148,9 +163,7 @@
|
||||
"extra": {
|
||||
"symfony": {
|
||||
"allow-contrib": false,
|
||||
"require": "5.4.*"
|
||||
"require": "6.4.*"
|
||||
}
|
||||
},
|
||||
"repositories": [
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
9967
composer.lock
generated
9967
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -1,23 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Symfony\Component\Dotenv\Dotenv;
|
||||
|
||||
require dirname(__DIR__).'/vendor/autoload.php';
|
||||
|
||||
if (!class_exists(Dotenv::class)) {
|
||||
throw new LogicException('Please run "composer require symfony/dotenv" to load the ".env" files configuring the application.');
|
||||
}
|
||||
|
||||
// Load cached env vars if the .env.local.php file exists
|
||||
// Run "composer dump-env prod" to create it (requires symfony/flex >=1.2)
|
||||
if (is_array($env = @include dirname(__DIR__).'/.env.local.php') && (!isset($env['APP_ENV']) || ($_SERVER['APP_ENV'] ?? $_ENV['APP_ENV'] ?? $env['APP_ENV']) === $env['APP_ENV'])) {
|
||||
(new Dotenv(false))->populate($env);
|
||||
} else {
|
||||
// load all the .env files
|
||||
(new Dotenv(false))->loadEnv(dirname(__DIR__).'/.env');
|
||||
}
|
||||
|
||||
$_SERVER += $_ENV;
|
||||
$_SERVER['APP_ENV'] = $_ENV['APP_ENV'] = ($_SERVER['APP_ENV'] ?? $_ENV['APP_ENV'] ?? null) ?: 'dev';
|
||||
$_SERVER['APP_DEBUG'] = $_SERVER['APP_DEBUG'] ?? $_ENV['APP_DEBUG'] ?? 'prod' !== $_SERVER['APP_ENV'];
|
||||
$_SERVER['APP_DEBUG'] = $_ENV['APP_DEBUG'] = (int) $_SERVER['APP_DEBUG'] || filter_var($_SERVER['APP_DEBUG'], FILTER_VALIDATE_BOOLEAN) ? '1' : '0';
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
return [
|
||||
Symfony\Bundle\FrameworkBundle\FrameworkBundle::class => ['all' => true],
|
||||
Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle::class => ['all' => true],
|
||||
Doctrine\Bundle\DoctrineBundle\DoctrineBundle::class => ['all' => true],
|
||||
Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle::class => ['all' => true],
|
||||
Symfony\Bundle\SecurityBundle\SecurityBundle::class => ['all' => true],
|
||||
@@ -27,5 +26,11 @@ return [
|
||||
Scheb\TwoFactorBundle\SchebTwoFactorBundle::class => ['all' => true],
|
||||
SpomkyLabs\CborBundle\SpomkyLabsCborBundle::class => ['all' => true],
|
||||
Webauthn\Bundle\WebauthnBundle::class => ['all' => true],
|
||||
Hslavich\OneloginSamlBundle\HslavichOneloginSamlBundle::class => ['all' => true],
|
||||
Nbgrp\OneloginSamlBundle\NbgrpOneloginSamlBundle::class => ['all' => true],
|
||||
Symfony\UX\StimulusBundle\StimulusBundle::class => ['all' => true],
|
||||
Symfony\UX\Translator\UxTranslatorBundle::class => ['all' => true],
|
||||
Jbtronics\DompdfFontLoaderBundle\DompdfFontLoaderBundle::class => ['all' => true],
|
||||
KnpU\OAuth2ClientBundle\KnpUOAuth2ClientBundle::class => ['all' => true],
|
||||
Nelmio\CorsBundle\NelmioCorsBundle::class => ['all' => true],
|
||||
ApiPlatform\Symfony\Bundle\ApiPlatformBundle::class => ['all' => true],
|
||||
];
|
||||
|
||||
36
config/packages/api_platform.yaml
Normal file
36
config/packages/api_platform.yaml
Normal file
@@ -0,0 +1,36 @@
|
||||
api_platform:
|
||||
title: 'Part-DB API'
|
||||
description: 'API of Part-DB'
|
||||
version: '0.1.0'
|
||||
|
||||
formats:
|
||||
jsonld: ['application/ld+json']
|
||||
json: ['application/json']
|
||||
jsonapi: ['application/vnd.api+json']
|
||||
|
||||
docs_formats:
|
||||
jsonld: ['application/ld+json']
|
||||
jsonopenapi: ['application/vnd.openapi+json']
|
||||
html: ['text/html']
|
||||
json: ['application/vnd.openapi+json']
|
||||
|
||||
swagger:
|
||||
api_keys:
|
||||
# overridden in OpenApiFactoryDecorator
|
||||
access_token:
|
||||
name: Authorization
|
||||
type: header
|
||||
|
||||
defaults:
|
||||
# TODO: Change this to true later. In the moment it is false, because we use the session in somewhere
|
||||
stateless: false
|
||||
cache_headers:
|
||||
vary: ['Content-Type', 'Authorization', 'Origin']
|
||||
extra_properties:
|
||||
standard_put: true
|
||||
rfc_7807_compliant_errors: true
|
||||
|
||||
pagination_client_items_per_page: true # Allow clients to override the default items per page
|
||||
|
||||
keep_legacy_inflector: false
|
||||
event_listeners_backward_compatibility_layer: false
|
||||
@@ -20,3 +20,6 @@ framework:
|
||||
tree.cache:
|
||||
adapter: cache.app
|
||||
tags: true
|
||||
|
||||
info_provider.cache:
|
||||
adapter: cache.app
|
||||
|
||||
@@ -9,7 +9,7 @@ datatables:
|
||||
# Set options, as documented at https://datatables.net/reference/option/
|
||||
options:
|
||||
lengthMenu : [[10, 25, 50, 100, -1], [10, 25, 50, 100, "All"]]
|
||||
pageLength: 50
|
||||
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' B l> <'col mb-2' <'pull-end' p>>>
|
||||
<'card'
|
||||
|
||||
@@ -2,6 +2,9 @@ doctrine:
|
||||
dbal:
|
||||
url: '%env(resolve:DATABASE_URL)%'
|
||||
|
||||
# Required for DAMA doctrine test bundle
|
||||
use_savepoints: true
|
||||
|
||||
# IMPORTANT: You MUST configure your server version,
|
||||
# either here or in the DATABASE_URL env var (see .env file)
|
||||
|
||||
@@ -12,6 +15,8 @@ doctrine:
|
||||
class: App\Doctrine\Types\UTCDateTimeType
|
||||
big_decimal:
|
||||
class: App\Doctrine\Types\BigDecimalType
|
||||
tinyint:
|
||||
class: App\Doctrine\Types\TinyIntType
|
||||
|
||||
schema_filter: ~^(?!internal)~
|
||||
# Only enable this when needed
|
||||
@@ -19,12 +24,15 @@ doctrine:
|
||||
|
||||
orm:
|
||||
auto_generate_proxy_classes: true
|
||||
enable_lazy_ghost_objects: true
|
||||
report_fields_where_declared: true
|
||||
validate_xml_mapping: true
|
||||
naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware
|
||||
auto_mapping: true
|
||||
mappings:
|
||||
App:
|
||||
type: attribute
|
||||
is_bundle: false
|
||||
type: annotation
|
||||
dir: '%kernel.project_dir%/src/Entity'
|
||||
prefix: 'App\Entity'
|
||||
alias: App
|
||||
@@ -33,6 +41,8 @@ doctrine:
|
||||
string_functions:
|
||||
regexp: DoctrineExtensions\Query\Mysql\Regexp
|
||||
ifnull: DoctrineExtensions\Query\Mysql\IfNull
|
||||
field: DoctrineExtensions\Query\Mysql\Field
|
||||
field2: App\Doctrine\Functions\Field2
|
||||
|
||||
when@test:
|
||||
doctrine:
|
||||
|
||||
11
config/packages/dompdf_font_loader.yaml
Normal file
11
config/packages/dompdf_font_loader.yaml
Normal file
@@ -0,0 +1,11 @@
|
||||
dompdf_font_loader:
|
||||
auto_install: true
|
||||
|
||||
fonts:
|
||||
unifont:
|
||||
normal: "%kernel.project_dir%/vendor/part-db/label-fonts/fonts/unifont.ttf"
|
||||
|
||||
# Enable autodiscovery of fonts, so that font installation is much easier
|
||||
autodiscovery:
|
||||
paths:
|
||||
- "%kernel.project_dir%/assets/fonts/dompdf"
|
||||
@@ -2,8 +2,13 @@
|
||||
framework:
|
||||
secret: '%env(APP_SECRET)%'
|
||||
csrf_protection: true
|
||||
annotations: false
|
||||
handle_all_throwables: true
|
||||
|
||||
# Must be set to true, to enable the change of HTTP methhod via _method parameter, otherwise our delete routines does not work anymore
|
||||
# We set this header by ourselves, so we can disable it here
|
||||
disallow_search_engine_index: false
|
||||
|
||||
# Must be set to true, to enable the change of HTTP method via _method parameter, otherwise our delete routines does not work anymore
|
||||
# TODO: Rework delete routines to work without _method parameter as it is not recommended anymore (see https://github.com/symfony/symfony/issues/45278)
|
||||
http_method_override: true
|
||||
|
||||
@@ -22,16 +27,12 @@ framework:
|
||||
handler_id: null
|
||||
cookie_secure: auto
|
||||
cookie_samesite: lax
|
||||
storage_factory_id: session.storage.factory.native
|
||||
|
||||
#esi: true
|
||||
#fragments: true
|
||||
php_errors:
|
||||
log: true
|
||||
|
||||
form:
|
||||
legacy_error_messages: false # Enable to use the new Form component validation messages
|
||||
|
||||
when@test:
|
||||
framework:
|
||||
test: true
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
# See https://github.com/SAML-Toolkits/php-saml for more information about the SAML settings
|
||||
|
||||
hslavich_onelogin_saml:
|
||||
# Basic settings
|
||||
idp:
|
||||
entityId: '%env(string:SAML_IDP_ENTITY_ID)%'
|
||||
singleSignOnService:
|
||||
url: '%env(string:SAML_IDP_SINGLE_SIGN_ON_SERVICE)%'
|
||||
binding: 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect'
|
||||
singleLogoutService:
|
||||
url: '%env(string:SAML_IDP_SINGLE_LOGOUT_SERVICE)%'
|
||||
binding: 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect'
|
||||
x509cert: '%env(string:SAML_IDP_X509_CERT)%'
|
||||
sp:
|
||||
entityId: '%env(string:SAML_SP_ENTITY_ID)%'
|
||||
assertionConsumerService:
|
||||
url: '%partdb.default_uri%saml/acs'
|
||||
binding: 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST'
|
||||
singleLogoutService:
|
||||
url: '%partdb.default_uri%logout'
|
||||
binding: 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect'
|
||||
x509cert: '%env(string:SAML_SP_X509_CERT)%'
|
||||
privateKey: '%env(string:SAMLP_SP_PRIVATE_KEY)%'
|
||||
|
||||
# Optional settings
|
||||
#baseurl: 'http://myapp.com'
|
||||
strict: true
|
||||
debug: false
|
||||
security:
|
||||
allowRepeatAttributeName: true
|
||||
# nameIdEncrypted: false
|
||||
authnRequestsSigned: true
|
||||
logoutRequestSigned: true
|
||||
logoutResponseSigned: true
|
||||
# wantMessagesSigned: false
|
||||
# wantAssertionsSigned: true
|
||||
# wantNameIdEncrypted: false
|
||||
# requestedAuthnContext: true
|
||||
# signMetadata: false
|
||||
# wantXMLValidation: true
|
||||
# relaxDestinationValidation: false
|
||||
# destinationStrictlyMatches: true
|
||||
# rejectUnsolicitedResponsesWithInResponseTo: false
|
||||
# signatureAlgorithm: 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256'
|
||||
# digestAlgorithm: 'http://www.w3.org/2001/04/xmlenc#sha256'
|
||||
#contactPerson:
|
||||
# technical:
|
||||
# givenName: 'Tech User'
|
||||
# emailAddress: 'techuser@example.com'
|
||||
# support:
|
||||
# givenName: 'Support User'
|
||||
# emailAddress: 'supportuser@example.com'
|
||||
# administrative:
|
||||
# givenName: 'Administrative User'
|
||||
# emailAddress: 'administrativeuser@example.com'
|
||||
#organization:
|
||||
# en:
|
||||
# name: 'Part-DB-name'
|
||||
# displayname: 'Displayname'
|
||||
# url: 'http://example.com'
|
||||
5
config/packages/http_client.yaml
Normal file
5
config/packages/http_client.yaml
Normal file
@@ -0,0 +1,5 @@
|
||||
framework:
|
||||
http_client:
|
||||
default_options:
|
||||
headers:
|
||||
'User-Agent': 'Part-DB'
|
||||
10
config/packages/http_discovery.yaml
Normal file
10
config/packages/http_discovery.yaml
Normal file
@@ -0,0 +1,10 @@
|
||||
services:
|
||||
Psr\Http\Message\RequestFactoryInterface: '@http_discovery.psr17_factory'
|
||||
Psr\Http\Message\ResponseFactoryInterface: '@http_discovery.psr17_factory'
|
||||
Psr\Http\Message\ServerRequestFactoryInterface: '@http_discovery.psr17_factory'
|
||||
Psr\Http\Message\StreamFactoryInterface: '@http_discovery.psr17_factory'
|
||||
Psr\Http\Message\UploadedFileFactoryInterface: '@http_discovery.psr17_factory'
|
||||
Psr\Http\Message\UriFactoryInterface: '@http_discovery.psr17_factory'
|
||||
|
||||
http_discovery.psr17_factory:
|
||||
class: Http\Discovery\Psr17Factory
|
||||
38
config/packages/knpu_oauth2_client.yaml
Normal file
38
config/packages/knpu_oauth2_client.yaml
Normal file
@@ -0,0 +1,38 @@
|
||||
knpu_oauth2_client:
|
||||
clients:
|
||||
# configure your clients as described here: https://github.com/knpuniversity/oauth2-client-bundle#configuration
|
||||
|
||||
ip_digikey_oauth:
|
||||
type: generic
|
||||
provider_class: '\League\OAuth2\Client\Provider\GenericProvider'
|
||||
|
||||
client_id: '%env(PROVIDER_DIGIKEY_CLIENT_ID)%'
|
||||
client_secret: '%env(PROVIDER_DIGIKEY_SECRET)%'
|
||||
|
||||
redirect_route: 'oauth_client_check'
|
||||
redirect_params: {name: 'ip_digikey_oauth'}
|
||||
|
||||
provider_options:
|
||||
urlAuthorize: 'https://api.digikey.com/v1/oauth2/authorize'
|
||||
urlAccessToken: 'https://api.digikey.com/v1/oauth2/token'
|
||||
urlResourceOwnerDetails: ''
|
||||
|
||||
# Sandbox
|
||||
#urlAuthorize: 'https://sandbox-api.digikey.com/v1/oauth2/authorize'
|
||||
#urlAccessToken: 'https://sandbox-api.digikey.com/v1/oauth2/token'
|
||||
#urlResourceOwnerDetails: ''
|
||||
|
||||
ip_octopart_oauth:
|
||||
type: generic
|
||||
provider_class: '\League\OAuth2\Client\Provider\GenericProvider'
|
||||
|
||||
client_id: '%env(PROVIDER_OCTOPART_CLIENT_ID)%'
|
||||
client_secret: '%env(PROVIDER_OCTOPART_SECRET)%'
|
||||
|
||||
redirect_route: 'oauth_client_check'
|
||||
redirect_params: { name: 'ip_octopart_oauth' }
|
||||
|
||||
provider_options:
|
||||
urlAuthorize: 'https://identity.nexar.com/connect/authorize'
|
||||
urlAccessToken: 'https://identity.nexar.com/connect/token'
|
||||
urlResourceOwnerDetails: ''
|
||||
@@ -3,9 +3,15 @@ liip_imagine:
|
||||
# valid drivers options include "gd" or "gmagick" or "imagick"
|
||||
driver: "gd"
|
||||
|
||||
twig:
|
||||
mode: lazy
|
||||
|
||||
default_filter_set_settings:
|
||||
format: webp
|
||||
|
||||
filter_sets:
|
||||
thumbnail_sm:
|
||||
quality: 90
|
||||
quality: 65
|
||||
filters:
|
||||
thumbnail:
|
||||
size: [150, 150]
|
||||
@@ -20,7 +26,7 @@ liip_imagine:
|
||||
mode: inset
|
||||
|
||||
thumbnail_xs:
|
||||
quality: 90
|
||||
quality: 60
|
||||
filters:
|
||||
thumbnail:
|
||||
size: [50, 50]
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
framework:
|
||||
lock: '%env(LOCK_DSN)%'
|
||||
69
config/packages/nbgrp_onelogin_saml.yaml
Normal file
69
config/packages/nbgrp_onelogin_saml.yaml
Normal file
@@ -0,0 +1,69 @@
|
||||
# See https://github.com/SAML-Toolkits/php-saml for more information about the SAML settings
|
||||
|
||||
# Define a parameter here, so we can access it later in the default fallback
|
||||
parameters:
|
||||
saml.sp.privateKey: '%env(string:SAML_SP_PRIVATE_KEY)%'
|
||||
|
||||
nbgrp_onelogin_saml:
|
||||
use_proxy_vars: '%env(bool:SAML_BEHIND_PROXY)%'
|
||||
onelogin_settings:
|
||||
default:
|
||||
# Basic settings
|
||||
idp:
|
||||
entityId: '%env(string:SAML_IDP_ENTITY_ID)%'
|
||||
singleSignOnService:
|
||||
url: '%env(string:SAML_IDP_SINGLE_SIGN_ON_SERVICE)%'
|
||||
binding: 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect'
|
||||
singleLogoutService:
|
||||
url: '%env(string:SAML_IDP_SINGLE_LOGOUT_SERVICE)%'
|
||||
binding: 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect'
|
||||
x509cert: '%env(string:SAML_IDP_X509_CERT)%'
|
||||
sp:
|
||||
entityId: '%env(string:SAML_SP_ENTITY_ID)%'
|
||||
assertionConsumerService:
|
||||
url: '%partdb.default_uri%saml/acs'
|
||||
binding: 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST'
|
||||
singleLogoutService:
|
||||
url: '%partdb.default_uri%logout'
|
||||
binding: 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect'
|
||||
x509cert: '%env(string:SAML_SP_X509_CERT)%'
|
||||
# Before the env variable was wrongly named "SAMLP_SP_PRIVATE_KEY".
|
||||
# For compatibility reasons we keep it and only fallback to the new name if the old one is not set. This may be removed in the future.
|
||||
privateKey: '%env(string:default:saml.sp.privateKey:string:SAMLP_SP_PRIVATE_KEY)%'
|
||||
|
||||
# Optional settings
|
||||
baseurl: '%partdb.default_uri%saml/'
|
||||
strict: true
|
||||
debug: false
|
||||
security:
|
||||
allowRepeatAttributeName: true
|
||||
# nameIdEncrypted: false
|
||||
authnRequestsSigned: true
|
||||
logoutRequestSigned: true
|
||||
logoutResponseSigned: true
|
||||
# wantMessagesSigned: false
|
||||
# wantAssertionsSigned: true
|
||||
# wantNameIdEncrypted: false
|
||||
# requestedAuthnContext: true
|
||||
# signMetadata: false
|
||||
# wantXMLValidation: true
|
||||
# relaxDestinationValidation: false
|
||||
# destinationStrictlyMatches: true
|
||||
# rejectUnsolicitedResponsesWithInResponseTo: false
|
||||
# signatureAlgorithm: 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256'
|
||||
# digestAlgorithm: 'http://www.w3.org/2001/04/xmlenc#sha256'
|
||||
#contactPerson:
|
||||
# technical:
|
||||
# givenName: 'Tech User'
|
||||
# emailAddress: 'techuser@example.com'
|
||||
# support:
|
||||
# givenName: 'Support User'
|
||||
# emailAddress: 'supportuser@example.com'
|
||||
# administrative:
|
||||
# givenName: 'Administrative User'
|
||||
# emailAddress: 'administrativeuser@example.com'
|
||||
#organization:
|
||||
# en:
|
||||
# name: 'Part-DB-name'
|
||||
# displayname: 'Displayname'
|
||||
# url: 'http://example.com'
|
||||
10
config/packages/nelmio_cors.yaml
Normal file
10
config/packages/nelmio_cors.yaml
Normal file
@@ -0,0 +1,10 @@
|
||||
nelmio_cors:
|
||||
defaults:
|
||||
origin_regex: true
|
||||
allow_origin: ['%env(CORS_ALLOW_ORIGIN)%']
|
||||
allow_methods: ['GET', 'OPTIONS', 'POST', 'PUT', 'PATCH', 'DELETE']
|
||||
allow_headers: ['Content-Type', 'Authorization']
|
||||
expose_headers: ['Link']
|
||||
max_age: 3600
|
||||
paths:
|
||||
'^/': null
|
||||
@@ -12,6 +12,13 @@ nelmio_security:
|
||||
external_redirects:
|
||||
abort: true
|
||||
log: true
|
||||
allow_list:
|
||||
# Whitelist the domain of the SAML IDP, so we can redirect to it during the SAML login process
|
||||
- '%env(string:key:host:url:SAML_IDP_SINGLE_SIGN_ON_SERVICE)%'
|
||||
|
||||
# Whitelist the info provider APIs (OAuth redirects)
|
||||
- 'digikey.com'
|
||||
- 'nexar.com'
|
||||
|
||||
# forces Microsoft's XSS-Protection with
|
||||
# its block mode
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
# See the configuration reference at https://symfony.com/bundles/SchebTwoFactorBundle/5.x/configuration.html
|
||||
# See the configuration reference at https://symfony.com/bundles/SchebTwoFactorBundle/6.x/configuration.html
|
||||
scheb_two_factor:
|
||||
|
||||
google:
|
||||
enabled: true # If Google Authenticator should be enabled, default false
|
||||
server_name: '%partdb.title%' # Server name used in QR code
|
||||
issuer: 'Part-DB' # Issuer name used in QR code
|
||||
server_name: '$$DOMAIN$$' # This field is replaced by the domain name of the server in DecoratedGoogleAuthenticator
|
||||
issuer: '%partdb.title%' # Issuer name used in QR code
|
||||
digits: 6 # Number of digits in authentication code
|
||||
window: 1 # How many codes before/after the current one would be accepted as valid
|
||||
leeway: 5 # Acceptable time drift in seconds
|
||||
template: security/2fa_form.html.twig
|
||||
|
||||
backup_codes:
|
||||
@@ -23,6 +23,6 @@ scheb_two_factor:
|
||||
security_tokens:
|
||||
- Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken
|
||||
# If you're using guard-based authentication, you have to use this one:
|
||||
# - Symfony\Component\Security\Guard\Token\PostAuthenticationGuardToken
|
||||
# - Symfony\Component\Security\Http\Authenticator\Token\PostAuthenticationToken
|
||||
# If you're using authenticator-based security (introduced in Symfony 5.1), you have to use this one:
|
||||
# - Symfony\Component\Security\Http\Authenticator\Token\PostAuthenticationToken
|
||||
- Symfony\Component\Security\Http\Authenticator\Token\PostAuthenticationToken
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
security:
|
||||
enable_authenticator_manager: true
|
||||
|
||||
# https://symfony.com/doc/current/security.html#registering-the-user-hashing-passwords
|
||||
password_hashers:
|
||||
Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: 'auto'
|
||||
|
||||
@@ -22,6 +21,12 @@ security:
|
||||
user_checker: App\Security\UserChecker
|
||||
entry_point: form_login
|
||||
|
||||
# Enable user impersonation
|
||||
switch_user: { role: CAN_SWITCH_USER }
|
||||
|
||||
custom_authenticators:
|
||||
- App\Security\ApiTokenAuthenticator
|
||||
|
||||
two_factor:
|
||||
auth_form_path: 2fa_login
|
||||
check_path: 2fa_login_check
|
||||
@@ -64,3 +69,7 @@ security:
|
||||
# We get into trouble with the U2F authentication, if the calls to the trees trigger an 2FA login
|
||||
# This settings should not do much harm, because a read only access to show available data structures is not really critical
|
||||
- { path: "^/\\w{2}/tree", role: PUBLIC_ACCESS }
|
||||
# Restrict access to API to users, which has the API access permission
|
||||
- { path: "^/api", allow_if: 'is_granted("@api.access_api") and is_authenticated()' }
|
||||
# Restrict access to KICAD to users, which has API access permission
|
||||
- { path: "^/kicad-api", allow_if: 'is_granted("@api.access_api") and is_authenticated()' }
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
sensio_framework_extra:
|
||||
router:
|
||||
annotations: false
|
||||
@@ -1,4 +1,2 @@
|
||||
framework:
|
||||
test: true
|
||||
session:
|
||||
storage_id: session.storage.mock_file
|
||||
|
||||
@@ -20,6 +20,7 @@ twig:
|
||||
avatar_helper: '@App\Services\UserSystem\UserAvatarHelper'
|
||||
available_themes: '%partdb.available_themes%'
|
||||
saml_enabled: '%partdb.saml.enabled%'
|
||||
part_preview_generator: '@App\Services\Attachments\PartPreviewGenerator'
|
||||
|
||||
when@test:
|
||||
twig:
|
||||
|
||||
4
config/packages/uid.yaml
Normal file
4
config/packages/uid.yaml
Normal file
@@ -0,0 +1,4 @@
|
||||
framework:
|
||||
uid:
|
||||
default_uuid_version: 7
|
||||
time_based_uuid_version: 7
|
||||
3
config/packages/ux_translator.yaml
Normal file
3
config/packages/ux_translator.yaml
Normal file
@@ -0,0 +1,3 @@
|
||||
ux_translator:
|
||||
# The directory where the JavaScript translations are dumped
|
||||
dump_directory: '%kernel.project_dir%/var/translations'
|
||||
@@ -4,7 +4,9 @@ when@dev:
|
||||
intercept_redirects: false
|
||||
|
||||
framework:
|
||||
profiler: { only_exceptions: false }
|
||||
profiler:
|
||||
only_exceptions: false
|
||||
collect_serializer_data: true
|
||||
|
||||
when@test:
|
||||
web_profiler:
|
||||
|
||||
@@ -11,17 +11,20 @@ parameters:
|
||||
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.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', 'fr', 'ru', 'ja'] # The languages that are shown in user drop down menu
|
||||
partdb.locale_menu: ['en', 'de', 'it', 'fr', 'ru', 'ja'] # 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.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
|
||||
|
||||
######################################################################################################################
|
||||
# Users and Privacy
|
||||
######################################################################################################################
|
||||
partdb.gpdr_compliance: true # If this option is activated, IP addresses are anonymized to be GPDR compliant
|
||||
partdb.gdpr_compliance: true # If this option is activated, IP addresses are anonymized to be GDPR compliant
|
||||
partdb.users.use_gravatar: '%env(bool:USE_GRAVATAR)%' # Set to false, if no Gravatar images should be used for user profiles.
|
||||
partdb.users.email_pw_reset: '%env(bool:ALLOW_EMAIL_PW_RESET)%' # Config if users are able, to reset their password by email. By default this enabled, when a mail server is configured.
|
||||
|
||||
partdb.check_for_updates: '%env(bool:CHECK_FOR_UPDATES)' # Set to false, if Part-DB should not contact the GitHub API to check for updates
|
||||
|
||||
######################################################################################################################
|
||||
# Mail settings
|
||||
######################################################################################################################
|
||||
@@ -32,6 +35,7 @@ parameters:
|
||||
# Attachments and files
|
||||
######################################################################################################################
|
||||
partdb.attachments.allow_downloads: '%env(bool:ALLOW_ATTACHMENT_DOWNLOADS)%' # Allow users to download attachments to server. Warning: This can be dangerous, because via that feature attackers maybe can access ressources on your intranet!
|
||||
partdb.attachments.download_by_default: '%env(bool:ATTACHMENT_DOWNLOAD_BY_DEFAULT)%' # If this is set the 'download external files' checkbox is set by default for new attachments (only if allow_downloads is set to true)
|
||||
partdb.attachments.dir.media: 'public/media/' # The folder where uploaded attachment files are saved (must be in public folder)
|
||||
partdb.attachments.dir.secure: 'uploads/' # The folder where secured attachment files are saved (must not be in public/)
|
||||
partdb.attachments.max_file_size: '%env(string:MAX_ATTACHMENT_FILE_SIZE)%' # The maximum size of an attachment file (in bytes, you can use M for megabytes and G for gigabytes)
|
||||
@@ -47,6 +51,12 @@ parameters:
|
||||
######################################################################################################################
|
||||
partdb.saml.enabled: '%env(bool:SAML_ENABLED)%' # If this is set to true, SAML authentication is enabled
|
||||
|
||||
######################################################################################################################
|
||||
# Table settings
|
||||
######################################################################################################################
|
||||
partdb.table.default_page_size: '%env(int:TABLE_DEFAULT_PAGE_SIZE)%' # The default number of entries shown per page in tables
|
||||
partdb.table.parts.default_columns: '%env(trim:string:TABLE_PARTS_DEFAULT_COLUMNS)%' # The default columns in part tables and their order
|
||||
|
||||
######################################################################################################################
|
||||
# Sidebar
|
||||
######################################################################################################################
|
||||
@@ -105,6 +115,8 @@ parameters:
|
||||
env(USE_GRAVATAR): '0'
|
||||
env(MAX_ATTACHMENT_FILE_SIZE): '100M'
|
||||
|
||||
env(ENFORCE_CHANGE_COMMENTS_FOR): ''
|
||||
|
||||
env(ERROR_PAGE_ADMIN_EMAIL): ''
|
||||
env(ERROR_PAGE_SHOW_HELP): 1
|
||||
|
||||
@@ -116,9 +128,18 @@ parameters:
|
||||
env(EMAIL_SENDER_NAME): 'Part-DB Mailer'
|
||||
env(ALLOW_EMAIL_PW_RESET): 0
|
||||
|
||||
env(TABLE_DEFAULT_PAGE_SIZE): 50
|
||||
|
||||
env(TRUSTED_PROXIES): '127.0.0.1' #By default trust only our own server
|
||||
env(TRUSTED_HOSTS): '' # Trust all host names by default
|
||||
|
||||
env(DEFAULT_URI): 'https://partdb.changeme.invalid/'
|
||||
|
||||
env(SAML_ROLE_MAPPING): '{}'
|
||||
|
||||
env(HISTORY_SAVE_CHANGED_DATA): 1
|
||||
env(HISTORY_SAVE_CHANGED_FIELDS): 1
|
||||
env(HISTORY_SAVE_REMOVED_DATA): 1
|
||||
env(HISTORY_SAVE_NEW_DATA): 1
|
||||
|
||||
env(EDA_KICAD_CATEGORY_DEPTH): 0
|
||||
|
||||
@@ -25,27 +25,35 @@ perms: # Here comes a list with all Permission names (they have a perm_[name] co
|
||||
# If a part can be read by a user, he can also see all the datastructures (except devices)
|
||||
alsoSet: ['storelocations.read', 'footprints.read', 'categories.read', 'suppliers.read', 'manufacturers.read',
|
||||
'currencies.read', 'attachment_types.read', 'measurement_units.read']
|
||||
apiTokenRole: ROLE_API_READ_ONLY
|
||||
edit:
|
||||
label: "perm.edit"
|
||||
alsoSet: ['read', 'parts_stock.withdraw', 'parts_stock.add', 'parts_stock.move']
|
||||
apiTokenRole: ROLE_API_EDIT
|
||||
create:
|
||||
label: "perm.create"
|
||||
alsoSet: ['read', 'edit']
|
||||
apiTokenRole: ROLE_API_EDIT
|
||||
delete:
|
||||
label: "perm.delete"
|
||||
alsoSet: ['read', 'edit']
|
||||
apiTokenRole: ROLE_API_EDIT
|
||||
change_favorite:
|
||||
label: "perm.part.change_favorite"
|
||||
alsoSet: ['edit']
|
||||
apiTokenRole: ROLE_API_EDIT
|
||||
show_history:
|
||||
label: "perm.part.show_history"
|
||||
alsoSet: ['read']
|
||||
apiTokenRole: ROLE_API_READ_ONLY
|
||||
revert_element:
|
||||
label: "perm.revert_elements"
|
||||
alsoSet: ["read", "edit", "create", "delete", "show_history"]
|
||||
apiTokenRole: ROLE_API_EDIT
|
||||
import:
|
||||
label: "perm.import"
|
||||
alsoSet: ["read", "edit", "create"]
|
||||
apiTokenRole: ROLE_API_EDIT
|
||||
|
||||
parts_stock:
|
||||
group: "data"
|
||||
@@ -53,10 +61,13 @@ perms: # Here comes a list with all Permission names (they have a perm_[name] co
|
||||
operations:
|
||||
withdraw:
|
||||
label: "perm.parts_stock.withdraw"
|
||||
apiTokenRole: ROLE_API_EDIT
|
||||
add:
|
||||
label: "perm.parts_stock.add"
|
||||
apiTokenRole: ROLE_API_EDIT
|
||||
move:
|
||||
label: "perm.parts_stock.move"
|
||||
apiTokenRole: ROLE_API_EDIT
|
||||
|
||||
|
||||
storelocations: &PART_CONTAINING
|
||||
@@ -65,23 +76,30 @@ perms: # Here comes a list with all Permission names (they have a perm_[name] co
|
||||
operations:
|
||||
read:
|
||||
label: "perm.read"
|
||||
apiTokenRole: ROLE_API_READ_ONLY
|
||||
edit:
|
||||
label: "perm.edit"
|
||||
alsoSet: 'read'
|
||||
apiTokenRole: ROLE_API_EDIT
|
||||
create:
|
||||
label: "perm.create"
|
||||
alsoSet: ['read', 'edit']
|
||||
apiTokenRole: ROLE_API_EDIT
|
||||
delete:
|
||||
label: "perm.delete"
|
||||
alsoSet: ['read', 'edit']
|
||||
apiTokenRole: ROLE_API_EDIT
|
||||
show_history:
|
||||
label: "perm.show_history"
|
||||
apiTokenRole: ROLE_API_READ_ONLY
|
||||
revert_element:
|
||||
label: "perm.revert_elements"
|
||||
alsoSet: ["read", "edit", "create", "delete", "show_history"]
|
||||
apiTokenRole: ROLE_API_EDIT
|
||||
import:
|
||||
label: "perm.import"
|
||||
alsoSet: [ "read", "edit", "create" ]
|
||||
apiTokenRole: ROLE_API_EDIT
|
||||
|
||||
footprints:
|
||||
<<: *PART_CONTAINING
|
||||
@@ -139,32 +157,48 @@ perms: # Here comes a list with all Permission names (they have a perm_[name] co
|
||||
ic_logos:
|
||||
label: "perm.tools.ic_logos"
|
||||
|
||||
info_providers:
|
||||
label: "perm.part.info_providers"
|
||||
operations:
|
||||
create_parts:
|
||||
label: "perm.part.info_providers.create_parts"
|
||||
alsoSet: ['parts.create']
|
||||
apiTokenRole: ROLE_API_EDIT
|
||||
|
||||
groups:
|
||||
label: "perm.groups"
|
||||
group: "system"
|
||||
operations:
|
||||
read:
|
||||
label: "perm.read"
|
||||
apiTokenRole: ROLE_API_ADMIN
|
||||
edit:
|
||||
label: "perm.edit"
|
||||
alsoSet: 'read'
|
||||
apiTokenRole: ROLE_API_ADMIN
|
||||
create:
|
||||
label: "perm.create"
|
||||
alsoSet: ['read', 'edit']
|
||||
apiTokenRole: ROLE_API_ADMIN
|
||||
delete:
|
||||
label: "perm.delete"
|
||||
alsoSet: ['read', 'delete']
|
||||
apiTokenRole: ROLE_API_ADMIN
|
||||
edit_permissions:
|
||||
label: "perm.edit_permissions"
|
||||
alsoSet: ['read', 'edit']
|
||||
apiTokenRole: ROLE_API_ADMIN
|
||||
show_history:
|
||||
label: "perm.show_history"
|
||||
apiTokenRole: ROLE_API_ADMIN
|
||||
revert_element:
|
||||
label: "perm.revert_elements"
|
||||
alsoSet: ["read", "edit", "create", "delete", "edit_permissions", "show_history"]
|
||||
apiTokenRole: ROLE_API_ADMIN
|
||||
import:
|
||||
label: "perm.import"
|
||||
alsoSet: [ "read", "edit", "create" ]
|
||||
apiTokenRole: ROLE_API_ADMIN
|
||||
|
||||
users:
|
||||
label: "perm.users"
|
||||
@@ -172,34 +206,49 @@ perms: # Here comes a list with all Permission names (they have a perm_[name] co
|
||||
operations:
|
||||
read:
|
||||
label: "perm.read"
|
||||
apiTokenRole: ROLE_API_ADMIN
|
||||
create:
|
||||
label: "perm.create"
|
||||
alsoSet: ['read', 'edit_username', 'edit_infos']
|
||||
apiTokenRole: ROLE_API_ADMIN
|
||||
delete:
|
||||
label: "perm.delete"
|
||||
alsoSet: ['read', 'edit_username', 'edit_infos']
|
||||
apiTokenRole: ROLE_API_ADMIN
|
||||
edit_username:
|
||||
label: "perm.users.edit_user_name"
|
||||
alsoSet: ['read']
|
||||
apiTokenRole: ROLE_API_ADMIN
|
||||
edit_infos:
|
||||
label: "perm.users.edit_infos"
|
||||
alsoSet: 'read'
|
||||
apiTokenRole: ROLE_API_ADMIN
|
||||
edit_permissions:
|
||||
label: "perm.users.edit_permissions"
|
||||
alsoSet: 'read'
|
||||
apiTokenRole: ROLE_API_ADMIN
|
||||
set_password:
|
||||
label: "perm.users.set_password"
|
||||
alsoSet: 'read'
|
||||
apiTokenRole: ROLE_API_FULL
|
||||
impersonate:
|
||||
label: "perm.users.impersonate"
|
||||
alsoSet: ['set_password']
|
||||
apiTokenRole: ROLE_API_FULL
|
||||
change_user_settings:
|
||||
label: "perm.users.change_user_settings"
|
||||
apiTokenRole: ROLE_API_ADMIN
|
||||
show_history:
|
||||
label: "perm.show_history"
|
||||
apiTokenRole: ROLE_API_ADMIN
|
||||
revert_element:
|
||||
label: "perm.revert_elements"
|
||||
alsoSet: ["read", "create", "delete", "edit_permissions", "show_history", "edit_infos", "edit_username"]
|
||||
apiTokenRole: ROLE_API_ADMIN
|
||||
import:
|
||||
label: "perm.import"
|
||||
alsoSet: [ "read", "create" ]
|
||||
apiTokenRole: ROLE_API_ADMIN
|
||||
|
||||
#database:
|
||||
# label: "perm.database"
|
||||
@@ -234,60 +283,94 @@ perms: # Here comes a list with all Permission names (they have a perm_[name] co
|
||||
operations:
|
||||
show_logs:
|
||||
label: "perm.show_logs"
|
||||
apiTokenRole: ROLE_API_ADMIN
|
||||
delete_logs:
|
||||
label: "perm.delete_logs"
|
||||
alsoSet: 'show_logs'
|
||||
apiTokenRole: ROLE_API_ADMIN
|
||||
server_infos:
|
||||
label: "perm.server_infos"
|
||||
apiTokenRole: ROLE_API_ADMIN
|
||||
manage_oauth_tokens:
|
||||
label: "Manage OAuth tokens"
|
||||
apiTokenRole: ROLE_API_ADMIN
|
||||
show_updates:
|
||||
label: "perm.system.show_available_updates"
|
||||
apiTokenRole: ROLE_API_ADMIN
|
||||
|
||||
|
||||
attachments:
|
||||
label: "perm.part.attachments"
|
||||
operations:
|
||||
show_private:
|
||||
label: "perm.attachments.show_private"
|
||||
apiTokenRole: ROLE_API_READ_ONLY
|
||||
list_attachments:
|
||||
label: "perm.attachments.list_attachments"
|
||||
alsoSet: ['attachment_types.read']
|
||||
apiTokenRole: ROLE_API_READ_ONLY
|
||||
|
||||
self:
|
||||
label: "perm.self"
|
||||
operations:
|
||||
edit_infos:
|
||||
label: "perm.self.edit_infos"
|
||||
apiTokenRole: ROLE_API_FULL
|
||||
edit_username:
|
||||
label: "perm.self.edit_username"
|
||||
apiTokenRole: ROLE_API_FULL
|
||||
show_permissions:
|
||||
label: "perm.self.show_permissions"
|
||||
apiTokenRole: ROLE_API_READ_ONLY
|
||||
show_logs:
|
||||
label: "perm.self.show_logs"
|
||||
apiTokenRole: ROLE_API_FULL
|
||||
|
||||
labels:
|
||||
label: "perm.labels"
|
||||
operations:
|
||||
create_labels:
|
||||
label: "perm.self.create_labels"
|
||||
apiTokenRole: ROLE_API_READ_ONLY
|
||||
edit_options:
|
||||
label: "perm.self.edit_options"
|
||||
alsoSet: ['create_labels']
|
||||
apiTokenRole: ROLE_API_READ_ONLY
|
||||
read_profiles:
|
||||
label: "perm.self.read_profiles"
|
||||
apiTokenRole: ROLE_API_READ_ONLY
|
||||
edit_profiles:
|
||||
label: "perm.self.edit_profiles"
|
||||
alsoSet: ['read_profiles']
|
||||
apiTokenRole: ROLE_API_EDIT
|
||||
create_profiles:
|
||||
label: "perm.self.create_profiles"
|
||||
alsoSet: ['read_profiles', 'edit_profiles']
|
||||
apiTokenRole: ROLE_API_EDIT
|
||||
delete_profiles:
|
||||
label: "perm.self.delete_profiles"
|
||||
alsoSet: ['read_profiles', 'edit_profiles', 'create_profiles']
|
||||
apiTokenRole: ROLE_API_EDIT
|
||||
use_twig:
|
||||
label: "perm.labels.use_twig"
|
||||
alsoSet: ['create_labels', 'edit_options']
|
||||
apiTokenRole: ROLE_API_ADMIN
|
||||
show_history:
|
||||
label: "perm.show_history"
|
||||
alsoSet: ['read_profiles']
|
||||
apiTokenRole: ROLE_API_READ_ONLY
|
||||
revert_element:
|
||||
label: "perm.revert_elements"
|
||||
alsoSet: ['read_profiles', 'edit_profiles', 'create_profiles', 'delete_profiles']
|
||||
apiTokenRole: ROLE_API_EDIT
|
||||
|
||||
|
||||
api:
|
||||
label: "perm.api"
|
||||
operations:
|
||||
access_api:
|
||||
label: "perm.api.access_api"
|
||||
apiTokenRole: ROLE_API_READ_ONLY
|
||||
manage_tokens:
|
||||
label: "perm.api.manage_tokens"
|
||||
alsoSet: ['access_api']
|
||||
apiTokenRole: ROLE_API_FULL
|
||||
@@ -1,12 +1,8 @@
|
||||
#index:
|
||||
# path: /
|
||||
# controller: App\Controller\DefaultController::index
|
||||
|
||||
# Redirect every url without an locale to the locale of the user/the global base locale
|
||||
|
||||
scan_qr:
|
||||
path: /scan/{type}/{id}
|
||||
controller: App\Controller\ScanController:scanQRCode
|
||||
controller: App\Controller\ScanController::scanQRCode
|
||||
|
||||
csp_report:
|
||||
path: /csp/report
|
||||
@@ -19,5 +15,5 @@ redirector:
|
||||
requirements:
|
||||
url: ".*"
|
||||
controller: App\Controller\RedirectController::addLocalePart
|
||||
# Dont match localized routes (no redirection loop, if no root with that name exists)
|
||||
condition: "not (request.getPathInfo() matches '/^\\\\/[a-z]{2}(_[A-Z]{2})?\\\\//')"
|
||||
# Dont match localized routes (no redirection loop, if no root with that name exists) or API prefixed routes
|
||||
condition: "not (request.getPathInfo() matches '/^\\\\/([a-z]{2}(_[A-Z]{2})?|api)\\\\//')"
|
||||
4
config/routes/api_platform.yaml
Normal file
4
config/routes/api_platform.yaml
Normal file
@@ -0,0 +1,4 @@
|
||||
api_platform:
|
||||
resource: .
|
||||
type: api_platform
|
||||
prefix: /api
|
||||
@@ -1,6 +1,8 @@
|
||||
controllers:
|
||||
resource: ../../src/Controller/
|
||||
type: annotation
|
||||
resource:
|
||||
path: ../../src/Controller/
|
||||
namespace: App\Controller
|
||||
type: attribute
|
||||
prefix: '{_locale}'
|
||||
|
||||
defaults:
|
||||
@@ -11,4 +13,4 @@ controllers:
|
||||
|
||||
kernel:
|
||||
resource: ../../src/Kernel.php
|
||||
type: annotation
|
||||
type: attribute
|
||||
@@ -1,4 +1,4 @@
|
||||
hslavich_saml_sp:
|
||||
resource: "@HslavichOneloginSamlBundle/Resources/config/routing.yml"
|
||||
nbgrp_saml:
|
||||
resource: "@NbgrpOneloginSamlBundle/Resources/config/routes.php"
|
||||
# Only load the SAML routes if SAML is enabled
|
||||
condition: "env('SAML_ENABLED') == '1' or env('SAML_ENABLED') == 'true'"
|
||||
3
config/routes/security.yaml
Normal file
3
config/routes/security.yaml
Normal file
@@ -0,0 +1,3 @@
|
||||
_security_logout:
|
||||
resource: security.route_loader.logout
|
||||
type: service
|
||||
@@ -14,16 +14,19 @@ services:
|
||||
autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
|
||||
bind:
|
||||
bool $demo_mode: '%partdb.demo_mode%'
|
||||
bool $gpdr_compliance : '%partdb.gpdr_compliance%'
|
||||
bool $kernel_debug: '%kernel.debug%'
|
||||
bool $gdpr_compliance: '%partdb.gdpr_compliance%'
|
||||
bool $kernel_debug_enabled: '%kernel.debug%'
|
||||
string $kernel_cache_dir: '%kernel.cache_dir%'
|
||||
string $partdb_title: '%partdb.title%'
|
||||
string $default_currency: '%partdb.default_currency%'
|
||||
string $base_currency: '%partdb.default_currency%'
|
||||
|
||||
_instanceof:
|
||||
App\Services\LabelSystem\PlaceholderProviders\PlaceholderProviderInterface:
|
||||
tags: ['app.label_placeholder_provider']
|
||||
|
||||
App\Services\InfoProviderSystem\Providers\InfoProviderInterface:
|
||||
tags: ['app.info_provider']
|
||||
|
||||
# makes classes in src/ available to be used as services
|
||||
# this creates a service per class whose id is the fully-qualified class name
|
||||
App\:
|
||||
@@ -78,6 +81,7 @@ services:
|
||||
$save_changed_fields: '%env(bool:HISTORY_SAVE_CHANGED_FIELDS)%'
|
||||
$save_changed_data: '%env(bool:HISTORY_SAVE_CHANGED_DATA)%'
|
||||
$save_removed_data: '%env(bool:HISTORY_SAVE_REMOVED_DATA)%'
|
||||
$save_new_data: '%env(bool:HISTORY_SAVE_NEW_DATA)%'
|
||||
tags:
|
||||
- { name: 'doctrine.event_subscriber' }
|
||||
|
||||
@@ -87,8 +91,9 @@ services:
|
||||
|
||||
App\Form\AttachmentFormType:
|
||||
arguments:
|
||||
$allow_attachments_downloads: '%partdb.attachments.allow_downloads%'
|
||||
$allow_attachments_download: '%partdb.attachments.allow_downloads%'
|
||||
$max_file_size: '%partdb.attachments.max_file_size%'
|
||||
$download_by_default: '%partdb.attachments.download_by_default%'
|
||||
|
||||
App\Services\Attachments\AttachmentSubmitHandler:
|
||||
arguments:
|
||||
@@ -96,11 +101,9 @@ services:
|
||||
$mimeTypes: '@mime_types'
|
||||
$max_upload_size: '%partdb.attachments.max_file_size%'
|
||||
|
||||
App\EventSubscriber\LogSystem\LogoutLoggerListener:
|
||||
tags:
|
||||
- name: 'kernel.event_listener'
|
||||
event: 'Symfony\Component\Security\Http\Event\LogoutEvent'
|
||||
dispatcher: security.event_dispatcher.main
|
||||
App\Services\LogSystem\EventCommentNeededHelper:
|
||||
arguments:
|
||||
$enforce_change_comments_for: '%partdb.enforce_change_comments_for%'
|
||||
|
||||
####################################################################################################################
|
||||
# Attachment system
|
||||
@@ -138,6 +141,19 @@ services:
|
||||
$saml_role_mapping: '%env(json:SAML_ROLE_MAPPING)%'
|
||||
$update_group_on_login: '%env(bool:SAML_UPDATE_GROUP_ON_LOGIN)%'
|
||||
|
||||
|
||||
security.access_token_extractor.header.token:
|
||||
class: Symfony\Component\Security\Http\AccessToken\HeaderAccessTokenExtractor
|
||||
arguments:
|
||||
$tokenType: 'Token'
|
||||
|
||||
security.access_token_extractor.main:
|
||||
class: Symfony\Component\Security\Http\AccessToken\ChainAccessTokenExtractor
|
||||
arguments:
|
||||
$accessTokenExtractors:
|
||||
- '@security.access_token_extractor.header'
|
||||
- '@security.access_token_extractor.header.token'
|
||||
|
||||
####################################################################################################################
|
||||
# Cache
|
||||
####################################################################################################################
|
||||
@@ -178,7 +194,7 @@ services:
|
||||
|
||||
App\EventSubscriber\UserSystem\SetUserTimezoneSubscriber:
|
||||
arguments:
|
||||
$timezone: '%partdb.timezone%'
|
||||
$default_timezone: '%partdb.timezone%'
|
||||
|
||||
App\Controller\SecurityController:
|
||||
arguments:
|
||||
@@ -209,6 +225,15 @@ services:
|
||||
arguments:
|
||||
$saml_enabled: '%partdb.saml.enabled%'
|
||||
|
||||
####################################################################################################################
|
||||
# Table settings
|
||||
####################################################################################################################
|
||||
App\DataTables\PartsDataTable:
|
||||
arguments:
|
||||
$visible_columns: '%partdb.table.parts.default_columns%'
|
||||
|
||||
App\DataTables\Helpers\ColumnSortHelper:
|
||||
shared: false # Service has a state so not share it between different tables
|
||||
|
||||
####################################################################################################################
|
||||
# Label system
|
||||
@@ -222,6 +247,11 @@ services:
|
||||
tags:
|
||||
- { name: 'app.label_placeholder_provider', priority: 10}
|
||||
|
||||
App\Services\LabelSystem\DompdfFactory:
|
||||
arguments:
|
||||
$fontDirectory: '%kernel.project_dir%/var/dompdf/fonts/'
|
||||
$tmpDirectory: '%kernel.project_dir%/var/dompdf/tmp/'
|
||||
|
||||
####################################################################################################################
|
||||
# Trees
|
||||
####################################################################################################################
|
||||
@@ -230,6 +260,69 @@ services:
|
||||
$rootNodeExpandedByDefault: '%partdb.sidebar.root_expanded%'
|
||||
$rootNodeEnabled: '%partdb.sidebar.root_node_enable%'
|
||||
|
||||
####################################################################################################################
|
||||
# Part info provider system
|
||||
####################################################################################################################
|
||||
App\Services\InfoProviderSystem\ProviderRegistry:
|
||||
arguments:
|
||||
$providers: !tagged_iterator 'app.info_provider'
|
||||
|
||||
App\Services\InfoProviderSystem\Providers\Element14Provider:
|
||||
arguments:
|
||||
$api_key: '%env(string:PROVIDER_ELEMENT14_KEY)%'
|
||||
$store_id: '%env(string:PROVIDER_ELEMENT14_STORE_ID)%'
|
||||
|
||||
App\Services\InfoProviderSystem\Providers\DigikeyProvider:
|
||||
arguments:
|
||||
$clientId: '%env(string:PROVIDER_DIGIKEY_CLIENT_ID)%'
|
||||
$currency: '%env(string:PROVIDER_DIGIKEY_CURRENCY)%'
|
||||
$language: '%env(string:PROVIDER_DIGIKEY_LANGUAGE)%'
|
||||
$country: '%env(string:PROVIDER_DIGIKEY_COUNTRY)%'
|
||||
|
||||
App\Services\InfoProviderSystem\Providers\TMEClient:
|
||||
arguments:
|
||||
$secret: '%env(string:PROVIDER_TME_SECRET)%'
|
||||
$token: '%env(string:PROVIDER_TME_KEY)%'
|
||||
|
||||
App\Services\InfoProviderSystem\Providers\TMEProvider:
|
||||
arguments:
|
||||
$currency: '%env(string:PROVIDER_TME_CURRENCY)%'
|
||||
$country: '%env(string:PROVIDER_TME_COUNTRY)%'
|
||||
$language: '%env(string:PROVIDER_TME_LANGUAGE)%'
|
||||
$get_gross_prices: '%env(bool:PROVIDER_TME_GET_GROSS_PRICES)%'
|
||||
|
||||
App\Services\InfoProviderSystem\Providers\OctopartProvider:
|
||||
arguments:
|
||||
$clientId: '&env(string:PROVIDER_OCTOPART_CLIENT_ID)%'
|
||||
$secret: '%env(string:PROVIDER_OCTOPART_SECRET)%'
|
||||
$country: '%env(string:PROVIDER_OCTOPART_COUNTRY)%'
|
||||
$currency: '%env(string:PROVIDER_OCTOPART_CURRENCY)%'
|
||||
$search_limit: '%env(int:PROVIDER_OCTOPART_SEARCH_LIMIT)%'
|
||||
$onlyAuthorizedSellers: '%env(bool:PROVIDER_OCTOPART_ONLY_AUTHORIZED_SELLERS)%'
|
||||
|
||||
App\Services\InfoProviderSystem\Providers\MouserProvider:
|
||||
arguments:
|
||||
$api_key: '%env(string:PROVIDER_MOUSER_KEY)%'
|
||||
$language: '%env(string:PROVIDER_MOUSER_SEARCH_WITH_SIGNUP_LANGUAGE)%'
|
||||
$options: '%env(string:PROVIDER_MOUSER_SEARCH_OPTION)%'
|
||||
$search_limit: '%env(int:PROVIDER_MOUSER_SEARCH_LIMIT)%'
|
||||
|
||||
####################################################################################################################
|
||||
# API system
|
||||
####################################################################################################################
|
||||
App\State\PartDBInfoProvider:
|
||||
arguments:
|
||||
$default_uri: '%partdb.default_uri%'
|
||||
$global_locale: '%partdb.locale%'
|
||||
$global_timezone: '%partdb.timezone%'
|
||||
|
||||
####################################################################################################################
|
||||
# EDA system
|
||||
####################################################################################################################
|
||||
App\Services\EDA\KiCadHelper:
|
||||
arguments:
|
||||
$category_depth: '%env(int:EDA_KICAD_CATEGORY_DEPTH)%'
|
||||
|
||||
####################################################################################################################
|
||||
# Symfony overrides
|
||||
####################################################################################################################
|
||||
@@ -240,6 +333,13 @@ services:
|
||||
tags:
|
||||
- {name: serializer.normalizer, priority: -9000}
|
||||
|
||||
# Disable igbinary serialization for cache even when igbinary is available, as it causes issues with the doctrine
|
||||
# proxy objects (see https://github.com/igbinary/igbinary/issues/377 and https://github.com/igbinary/igbinary/issues/273)
|
||||
cache.default_marshaller:
|
||||
class: Symfony\Component\Cache\Marshaller\DefaultMarshaller
|
||||
arguments:
|
||||
$useIgbinarySerialize: false
|
||||
|
||||
|
||||
####################################################################################################################
|
||||
# Miscellaneous
|
||||
@@ -253,7 +353,7 @@ services:
|
||||
tags:
|
||||
- { name: 'doctrine.fixtures.purger_factory', alias: 'reset_autoincrement_purger' }
|
||||
|
||||
# We are needing this service inside of a migration, where only the container is injected. So we need to define it as public, to access it from the container.
|
||||
# We are needing this service inside a migration, where only the container is injected. So we need to define it as public, to access it from the container.
|
||||
App\Services\UserSystem\PermissionPresetsHelper:
|
||||
public: true
|
||||
|
||||
@@ -261,6 +361,20 @@ services:
|
||||
arguments:
|
||||
$project_dir: '%kernel.project_dir%'
|
||||
|
||||
App\Services\System\UpdateAvailableManager:
|
||||
arguments:
|
||||
$check_for_updates: '%partdb.check_for_updates%'
|
||||
|
||||
App\Services\System\BannerHelper:
|
||||
arguments:
|
||||
$partdb_banner: '%partdb.banner%'
|
||||
$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
|
||||
####################################################################################################################
|
||||
@@ -277,3 +391,14 @@ services:
|
||||
autowire: true
|
||||
tags:
|
||||
- { name: monolog.processor }
|
||||
|
||||
when@test:
|
||||
services:
|
||||
# Decorate the doctrine fixtures load command to use our custom purger by default
|
||||
doctrine.fixtures_load_command.custom:
|
||||
decorates: doctrine.fixtures_load_command
|
||||
class: Doctrine\Bundle\FixturesBundle\Command\LoadDataFixturesDoctrineCommand
|
||||
arguments:
|
||||
- '@doctrine.fixtures.loader'
|
||||
- '@doctrine'
|
||||
- { default: '@App\Doctrine\Purger\DoNotUsePurgerFactory' }
|
||||
78
docs/api/authentication.md
Normal file
78
docs/api/authentication.md
Normal file
@@ -0,0 +1,78 @@
|
||||
---
|
||||
title: Authentication
|
||||
layout: default
|
||||
parent: API
|
||||
nav_order: 2
|
||||
---
|
||||
|
||||
# Authentication
|
||||
|
||||
To use API endpoints, the external application has to authenticate itself, so that Part-DB knows which user is accessing
|
||||
the data and which permissions
|
||||
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
|
||||
specific user. This user limits the permissions of the application, so that it can only access data, which the user is
|
||||
allowed to access.
|
||||
|
||||
The only method currently available for authentication is to use 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
|
||||
user, when accessing the API.
|
||||
The API token is passed via the `Authentication` HTTP header during the API request, like the
|
||||
following: `Authentication: Bearer tcp_sdjfks....`.
|
||||
|
||||
{: .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
|
||||
> API token like a password
|
||||
> and keep it secret. Only share it with trusted applications.
|
||||
|
||||
API tokens can be created and managed on the user settings page in the API token section. You can create as many API
|
||||
tokens as you want and also delete them again.
|
||||
When deleting a token, it is immediately invalidated and can not be used anymore, which means that the application can
|
||||
not access the API anymore with this token.
|
||||
|
||||
### 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
|
||||
can only access data, which 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
|
||||
subset of permissions the token has, which can be less than the permissions of the user. For example, you can have a
|
||||
user
|
||||
with full read and write permissions, but create a token with only read permissions, which can only read data, but not
|
||||
change anything in the database.
|
||||
|
||||
{: .warning }
|
||||
> In general, you should always use the least possible permissions for a token, to limit the possible damage, which can
|
||||
> be done with a stolen token or a bug in the application.
|
||||
> 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.
|
||||
|
||||
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
|
||||
not change anything.
|
||||
* **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.
|
||||
* **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.
|
||||
* **Full**: The token can do anything the user can do, including changing the users password and create new tokens. This
|
||||
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
|
||||
would be allowed by the token scope.
|
||||
|
||||
### Expiration date
|
||||
|
||||
API tokens can have an expiration date, which means that the token is only valid until the expiration date. After that
|
||||
the token is automatically invalidated and can not be used anymore. The token is still listed on the user settings page,
|
||||
and can be deleted there, but the code can not be used to access Part-DB anymore after the expiration date.
|
||||
|
||||
### Get token information
|
||||
|
||||
When authenticating with an API token, you can get information about the currently used token by accessing
|
||||
the `/api/tokens/current` endpoint.
|
||||
It gives you information about the token scope, expiration date and the user, which is bound to the token and the last
|
||||
time the token was used.
|
||||
11
docs/api/index.md
Normal file
11
docs/api/index.md
Normal file
@@ -0,0 +1,11 @@
|
||||
---
|
||||
layout: default
|
||||
title: API
|
||||
nav_order: 7
|
||||
has_children: true
|
||||
---
|
||||
|
||||
# API
|
||||
|
||||
Part-DB provides a REST API to access the data stored in the database.
|
||||
In this section you can find information about the API and how to use it.
|
||||
178
docs/api/intro.md
Normal file
178
docs/api/intro.md
Normal file
@@ -0,0 +1,178 @@
|
||||
---
|
||||
title: Introduction
|
||||
layout: default
|
||||
parent: API
|
||||
nav_order: 1
|
||||
---
|
||||
|
||||
# Introduction
|
||||
|
||||
Part-DB provides a [REST API](https://en.wikipedia.org/wiki/REST) to programmatically access the data stored in the
|
||||
database.
|
||||
This allows external applications to interact with Part-DB, extend it or integrate it into other applications.
|
||||
|
||||
{: .warning }
|
||||
> This feature is currently in beta. Please report any bugs you find.
|
||||
> The API should not be considered stable yet and could change in future versions, without prior notice.
|
||||
> Some features might be missing or not working yet.
|
||||
> Also be aware, that there might be security issues in the API, which could allow attackers to access or edit data via
|
||||
> the API, which
|
||||
> they normally should be able to access. So currently you should only use the API with trusted users and trusted
|
||||
> applications.
|
||||
|
||||
Part-DB uses [API Platform](https://api-platform.com/) to provide the API, which allows for easy creation of REST APIs
|
||||
with Symfony and gives you a lot of features out of the box.
|
||||
See the [API Platform documentation](https://api-platform.com/docs/core/) for more details about the API Platform
|
||||
features and how to use them.
|
||||
|
||||
## Enable the API
|
||||
|
||||
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).
|
||||
Please note that there are two relevant permissions, the first one allows users to access the `/api/` path at all and
|
||||
showing the documentation,
|
||||
and the second one allows them to create API tokens which is needed for authentication of external applications.
|
||||
|
||||
## Authentication
|
||||
|
||||
To use API endpoints, the external application has to authenticate itself, so that Part-DB knows which user is accessing
|
||||
the data and
|
||||
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
|
||||
with the `Authorization` header as bearer token, so you add a header `Authorization: Bearer <your token>`.
|
||||
|
||||
See [Authentication chapter]({% link api/authentication.md %}) for more details.
|
||||
|
||||
## API endpoints
|
||||
|
||||
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/`).
|
||||
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`.
|
||||
|
||||
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.
|
||||
For most entities, there are endpoints like this:
|
||||
|
||||
* **GET**: `/api/categories/` - List all categories in the database (with pagination of the results)
|
||||
* **POST**: `/api/categories/` - Create a new category
|
||||
* **GET**: `/api/categories/{id}` - Get a specific category by its ID
|
||||
* **DELETE**: `/api/categories/{id}` - Delete a specific category by its ID
|
||||
* **UPDATE**: `/api/categories/{id}` - Update a specific category by its ID. Only the fields which are sent in the
|
||||
request are updated, all other fields are left unchanged.
|
||||
Be aware that you have to set the [JSON Merge Patch](https://datatracker.ietf.org/doc/html/rfc7386) content type
|
||||
header (`Content-Type: application/merge-patch+json`) for this to work.
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
## Formats
|
||||
|
||||
The API supports different formats for the request and response data, which you can control via the `Accept`
|
||||
and `Content-Type` headers.
|
||||
You should use [JSON-LD](https://json-ld.org/) as format, which is basically JSON with some additional metadata, which
|
||||
allows
|
||||
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.
|
||||
|
||||
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
|
||||
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
|
||||
JSON-LD response (e.g. `/api/parts.jsonld`).
|
||||
|
||||
## OpenAPI schema
|
||||
|
||||
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`).
|
||||
This schema is a machine-readable description of the API, which can be imported in software to test the API or even
|
||||
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
|
||||
languages, like [OpenAPI Generator](https://openapi-generator.tech/).
|
||||
|
||||
An JSONLD/Hydra version of the schema is also available under `/api/docs.jsonld` (
|
||||
so `https://your-part-db.local/api/docs.jsonld`).
|
||||
|
||||
## Interactive documentation
|
||||
|
||||
Part-DB provides an interactive documentation for the API, which is available under `/api/docs` (
|
||||
so `https://your-part-db.local/api/docs`).
|
||||
You can pass your API token in the form on the top of the page, to authenticate yourself, and then you can try out the
|
||||
API directly in the browser.
|
||||
This is a great way to test the API and see how it works, without having to write any code.
|
||||
|
||||
## Pagination
|
||||
|
||||
By default, all list endpoints are paginated, which means only a certain number of results is returned per request.
|
||||
To get another page of the results, you have to use the `page` query parameter, which contains the page number you want
|
||||
to get (e.g. `/api/categoues/?page=2`).
|
||||
When using JSONLD, the links to the next page are also included in the `hydra:view` property of the response.
|
||||
|
||||
To change the size of the pages (the number of items in a single page) use the `itemsPerPage` query parameter (
|
||||
e.g. `/api/categoues/?itemsPerPage=50`).
|
||||
|
||||
See [API Platform docs](https://api-platform.com/docs/core/pagination) for more infos.
|
||||
|
||||
## Filtering results / Searching
|
||||
|
||||
When retrieving a list of entities, you can restrict the results by various filters. Almost all entities have a search
|
||||
filter,
|
||||
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 wildcard for multiple
|
||||
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
|
||||
by numeric values or dates. See the endpoint documentation for the available filters.
|
||||
|
||||
## Filter by associated entities
|
||||
|
||||
To get all parts with a certain category, manufacturer, etc. you can use the `category`, `manufacturer`, etc. query
|
||||
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.
|
||||
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`.
|
||||
|
||||
Suffix an id with `+` to suffix, to include all direct children categories of the given category. Use the `++` suffix to
|
||||
include all children categories recursively.
|
||||
To get all parts with the category "Resistor" (Category ID 1) and all children categories of "Capacitor" (Category ID
|
||||
2), you can use `/api/parts.jsonld?category=1,2++`.
|
||||
|
||||
See the endpoint documentation for the available entity filters.
|
||||
|
||||
## Ordering results
|
||||
|
||||
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
|
||||
this parameter multiple times to order by multiple fields.
|
||||
|
||||
See the endpoint documentation for the available fields to order by.
|
||||
|
||||
## Property filter
|
||||
|
||||
Sometimes you only want to get a subset of the properties of an entity, for example when you only need the name of a
|
||||
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
|
||||
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
|
||||
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
|
||||
all entities in the collection.
|
||||
|
||||
See [API Platform docs](https://api-platform.com/docs/core/filters/#property-filter) for more infos.
|
||||
|
||||
## Change comment
|
||||
|
||||
Similar to the changes using Part-DB web interface, you can add a change comment to every change you make via the API,
|
||||
which will be
|
||||
visible in the log of the entity.
|
||||
|
||||
You can pass the text for this via the `_comment` query parameter (beware the proper encoding). For
|
||||
example `/api/parts/123?_comment=This%20is%20a%20change%20comment`.
|
||||
BIN
docs/assets/usage/information_provider_system/animation.gif
Normal file
BIN
docs/assets/usage/information_provider_system/animation.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 358 KiB |
211
docs/concepts.md
211
docs/concepts.md
@@ -5,6 +5,7 @@ nav_order: 2
|
||||
---
|
||||
|
||||
# Concepts
|
||||
|
||||
This page explains the different concepts of Part-DB and what their intended use is:
|
||||
|
||||
1. TOC
|
||||
@@ -13,42 +14,76 @@ This page explains the different concepts of Part-DB and what their intended use
|
||||
## Part managment
|
||||
|
||||
### Part
|
||||
A part is the central concept of Part-DB. A part represents a single kind (or type) of a thing, like an electronic component, an device, an book or similar (depending on what you use Part-DB for). A part entity just represents a certain type of a thing, so if you have 1000 times an 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 each other, so that it does not matter which one of your 1000 things of Part you use.
|
||||
|
||||
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
|
||||
type of thing, so if you have 1000 times an 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
|
||||
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:
|
||||
* **Name** (Required): The name of the part or how you wanna call it. This could be an manufacturer provided name, or a name you thought of your self. The name have to be unique in a single category.
|
||||
* **Description**: A short (single-line) description of what this part is/does. For longer informations you should use the comment field or the specifications
|
||||
|
||||
* **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.
|
||||
* **Description**: A short (single-line) description of what this part is/does. For longer information you should use
|
||||
the comment field or the specifications
|
||||
* **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), but tags are much less strict and formal (they dont 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.
|
||||
* **Min Instock**: *Not really implemented yet*. Parts where the total instock is below this value, will show up for ordering.
|
||||
* **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 footprint will be shown instead in tables.
|
||||
* **Tags**: The list of tags this part belong 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
|
||||
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
|
||||
ordering.
|
||||
* **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
|
||||
footprint will be shown instead in tables.
|
||||
* **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 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 determine it automatically from the part name, set in the manufacturer entity (or no manfacturer is set), you can set the link here for each part individually.
|
||||
* **Manufacturing Status**: The manufacturing status of this part, meaning the information about where the part is in its manufacturing lifecycle.
|
||||
* **Needs review**: If you think parts informations maybe are 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 informations are not completly trustworthy.
|
||||
* **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.
|
||||
* **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
|
||||
the link here for each part individually.
|
||||
* **Manufacturing Status**: The manufacturing status of this part, meaning the information about where the part is in
|
||||
its manufacturing lifecycle.
|
||||
* **Needs review**: If you think parts information maybe are 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
|
||||
completely trustworthy.
|
||||
* **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.
|
||||
* **Internal Part number** (IPN): Each part is automatically assigned an numerical ID which 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 identifiers, or sync parts identifiers with the identifiers of another database you can use this field.
|
||||
* **Internal Part number** (IPN): Each part is automatically assigned a numerical ID which 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
|
||||
identifiers, or sync parts identifiers with the identifiers of another database you can use this field.
|
||||
|
||||
### Stock / Part lot
|
||||
A part can have many stock at multiple different locations. This is represented by part lots / stocks, which consists basically of a storelocation (so where are the parts of this lot are stored) and an amount (how many parts are there).
|
||||
|
||||
### Purchase Informations
|
||||
The purchase informations describe where the part can be bought (at which vendors) and to which prices.
|
||||
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.
|
||||
An order information can contain multiple price informations, which describes the prices for the part at the supplier including bulk discount, etc.
|
||||
A part can have many stock 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).
|
||||
|
||||
### Purchase Information
|
||||
|
||||
The purchase information describe where the part can be bought (at which vendors) and to which prices.
|
||||
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.
|
||||
An order information can contain multiple price information, which describes the prices for the part at the supplier
|
||||
including bulk discount, etc.
|
||||
|
||||
### Parameters
|
||||
Parameters represents various specifications / parameters of a part, like the 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 parameters 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 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 the same group value will be shown under the same group title).
|
||||
Parameters represents 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
|
||||
parameters 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
|
||||
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
|
||||
the same group value will be shown under the same group title).
|
||||
|
||||
## Core data
|
||||
|
||||
### Category
|
||||
|
||||
A category is used to group parts logically by their function (e.g. all NPN transistors would be put in a "NPN-Transistors" category).
|
||||
Categories are hierarchical structures meaning that you can create logical trees to group categories together. A possible category tree could look like this:
|
||||
A category is used to group parts logically by their function (e.g. all NPN transistors would be put in a "
|
||||
NPN-Transistors" category).
|
||||
Categories are hierarchical structures meaning that you can create logical trees to group categories together. A
|
||||
possible category tree could look like this:
|
||||
|
||||
* Active Components
|
||||
* Transistors
|
||||
@@ -60,97 +95,145 @@ Categories are hierarchical structures meaning that you can create logical trees
|
||||
* MCUs
|
||||
* Passive Components
|
||||
* Capacitors
|
||||
* Resitors
|
||||
* Resistors
|
||||
|
||||
### Supplier
|
||||
A Supplier is a vendor / distributor where you can buy/order parts. Price informations of parts are associated with a supplier.
|
||||
|
||||
A Supplier is a vendor / distributor where you can buy/order parts. Price information of parts are associated with a
|
||||
supplier.
|
||||
|
||||
### Manufacturer
|
||||
A manufacturer represents the company that manufacturer / build various parts (not necessary sell them). If the manufacturer also sell the parts, you have to create a supplier for that.
|
||||
|
||||
### Storelocation
|
||||
A storelocation 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).
|
||||
A manufacturer represents the company that manufacturer / build various parts (not necessary sell them). If the
|
||||
manufacturer also sell the parts, you have to create a supplier for that.
|
||||
|
||||
Storelocations are hierarchical to represent storelocations contained in each other.
|
||||
### 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
|
||||
SMD feeder of a machine or so).
|
||||
|
||||
Storage locations are hierarchical to represent storage locations contained in each other.
|
||||
An example tree could look like this:
|
||||
|
||||
* Shelf 1
|
||||
* Box 1
|
||||
* Box 2
|
||||
* Box shelf A1
|
||||
* Box shelf A2
|
||||
* Box shelf B1
|
||||
* Box shelf B2
|
||||
* Box 1
|
||||
* Box 2
|
||||
* Box shelf A1
|
||||
* Box shelf A2
|
||||
* Box shelf B1
|
||||
* Box shelf B2
|
||||
* Shelf 2
|
||||
* Cupboard
|
||||
|
||||
Storelocations should be defined down to the smallest possible location, to make finding the part again easy.
|
||||
Storage locations should be defined down to the smallest possible location, to make finding the part again easy.
|
||||
|
||||
### Footprint
|
||||
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.
|
||||
You can assign an image (and an 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.
|
||||
|
||||
Footprints are a hierachically which allows you to build logical sorted trees. An example tree could look like this:
|
||||
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.
|
||||
You can assign an image (and an 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.
|
||||
|
||||
Footprints are a hierarchically which allows you to build logical sorted trees. An example tree could look like this:
|
||||
|
||||
* Through-Hole components
|
||||
* DIP
|
||||
* DIP-8
|
||||
* DIP-28
|
||||
* DIP-28W
|
||||
* DIP-8
|
||||
* DIP-28
|
||||
* DIP-28W
|
||||
* TO
|
||||
* TO-92
|
||||
* TO-92
|
||||
* SMD components
|
||||
* SOIC
|
||||
* SO-8
|
||||
* SO-8
|
||||
* Resistors
|
||||
* 0805
|
||||
* 0603
|
||||
* 0805
|
||||
* 0603
|
||||
|
||||
### Measurement Unit
|
||||
By default part instock 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 the volume of a liquid, you have to define a measurement unit.
|
||||
|
||||
By default, part instock 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
|
||||
the volume of a liquid, you have to define a measurement unit.
|
||||
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 with this unit is shown.
|
||||
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
|
||||
with this unit is shown.
|
||||
|
||||
### Currency
|
||||
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 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 exchange rate will be used to show users the prices in their preferred currency.
|
||||
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
|
||||
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
|
||||
exchange rate will be used to show users the prices in their preferred currency.
|
||||
|
||||
## Attachments
|
||||
|
||||
### Attachment
|
||||
An attachment is an file that can be associated with another entity (like a Part, Storelocation, User, etc.). This could 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 allowed file types), a name describing the attachment and a file. The file can either be uploaded to the server and stored there, or given as a link to a file on another webpath. If configured in the settings, it is also possible that the webserver downloads the file from the supplied website and stores it locally on the server.
|
||||
An attachment is a file that can be associated with another entity (like a Part, Storelocation, User, etc.). This could
|
||||
for example be a datasheet in a Part, the logo of a vendor or some CAD drawing of a footprint.
|
||||
|
||||
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/sensitve files on it, you should mark the attachment as "Private attachment". Private attachments are only accessible to users, which has the permission to access private attachments.
|
||||
Please not, that no thumbnails are generated for private attachments, which can have an performance impact.
|
||||
An attachment has an attachment type (see below), which groups the attachments logically (and optionally restricts the
|
||||
allowed file types), a name describing the attachment and a file. The file can either be uploaded to the server and
|
||||
stored there, or given as a link to a file on another web path. If configured in the settings, it is also possible that
|
||||
the webserver downloads the file from the supplied website and stores it locally on the server.
|
||||
|
||||
Part-DB ships some preview images for various common footprints like DIP-8 and others, as internal ressources. 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.
|
||||
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
|
||||
attachment as "Private attachment". Private attachments are only accessible to users, which has the permission to access
|
||||
private attachments.
|
||||
Please not, 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
|
||||
be accessed/searched by typing the keyword in the URL field of a part and choosing one of the choices from the dropdown.
|
||||
|
||||
### Preview image / attachment
|
||||
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 supplier, the schematic symbol of a category or the image of an footprint.
|
||||
|
||||
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
|
||||
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.
|
||||
|
||||
Please note that as long as the picture is not secret, it should be stored on the Part-DB instance (by upload, or letting Part-DB download the file) and *not* be marked as a private attachments, so that thumbnails can be generated for the picture (which improves performance).
|
||||
|
||||
Please note that as long as the picture is not secret, it should be stored on the Part-DB instance (by upload, or
|
||||
letting Part-DB download the file) and *not* be marked as a private attachments, so that thumbnails can be generated for
|
||||
the picture (which improves performance).
|
||||
|
||||
### Attachment types
|
||||
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.
|
||||
|
||||
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.
|
||||
You can define file type restrictions, which file types and extensions are allowed for files with that attachment type.
|
||||
|
||||
## User System
|
||||
### User
|
||||
Each person which should be able to use Part-DB (by logging in) is represented by an 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 its own personal account with an 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 an non-logged in user can do. Normally the anonymous user should be the most restricted user.
|
||||
### User
|
||||
|
||||
Each person which 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
|
||||
its 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.
|
||||
Normally the anonymous user should be the most restricted user.
|
||||
|
||||
For simplification of access management users can be assigned to groups.
|
||||
|
||||
### Group
|
||||
A group is 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 managment, 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.
|
||||
|
||||
A group is 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
|
||||
use cases and then just assign users to them, without the need to change every permission on the users individually.
|
||||
|
||||
## Labels
|
||||
### Label profiles
|
||||
A label profile represents an template for a label (for a storelocation, a part or part lot). It consists of a size, an barcode type and the content. There are various placeholders which can be inserted in the text content and which will be used 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 dialog), however if you want to generate many labels, it is recommended to save the settings as label profile, to save it for later usage. This ensures that all generated labels look the same.
|
||||
### 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
|
||||
barcode type and the content. There are various placeholders which can be inserted in the text content and which will be
|
||||
used 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
|
||||
dialog), however if you want to generate many labels, it is recommended to save the settings as label profile, to save
|
||||
it for later usage. This ensures that all generated labels look the same.
|
||||
@@ -6,91 +6,232 @@ nav_order: 5
|
||||
|
||||
# Configuration
|
||||
|
||||
Part-DBs behavior can be configured to your needs. There are different kind of configuration options: Options which are user changable (changable dynamically via frontend), options which can be configured by environment variables, and options which are only configurable via symfony config files.
|
||||
Part-DBs behavior can be configured to your needs. There are different kind of configuration options: Options which are
|
||||
user changeable (changeable dynamically via frontend), options which can be configured by environment variables, and
|
||||
options which are only configurable via symfony config files.
|
||||
|
||||
## User changable
|
||||
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 the user admin page:
|
||||
* **Language**: The language that the users prefers, 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.
|
||||
* **Timezone**: The timezone which the user resides in and in which all dates and times should be shown. By default the globally configured language.
|
||||
## User changeable
|
||||
|
||||
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
|
||||
the user admin page:
|
||||
|
||||
* **Language**: The language that the users prefers, 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.
|
||||
* **Timezone**: The timezone which the user resides in and in which all dates and times should be shown. By default, the
|
||||
globally configured language.
|
||||
* **Theme**: The theme to use for the frontend. Allows the user to choose the frontend design, he prefers.
|
||||
* **Prefered currency**: One of the defined currencies, in which all prices should be shown, if possible. Prices with other currencies will be converted to the price selected here
|
||||
* **Preferred currency**: One of the defined currencies, in which all prices should be shown, if possible. Prices with
|
||||
other currencies will be converted to the price selected here
|
||||
|
||||
## Environment variables (.env.local)
|
||||
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 options listed, see `.env` file for full list of possible env variables.
|
||||
|
||||
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
|
||||
options listed, see `.env` file for full list of possible env variables.
|
||||
|
||||
### General options
|
||||
* `DATABASE_URL`: Configures the database which Part-DB uses. For mysql 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 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`)
|
||||
* `DEFAULT_LANG`: The default language to use serverwide (when no language is explictly specified by a user or via language chooser). Must be something like `en`, `de`, `fr`, etc.
|
||||
* `DEFAULT_TIMEZONE`: The default timezone to use globally, when a user has not 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 for a list of available options.
|
||||
* `BASE_CURRENCY`: The currency to use internally for monetary values and when no currency is explictly specified. When migrating from a legacy Part-DB version, this should be the same as the currency in the old Part-DB instance (normally euro). This should be the currency you use the most. **Please note that you can not really change this setting after you have created data**. The value has to be a valid [ISO4217](https://en.wikipedia.org/wiki/ISO_4217) code, like `EUR` or `USD`.
|
||||
* `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`.
|
||||
* `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 an URL and create it as local file. Please not that this allows users access to all ressources publicly available to the server (so full access to other servers in the same local network), which could be a security risk.
|
||||
* `USE_GRAVATAR`: Set to `1` to use [gravatar.com](gravatar.com) images for user avatars (as long as they have not set their own picture). The users browsers have to download the pictures from a third-party (gravatars) server, so 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` to specify the size in kilobytes, megabytes or gigabytes. By default `100M` (100 megabytes). Please note that this 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.
|
||||
* `DEFAULT_URI`: The default URI base to use for the Part-DB, when no URL can be determined from the browser request. This should be the primary URL/Domain, which is used to access Part-DB. This value is used to create correct links in 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 with a slash**.
|
||||
|
||||
* `DATABASE_URL`: Configures the database which Part-DB uses. For mysql 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
|
||||
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`)
|
||||
* `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.
|
||||
* `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.
|
||||
* `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
|
||||
for a list of available options.
|
||||
* `BASE_CURRENCY`: The currency to use internally for monetary values and when no currency is explicitly specified. When
|
||||
migrating from a legacy Part-DB version, this should be the same as the currency in the old Part-DB instance (normally
|
||||
euro). This should be the currency you use the most. **Please note that you can not really change this setting after
|
||||
you have created data**. The value has to be a valid [ISO4217](https://en.wikipedia.org/wiki/ISO_4217) code,
|
||||
like `EUR` or `USD`.
|
||||
* `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`.
|
||||
* `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
|
||||
resources publicly available to the server (so full access to other servers in the same local network), which could
|
||||
be a security risk.
|
||||
* `ATTACHMENT_DOWNLOAD_BY_DEFAULT`: When this is set to 1, the "download external file" checkbox is checked by default
|
||||
when adding a new attachment. Otherwise, it is unchecked by default. Use this if you wanna download all attachments
|
||||
locally by default. Attachment download is only possible, when `ALLOW_ATTACHMENT_DOWNLOADS` is set to 1.
|
||||
* `USE_GRAVATAR`: Set to `1` to use [gravatar.com](https://gravatar.com/) images for user avatars (as long as they have
|
||||
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.
|
||||
* `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
|
||||
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.
|
||||
* `DEFAULT_URI`: The default URI base to use for the Part-DB, when no URL can be determined from the browser request.
|
||||
This should be the primary URL/Domain, which is used to access Part-DB. This value is used to create correct links in
|
||||
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
|
||||
with a slash**.
|
||||
* `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
|
||||
to make change comments optional everywhere. Possible values are:
|
||||
* `part_edit`: Edit operation of an existing part
|
||||
* `part_delete`: Delete operation of an existing part
|
||||
* `part_create`: Creation of a new part
|
||||
* `part_stock_operation`: Stock operation on a part (therefore withdraw, add or move stock)
|
||||
* `datastructure_edit`: Edit operation of an existing datastructure (e.g. category, manufacturer, ...)
|
||||
* `datastructure_delete`: Delete operation of a existing 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
|
||||
versions, or if your server can not connect to the internet.
|
||||
|
||||
### E-Mail settings
|
||||
* `MAILER_DSN`: You can configure the mail provider which should be used for email delivery (see https://symfony.com/doc/current/components/mailer.html for full documentation). If you just want to use an SMTP 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 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 sent from.
|
||||
* `ALLOW_EMAIL_PW_RESET`: Set this value to true, if you wan to allow users to reset their password via an email notification. You have to configure the mailprovider first before via the MAILER_DSN setting.
|
||||
|
||||
* `MAILER_DSN`: You can configure the mail provider which should be used for email delivery (
|
||||
see https://symfony.com/doc/current/components/mailer.html for full documentation). If you just want to use an SMTP
|
||||
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
|
||||
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
|
||||
sent from.
|
||||
* `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 mailprovider first before via the MAILER_DSN setting.
|
||||
|
||||
### Table related settings
|
||||
|
||||
* `TABLE_DEFAULT_PAGE_SIZE`: The default page size for tables. This is the number of rows which are shown per page. Set
|
||||
to `-1` to disable pagination and show all rows at once.
|
||||
* `TABLE_PARTS_DEFAULT_COLUMNS`: The columns in parts tables, which are visible by default (when loading table for first
|
||||
time).
|
||||
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`.
|
||||
|
||||
### History/Eventlog related settings
|
||||
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 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)
|
||||
* `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 lot of changes to enties.
|
||||
* `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.
|
||||
|
||||
If you wanna use want to revert changes or view older revisions of entities, then `HISTORY_SAVE_CHANGED_FIELDS`, `HISTORY_SAVE_CHANGED_DATA` and `HISTORY_SAVE_REMOVED_DATA` all have to be true.
|
||||
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
|
||||
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)
|
||||
* `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
|
||||
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
|
||||
easily undelete an entity, when it was removed accidentally.
|
||||
* `HISTORY_SAVE_NEW_DATA`: When this option is set to true, the new data (the data after a change) is saved to element
|
||||
changed log entries. This allows you to easily see the changes between two revisions of an entity. This can increase
|
||||
database size, when you have a lot of changes to entities.
|
||||
|
||||
If you want to use want to revert changes or view older revisions of entities,
|
||||
then `HISTORY_SAVE_CHANGED_FIELDS`, `HISTORY_SAVE_CHANGED_DATA` and `HISTORY_SAVE_REMOVED_DATA` all have to be true.
|
||||
|
||||
### 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 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 contain senstive informations, but could confuse end-users.
|
||||
|
||||
* `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)
|
||||
* `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.
|
||||
|
||||
### EDA related settings
|
||||
|
||||
* `EDA_KICAD_CATEGORY_DEPTH`: A number, which determines how many levels of Part-DB categories should be shown inside KiCad.
|
||||
All parts in the selected category and all subcategories are shown in KiCad.
|
||||
For performance reason this value should not be too high. The default is 0, which means that only the top level categories are shown in KiCad.
|
||||
All parts in the selected category and all subcategories are shown in KiCad. Set this to a higher value, if you want to show more categories in KiCad.
|
||||
When you set this value to -1, all parts are shown inside a single category in KiCad.
|
||||
|
||||
### SAML SSO settings
|
||||
The following settings can be used to enable and configure Single-Sign on via SAML. This allows users to login to 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 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 file is not backuped by the backup script, so you have to backup 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.
|
||||
|
||||
* `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.
|
||||
* `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 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 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 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 afterwards by editing the user.
|
||||
* `SAML_IDP_ENTITY_ID`: The entity ID of your SAML Identity Provider (IdP). You can find this value in the metadata XML file or configuration UI of your IdP.
|
||||
* `SAML_IDP_SINGLE_SIGN_ON_SERVICE`: The URL of the SAML IdP Single Sign-On Service (SSO). You can find this value in the metadata XML file or configuration UI of your IdP.
|
||||
* `SAML_IDP_SINGLE_LOGOUT_SERVICE`: The URL of the SAML IdP Single Logout Service (SLO). You can find this value in the metadata XML file or configuration UI of your IdP.
|
||||
* `SAML_IDP_X509_CERT`: The base64 encoded X.509 public certificate of your SAML IdP. You can find this value in the metadata XML file or configuration UI of your IdP. It should start with `MIIC` and end with `=`.
|
||||
* `SAML_SP_ENTITY_ID`: The entity ID of your SAML Service Provider (SP). This is the value you have configured for the Part-DB client in your IdP.
|
||||
* `SAML_SP_X509_CERT`: The public X.509 certificate of your SAML SP (here Part-DB). This is the value you have configured for the Part-DB client in your IdP. It should start with `MIIC` and end with `=`. IdPs like keycloak allows you to generate a public/private key pair for the client which you can setup here and in the `SAML_SP_PRIVATE_KEY` setting.
|
||||
* `SAML_SP_PRIVATE_KEY`: The private key of your SAML SP (here Part-DB), corresponding the public key specified in `SAML_SP_X509_CERT`. This is the value you have configured for the Part-DB client in your IdP. It should start with `MIIE` and end with `=`. IdPs like keycloak allows you to generate a public/private key pair for the client which you can setup here and in the `SAML_SP_X509_CERT` setting.
|
||||
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
|
||||
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).
|
||||
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
|
||||
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
|
||||
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 %})
|
||||
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
|
||||
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.
|
||||
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.
|
||||
* `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
|
||||
Part-DB administrator can change the group afterward by editing the user.
|
||||
* `SAML_IDP_ENTITY_ID`: The entity ID of your SAML Identity Provider (IdP). You can find this value in the metadata XML
|
||||
file or configuration UI of your IdP.
|
||||
* `SAML_IDP_SINGLE_SIGN_ON_SERVICE`: The URL of the SAML IdP Single Sign-On Service (SSO). You can find this value in
|
||||
the metadata XML file or configuration UI of your IdP.
|
||||
* `SAML_IDP_SINGLE_LOGOUT_SERVICE`: The URL of the SAML IdP Single Logout Service (SLO). You can find this value in the
|
||||
metadata XML file or configuration UI of your IdP.
|
||||
* `SAML_IDP_X509_CERT`: The base64 encoded X.509 public certificate of your SAML IdP. You can find this value in the
|
||||
metadata XML file or configuration UI of your IdP. It should start with `MIIC` and end with `=`.
|
||||
* `SAML_SP_ENTITY_ID`: The entity ID of your SAML Service Provider (SP). This is the value you have configured for the
|
||||
Part-DB client in your IdP.
|
||||
* `SAML_SP_X509_CERT`: The public X.509 certificate of your SAML SP (here Part-DB). This is the value you have
|
||||
configured for the Part-DB client in your IdP. It should start with `MIIC` and end with `=`. IdPs like keycloak allows
|
||||
you to generate a public/private key pair for the client which you can set up here and in the `SAML_SP_PRIVATE_KEY`
|
||||
setting.
|
||||
* `SAML_SP_PRIVATE_KEY`: The private key of your SAML SP (here Part-DB), corresponding the public key specified
|
||||
in `SAML_SP_X509_CERT`. This is the value you have configured for the Part-DB client in your IdP. It should start
|
||||
with `MIIE` and end with `=`. IdPs like keycloak allows you to generate a public/private key pair for the client which
|
||||
you can set up here and in the `SAML_SP_X509_CERT` setting.
|
||||
|
||||
### Information provider settings
|
||||
|
||||
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.
|
||||
|
||||
### Other / less used options
|
||||
* `TRUSTED_PROXIES`: Set the IP addresses (or IP blocks) of trusted reverse proxies here. This is needed to get correct IP informations (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 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 instance, 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 support rewrite. In this case, all URL pathes will contain index.php/, which is needed then. Normally this setting do not need to be changed.
|
||||
* `FIXER_API_KEY`: If you want to automatically retrieve exchange rates for base currencies other than euros, you have 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.
|
||||
* `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 informations!**)
|
||||
* `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.
|
||||
|
||||
* `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).
|
||||
* `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.
|
||||
* `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.
|
||||
* `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
|
||||
not need to be changed.
|
||||
* `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
|
||||
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
|
||||
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
|
||||
container. In all other applications you can just change the `config/banner.md` file.
|
||||
|
||||
## Banner
|
||||
|
||||
To change the banner you can find on the homepage, you can either set the `BANNER` environment variable to the text you
|
||||
want to show, or you can edit the `config/banner.md` file. The banner is written in markdown, so you can use all
|
||||
markdown (and even some subset of HTML) syntax to format the text.
|
||||
|
||||
## parameters.yaml
|
||||
You can also configure some options via the `config/parameters.yaml` file. This should normally not needed,
|
||||
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 configuration
|
||||
|
||||
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
|
||||
manual merge, when you have changed something here and update to a newer version of Part-DB. It is possible that
|
||||
configuration
|
||||
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 command `bin/console cache:clear`.
|
||||
If you change something here, you have to clear the cache, before the changes will take effect with the
|
||||
command `bin/console cache:clear`.
|
||||
|
||||
The following options are available:
|
||||
|
||||
* `partdb.global_theme`: The default theme to use, when no user specific theme is set. Should be one of the themes from the `partdb.available_themes` config option.
|
||||
* `partdb.locale_menu`: The codes of the languages, which should be shown in the language chooser menu (the one with the user icon in the navbar). The first language in the list will be the default language.
|
||||
* `partdb.gpdr_compliance`: When set to true (default value), IP addresses which are saved in the database will be anonymized, by removing the last byte of the IP. This is required by the GDPR (General Data Protection Regulation) in the EU.
|
||||
* `partdb.sidebar.items`: The panel contents which should be shown in the sidebar by default. You can also change the number of sidebar panels by changing the number of items in this list.
|
||||
* `partdb.global_theme`: The default theme to use, when no user specific theme is set. Should be one of the themes from
|
||||
the `partdb.available_themes` config option.
|
||||
* `partdb.locale_menu`: The codes of the languages, which should be shown in the language chooser menu (the one with the
|
||||
user icon in the navbar). The first language in the list will be the default language.
|
||||
* `partdb.gdpr_compliance`: When set to true (default value), IP addresses which are saved in the database will be
|
||||
anonymized, by removing the last byte of the IP. This is required by the GDPR (General Data Protection Regulation) in
|
||||
the EU.
|
||||
* `partdb.sidebar.items`: The panel contents which should be shown in the sidebar by default. You can also change the
|
||||
number of sidebar panels by changing the number of items in this list.
|
||||
* `partdb.sidebar.root_node_enable`: Show a root node in the sidebar trees, of which all nodes are children of
|
||||
* `partdb.sidebar.root_expanded`: Expand the root node in the sidebar trees by default
|
||||
* `partdb.available_themes`: The list of available themes a user can choose from.
|
||||
@@ -5,38 +5,52 @@ nav_order: 0
|
||||
---
|
||||
|
||||
# Part-DB
|
||||
|
||||
Part-DB is an Open-Source inventory management system for your electronic components.
|
||||
It is installed on a web server and so can be accessed with any browser without the need to install additional software.
|
||||
|
||||
{: .important-title }
|
||||
> Demo
|
||||
>
|
||||
> If you want to test Part-DB without installing it, you can use [this](https://part-db.herokuapp.com) Heroku instance.
|
||||
> (Or this link for the [German Version](https://part-db.herokuapp.com/de/)).
|
||||
>
|
||||
> If you want to test Part-DB without installing it, you can use [this](https://demo.part-db.de/) Heroku instance.
|
||||
> (Or this link for the [German Version](https://demo.part-db.de/de/)).
|
||||
>
|
||||
> You can log in with username: **user** and password: **user**, to change/create data.
|
||||
>
|
||||
> Every change to the master branch gets automatically deployed, so it represents the currenct development progress and is
|
||||
> maybe not completly stable. Please mind, that the free Heroku instance is used, so it can take some time when loading the page
|
||||
> 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
|
||||
> the page
|
||||
> for the first time.
|
||||
|
||||
## Features
|
||||
|
||||
* 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 like datasheets or pictures with the parts.
|
||||
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.
|
||||
* 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
|
||||
* 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. Password reset via email can be setuped.
|
||||
* Optional support for single sign-on (SSO) via SAML (using an intermediate service like [Keycloak](https://www.keycloak.org/) you can connect Part-DB to an existing LDAP or Active Directory server)
|
||||
* Import/Export system (partial working)
|
||||
* 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
|
||||
* Event log: Track what changes happens to your inventory, track which user does what. Revert your parts to older versions.
|
||||
Two-factor authentication is supported (Google Authenticator and Webauthn/U2F keys) and can be enforced for groups.
|
||||
Password reset via email can be setup.
|
||||
* Optional support for single sign-on (SSO) via SAML (using an intermediate service
|
||||
like [Keycloak](https://www.keycloak.org/) you can connect Part-DB to an existing LDAP or Active Directory server)
|
||||
* Import/Export system
|
||||
* 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
|
||||
* Event log: Track what changes happens to your inventory, track which user does what. Revert your parts to older
|
||||
versions.
|
||||
* 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
|
||||
* Support for rich text descriptions and comments in parts
|
||||
* 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)
|
||||
|
||||
* 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
|
||||
prices for parts (see [here]({% link usage/information_provider_system.md %}))
|
||||
* 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
|
||||
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,
|
||||
or makerspaces, where many users have should have (controlled) access to the shared inventory.
|
||||
@@ -44,25 +58,31 @@ or makerspaces, where many users have should have (controlled) access to the sha
|
||||
Part-DB is also used by small companies and universities for managing their inventory.
|
||||
|
||||
## License
|
||||
|
||||
Part-DB is licensed under the GNU Affero General Public License v3.0 (or at your opinion any later).
|
||||
This mostly means that you can use Part-DB for whatever you want (even use it commercially)
|
||||
as long as you publish the source code for every change you make under the AGPL, too.
|
||||
|
||||
See [LICENSE](https://github.com/Part-DB/Part-DB-symfony/blob/master/LICENSE) for more informations.
|
||||
See [LICENSE](https://github.com/Part-DB/Part-DB-symfony/blob/master/LICENSE) for more information.
|
||||
|
||||
## 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).
|
||||
There you will find various methods to support development on a monthly or a one time base.
|
||||
|
||||
## Built with
|
||||
|
||||
* [Symfony 5](https://symfony.com/): The main framework used for the serverside PHP
|
||||
* [Bootstrap 5](https://getbootstrap.com/) and [Bootswatch](https://bootswatch.com/): Used as website theme
|
||||
* [Fontawesome](https://fontawesome.com/): Used as icon set
|
||||
* [Hotwire Stimulus](https://stimulus.hotwired.dev/) and [Hotwire Turbo](https://turbo.hotwired.dev/): Frontend Javascript
|
||||
* [Hotwire Stimulus](https://stimulus.hotwired.dev/) and [Hotwire Turbo](https://turbo.hotwired.dev/): Frontend
|
||||
Javascript
|
||||
|
||||
## Authors
|
||||
* **Jan Böhmer** - *Inital work and Maintainer* - [Github](https://github.com/jbtronics/)
|
||||
|
||||
See also the list of [contributors](https://github.com/Part-DB/Part-DB-symfony/graphs/contributors) who participated in this project.
|
||||
* **Jan Böhmer** - *Initial work and Maintainer* - [GitHub](https://github.com/jbtronics/)
|
||||
|
||||
See also the list of [contributors](https://github.com/Part-DB/Part-DB-symfony/graphs/contributors) who participated in
|
||||
this project.
|
||||
|
||||
Based on the original Part-DB by Christoph Lechner and K. Jacobs
|
||||
|
||||
@@ -7,24 +7,38 @@ nav_order: 1
|
||||
|
||||
# Choosing database: SQLite or MySQL
|
||||
|
||||
Part-DB saves its data in a [relational (SQL) database](https://en.wikipedia.org/wiki/Relational_database). Part-DB 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 differences).
|
||||
Part-DB saves its data in a [relational (SQL) database](https://en.wikipedia.org/wiki/Relational_database). Part-DB
|
||||
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
|
||||
differences).
|
||||
|
||||
{: .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 started creating data**. So you should choose the database type for your usecase (and possible future uses).
|
||||
You have to choose between the database types before you start using Part-DB and **you can not change it (easily) after
|
||||
you have started creating data**. So you should choose the database type for your use case (and possible future uses).
|
||||
|
||||
## Comparison
|
||||
|
||||
**SQLite** is the default database type which is configured out of the box. All data is saved in a single file (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
|
||||
**SQLite** is the default database type which is configured out of the box. All data is saved in a single file (
|
||||
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 **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 pretty slow compared to the same operation at MySQL. In future there might be features that may only be available, when using MySQL.
|
||||
When using **SQLite** The database can be backuped easily by just copying the SQLite file to a safe place. Ideally the *
|
||||
*MySQL** database has to be dumped to a SQL file (using `mysqldump`). The `console partdb:backup` command can do this
|
||||
automatically
|
||||
|
||||
In general MySQL might perform better for big Part-DB instances with many entries, lots of users and high activity, than SQLite.
|
||||
However, SQLite does not support certain operations like regex search, which has to be emulated by PHP and therefore are
|
||||
pretty slow compared to the same operation at MySQL. In future there might be features that may only be available, when
|
||||
using MySQL.
|
||||
|
||||
In general MySQL might perform better for big Part-DB instances with many entries, lots of users and high activity, than
|
||||
SQLite.
|
||||
|
||||
## Conclusion and Suggestion
|
||||
|
||||
When you are a hobbyist and use Part-DB for your own small inventory managment with only you as user (or maybe sometimes a few other people), then the easy to use SQLite database will be fine.
|
||||
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.
|
||||
|
||||
When you are planning to have a very big database, with a lot of entries and many users which regulary (and concurrently) using Part-DB you should maybe use MySQL as this will scale better.
|
||||
When you are planning to have a very big database, with a lot of entries and many users which regularly (and
|
||||
concurrently) using Part-DB you should maybe use MySQL as this will scale better.
|
||||
@@ -7,31 +7,34 @@ nav_order: 12
|
||||
|
||||
# Email
|
||||
|
||||
Part-DB can communicate with its users via email.
|
||||
Part-DB can communicate with its users via email.
|
||||
At the moment this is only used to send password reset links, but in future this will be used for other things too.
|
||||
|
||||
To make emails work you have to properly configure a mail provider in Part-DB.
|
||||
|
||||
## Configuration
|
||||
Part-DB uses [Symfony Mailer](https://symfony.com/doc/current/mailer.html) to send emails, which supports multiple
|
||||
automatic mail providers (like MailChimp or SendGrid). If you want to use one of these providers, check the Symfony Mailer documentation for more information.
|
||||
|
||||
We will only cover the configuration of a SMTP provider here, which is sufficient for most usecases.
|
||||
You will need an email account, which you can use send emails from via password-bases SMTP authentication, this account
|
||||
Part-DB uses [Symfony Mailer](https://symfony.com/doc/current/mailer.html) to send emails, which supports multiple
|
||||
automatic mail providers (like MailChimp or SendGrid). If you want to use one of these providers, check the Symfony
|
||||
Mailer documentation for more information.
|
||||
|
||||
We will only cover the configuration of an SMTP provider here, which is sufficient for most use-cases.
|
||||
You will need an email account, which you can use send emails from via password-bases SMTP authentication, this account
|
||||
should be dedicated to Part-DB.
|
||||
|
||||
To configure the SMTP provider, you have to set the following environment variables:
|
||||
|
||||
`MAILER_DSN`: You have to provide the SMTP server address and the credentials for the email account here. The format is the following:
|
||||
`smtp://<username>:<password>@<smtp-server-address>:<port>`. In most cases the username is the email address of the account, and the port is 587.
|
||||
`MAILER_DSN`: You have to provide the SMTP server address and the credentials for the email account here. The format is
|
||||
the following:
|
||||
`smtp://<username>:<password>@<smtp-server-address>:<port>`. In most cases the username is the email address of the
|
||||
account, and the port is 587.
|
||||
So the resulting DSN could look like this: `smtp://j.doe@mail.invalid:SUPER_SECRET_PA$$WORD@smtp.mail.invalid:587`.
|
||||
|
||||
`EMAIL_SENDER_EMAIL`: This is the email address which will be used as sender address for all emails sent by Part-DB.
|
||||
This should be the same email address as the one used in the `MAILER_DSN` (the email adress of your email account):
|
||||
This should be the same email address as the one used in the `MAILER_DSN` (the email address of your email account):
|
||||
e.g. `j.doe@mail.invalid`.
|
||||
|
||||
`EMAIL_SENDER_NAME`: This is the name which will be used as sender name for all emails sent by Part-DB.
|
||||
`EMAIL_SENDER_NAME`: This is the name which will be used as sender name for all emails sent by Part-DB.
|
||||
This can be anything you want, e.g. `My Part-DB Mailer`.
|
||||
|
||||
|
||||
Now you can enable the possibility to reset password by setting the `ALLOW_EMAIL_PW_RESET` env to `1` (or `true`).
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user