mirror of
https://github.com/Part-DB/Part-DB-server.git
synced 2026-03-04 14:29:35 +00:00
Compare commits
No commits in common. "18bf68cb6abadb765e28e738abbd950ebee39ce6" and "b2946aee0d444391b8e3ea45cc7facee08894809" have entirely different histories.
18bf68cb6a
...
b2946aee0d
40 changed files with 393 additions and 903 deletions
|
|
@ -47,7 +47,6 @@
|
|||
PassEnv PROVIDER_REICHELT_ENABLED PROVIDER_REICHELT_CURRENCY PROVIDER_REICHELT_COUNTRY PROVIDER_REICHELT_LANGUAGE PROVIDER_REICHELT_INCLUDE_VAT
|
||||
PassEnv PROVIDER_POLLIN_ENABLED
|
||||
PassEnv EDA_KICAD_CATEGORY_DEPTH
|
||||
PassEnv SHOW_PART_IMAGE_OVERLAY
|
||||
|
||||
# For most configuration files from conf-available/, which are
|
||||
# enabled or disabled at a global level, it is possible to
|
||||
|
|
|
|||
31
.env
31
.env
|
|
@ -67,6 +67,34 @@ 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
|
||||
|
||||
##################################################################################
|
||||
# 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
|
||||
|
||||
# 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
|
||||
|
||||
##################################################################################
|
||||
# EDA integration related settings
|
||||
|
|
@ -129,6 +157,9 @@ NO_URL_REWRITE_AVAILABLE=0
|
|||
# Set to 1, if Part-DB should redirect all HTTP requests to HTTPS. You dont need to configure this, if your webserver already does this.
|
||||
REDIRECT_TO_HTTPS=0
|
||||
|
||||
# If you want to use fixer.io for currency conversion, you have to set this to your API key
|
||||
FIXER_API_KEY=CHANGEME
|
||||
|
||||
# Override value if you want to show to show a given text on homepage.
|
||||
# When this is empty the content of config/banner.md is used as banner
|
||||
BANNER=""
|
||||
|
|
|
|||
|
|
@ -33,10 +33,7 @@ export default class extends Controller {
|
|||
{
|
||||
let value = "";
|
||||
if (this.unitValue) {
|
||||
//Escape percentage signs
|
||||
value = this.inputTarget.value.replace(/%/g, '\\%');
|
||||
|
||||
value = "\\mathrm{" + value + "}";
|
||||
value = "\\mathrm{" + this.inputTarget.value + "}";
|
||||
} else {
|
||||
value = this.inputTarget.value;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -85,9 +85,7 @@ export default class extends Controller
|
|||
tmp += '<span>' + katex.renderToString(data.symbol) + '</span>'
|
||||
}
|
||||
if (data.unit) {
|
||||
let unit = data.unit.replace(/%/g, '\\%');
|
||||
unit = "\\mathrm{" + unit + "}";
|
||||
tmp += '<span class="ms-2">' + katex.renderToString('[' + unit + ']') + '</span>'
|
||||
tmp += '<span class="ms-2">' + katex.renderToString('[' + data.unit + ']') + '</span>'
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
"hshn/base64-encoded-file": "^5.0",
|
||||
"jbtronics/2fa-webauthn": "^v2.2.0",
|
||||
"jbtronics/dompdf-font-loader-bundle": "^1.0.0",
|
||||
"jbtronics/settings-bundle": "^v2.6.0",
|
||||
"jbtronics/settings-bundle": "dev-master",
|
||||
"jfcherng/php-diff": "^6.14",
|
||||
"knpuniversity/oauth2-client-bundle": "^2.15",
|
||||
"league/csv": "^9.8.0",
|
||||
|
|
|
|||
541
composer.lock
generated
541
composer.lock
generated
File diff suppressed because it is too large
Load diff
|
|
@ -6,8 +6,8 @@ knpu_oauth2_client:
|
|||
type: generic
|
||||
provider_class: '\League\OAuth2\Client\Provider\GenericProvider'
|
||||
|
||||
client_id: '%env(settings:digikey:clientId)%'
|
||||
client_secret: '%env(settings:digikey:secret)%'
|
||||
client_id: '%env(PROVIDER_DIGIKEY_CLIENT_ID)%'
|
||||
client_secret: '%env(PROVIDER_DIGIKEY_SECRET)%'
|
||||
|
||||
redirect_route: 'oauth_client_check'
|
||||
redirect_params: {name: 'ip_digikey_oauth'}
|
||||
|
|
@ -26,8 +26,8 @@ knpu_oauth2_client:
|
|||
type: generic
|
||||
provider_class: '\League\OAuth2\Client\Provider\GenericProvider'
|
||||
|
||||
client_id: '%env(settings:octopart:clientId)%'
|
||||
client_secret: '%env(settings:octopart:secret)%'
|
||||
client_id: '%env(PROVIDER_OCTOPART_CLIENT_ID)%'
|
||||
client_secret: '%env(PROVIDER_OCTOPART_SECRET)%'
|
||||
|
||||
redirect_route: 'oauth_client_check'
|
||||
redirect_params: { name: 'ip_octopart_oauth' }
|
||||
|
|
|
|||
|
|
@ -1,8 +1,2 @@
|
|||
jbtronics_settings:
|
||||
default_storage_adapter: Jbtronics\SettingsBundle\Storage\ORMStorageAdapter
|
||||
|
||||
cache:
|
||||
default_cacheable: true
|
||||
|
||||
orm_storage:
|
||||
default_entity_class: App\Entity\SettingsEntry
|
||||
default_storage_adapter: Jbtronics\SettingsBundle\Storage\PHPFileStorageAdapter
|
||||
|
|
@ -6,5 +6,5 @@ florianv_swap:
|
|||
providers:
|
||||
european_central_bank: ~ # European Central Bank (only works for EUR base currency)
|
||||
fixer: # Fixer.io (needs an API key)
|
||||
access_key: "%env(string:default:settings:exchange_rate:fixerApiKey:INVALID)%"
|
||||
access_key: "%env(FIXER_API_KEY)%"
|
||||
#exchange_rates_api: ~
|
||||
|
|
@ -265,13 +265,17 @@ perms: # Here comes a list with all Permission names (they have a perm_[name] co
|
|||
# label: "perm.database.write_db_settings"
|
||||
# alsoSet: ['read_db_settings', 'see_status']
|
||||
|
||||
config:
|
||||
label: "perm.config"
|
||||
group: "system"
|
||||
operations:
|
||||
change_system_settings:
|
||||
label: "perm.config.change_system_settings"
|
||||
apiTokenRole: ROLE_API_ADMIN
|
||||
#config:
|
||||
# label: "perm.config"
|
||||
# group: "system"
|
||||
# operations:
|
||||
# read_config:
|
||||
# label: "perm.config.read_config"
|
||||
# edit_config:
|
||||
# label: "perm.config.edit_config"
|
||||
# alsoSet: 'read_config'
|
||||
# server_info:
|
||||
# label: "perm.config.server_info"
|
||||
|
||||
system:
|
||||
label: "perm.system"
|
||||
|
|
|
|||
|
|
@ -199,6 +199,23 @@ services:
|
|||
arguments:
|
||||
$providers: !tagged_iterator 'app.info_provider'
|
||||
|
||||
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\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)%'
|
||||
|
||||
|
||||
####################################################################################################################
|
||||
# API system
|
||||
####################################################################################################################
|
||||
|
|
|
|||
|
|
@ -95,8 +95,6 @@ bundled with Part-DB. Set `DATABASE_MYSQL_SSL_VERIFY_CERT` if you want to accept
|
|||
particularly for securing and protecting various aspects of your application. It's a secret key that is used for
|
||||
cryptographic operations and security measures (session management, CSRF protection, etc..). Therefore this
|
||||
value should be handled as confidential data and not shared publicly.
|
||||
* `SHOW_PART_IMAGE_OVERLAY`: Set to 0 to disable the part image overlay, which appears if you hover over an image in the
|
||||
part image gallery
|
||||
|
||||
### E-Mail settings
|
||||
|
||||
|
|
|
|||
|
|
@ -1,49 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use App\Migration\AbstractMultiPlatformMigration;
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
|
||||
final class Version20250706201121 extends AbstractMultiPlatformMigration
|
||||
{
|
||||
public function getDescription(): string
|
||||
{
|
||||
return 'Add settings_entry table for storing settings';
|
||||
}
|
||||
|
||||
public function mySQLUp(Schema $schema): void
|
||||
{
|
||||
$this->addSql('CREATE TABLE settings_entry (`key` VARCHAR(255) NOT NULL, `data` JSON DEFAULT NULL, id INT AUTO_INCREMENT NOT NULL, UNIQUE INDEX UNIQ_93F8DB394E645A7E (`key`), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci`');
|
||||
|
||||
}
|
||||
|
||||
public function mySQLDown(Schema $schema): void
|
||||
{
|
||||
$this->addSql('DROP TABLE settings_entry');
|
||||
}
|
||||
|
||||
public function sqLiteUp(Schema $schema): void
|
||||
{
|
||||
$this->addSql('CREATE TABLE settings_entry ("key" VARCHAR(255) NOT NULL, "data" CLOB DEFAULT NULL, id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)');
|
||||
$this->addSql('CREATE UNIQUE INDEX UNIQ_93F8DB39F48571EB ON settings_entry ("key")');
|
||||
}
|
||||
|
||||
public function sqLiteDown(Schema $schema): void
|
||||
{
|
||||
$this->addSql('DROP TABLE settings_entry');
|
||||
}
|
||||
|
||||
public function postgreSQLUp(Schema $schema): void
|
||||
{
|
||||
$this->addSql('CREATE TABLE settings_entry ("key" VARCHAR(255) NOT NULL, "data" JSON DEFAULT NULL, id INT GENERATED BY DEFAULT AS IDENTITY NOT NULL, PRIMARY KEY(id))');
|
||||
$this->addSql('CREATE UNIQUE INDEX UNIQ_93F8DB39F48571EB ON settings_entry ("key")');
|
||||
}
|
||||
|
||||
public function postgreSQLDown(Schema $schema): void
|
||||
{
|
||||
$this->addSql('DROP TABLE settings_entry');
|
||||
}
|
||||
}
|
||||
|
|
@ -40,8 +40,6 @@ class SettingsController extends AbstractController
|
|||
#[Route("/settings", name: "system_settings")]
|
||||
public function systemSettings(Request $request, TagAwareCacheInterface $cache): Response
|
||||
{
|
||||
$this->denyAccessUnlessGranted('@config.change_system_settings');
|
||||
|
||||
//Create a clone of the settings object
|
||||
$settings = $this->settingsManager->createTemporaryCopy(AppSettings::class);
|
||||
|
||||
|
|
@ -64,6 +62,9 @@ class SettingsController extends AbstractController
|
|||
$cache->invalidateTags(['tree_treeview', 'sidebar_tree_update']);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//Render the form
|
||||
return $this->render('settings/settings.html.twig', [
|
||||
'form' => $form
|
||||
|
|
|
|||
|
|
@ -217,7 +217,7 @@ abstract class AbstractParameter extends AbstractNamedDBElement implements Uniqu
|
|||
|
||||
$str = '';
|
||||
$bracket_opened = false;
|
||||
if ($this->value_typical !== null) {
|
||||
if ($this->value_typical) {
|
||||
$str .= $this->getValueTypicalWithUnit($latex_formatted);
|
||||
if ($this->value_min || $this->value_max) {
|
||||
$bracket_opened = true;
|
||||
|
|
@ -225,11 +225,11 @@ abstract class AbstractParameter extends AbstractNamedDBElement implements Uniqu
|
|||
}
|
||||
}
|
||||
|
||||
if ($this->value_max !== null && $this->value_min !== null) {
|
||||
if ($this->value_max && $this->value_min) {
|
||||
$str .= $this->getValueMinWithUnit($latex_formatted).' ... '.$this->getValueMaxWithUnit($latex_formatted);
|
||||
} elseif ($this->value_max !== null) {
|
||||
} elseif ($this->value_max) {
|
||||
$str .= 'max. '.$this->getValueMaxWithUnit($latex_formatted);
|
||||
} elseif ($this->value_min !== null) {
|
||||
} elseif ($this->value_min) {
|
||||
$str .= 'min. '.$this->getValueMinWithUnit($latex_formatted);
|
||||
}
|
||||
|
||||
|
|
@ -449,10 +449,7 @@ abstract class AbstractParameter extends AbstractNamedDBElement implements Uniqu
|
|||
if (!$with_latex) {
|
||||
$unit = $this->unit;
|
||||
} else {
|
||||
//Escape the percentage sign for convenience (as latex uses it as comment and it is often used in units)
|
||||
$escaped = preg_replace('/\\\\?%/', "\\\\%", $this->unit);
|
||||
|
||||
$unit = '$\mathrm{'.$escaped.'}$';
|
||||
$unit = '$\mathrm{'.$this->unit.'}$';
|
||||
}
|
||||
|
||||
return $str.' '.$unit;
|
||||
|
|
@ -460,7 +457,7 @@ abstract class AbstractParameter extends AbstractNamedDBElement implements Uniqu
|
|||
|
||||
return $str;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the class of the element that is allowed to be associated with this attachment.
|
||||
* @return string
|
||||
|
|
|
|||
|
|
@ -1,35 +0,0 @@
|
|||
<?php
|
||||
/*
|
||||
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||
*
|
||||
* Copyright (C) 2019 - 2025 Jan Böhmer (https://github.com/jbtronics)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published
|
||||
* by the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
namespace App\Entity;
|
||||
|
||||
use Doctrine\DBAL\Types\Types;
|
||||
use Jbtronics\SettingsBundle\Entity\AbstractSettingsORMEntry;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
||||
#[ORM\Entity]
|
||||
class SettingsEntry extends AbstractSettingsORMEntry
|
||||
{
|
||||
#[ORM\Id, ORM\GeneratedValue, ORM\Column(type: Types::INTEGER)]
|
||||
protected int $id;
|
||||
}
|
||||
|
|
@ -241,49 +241,6 @@ class KiCadHelper
|
|||
$result["fields"]["Part-DB IPN"] = $this->createField($part->getIpn());
|
||||
}
|
||||
|
||||
// Add supplier information from orderdetails (include obsolete orderdetails)
|
||||
if ($part->getOrderdetails(false)->count() > 0) {
|
||||
$supplierCounts = [];
|
||||
|
||||
foreach ($part->getOrderdetails(false) as $orderdetail) {
|
||||
if ($orderdetail->getSupplier() !== null && $orderdetail->getSupplierPartNr() !== '') {
|
||||
$supplierName = $orderdetail->getSupplier()->getName();
|
||||
|
||||
$supplierName .= " SPN"; // Append "SPN" to the supplier name to indicate Supplier Part Number
|
||||
|
||||
if (!isset($supplierCounts[$supplierName])) {
|
||||
$supplierCounts[$supplierName] = 0;
|
||||
}
|
||||
$supplierCounts[$supplierName]++;
|
||||
|
||||
// Create field name with sequential number if more than one from same supplier (e.g. "Mouser", "Mouser 2", etc.)
|
||||
$fieldName = $supplierCounts[$supplierName] > 1
|
||||
? $supplierName . ' ' . $supplierCounts[$supplierName]
|
||||
: $supplierName;
|
||||
|
||||
$result["fields"][$fieldName] = $this->createField($orderdetail->getSupplierPartNr());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Add fields for KiCost:
|
||||
if ($part->getManufacturer() !== null) {
|
||||
$result["fields"]["manf"] = $this->createField($part->getManufacturer()->getName());
|
||||
}
|
||||
if ($part->getManufacturerProductNumber() !== "") {
|
||||
$result['fields']['manf#'] = $this->createField($part->getManufacturerProductNumber());
|
||||
}
|
||||
|
||||
//For each supplier, add a field with the supplier name and the supplier part number for KiCost
|
||||
if ($part->getOrderdetails(false)->count() > 0) {
|
||||
foreach ($part->getOrderdetails(false) as $orderdetail) {
|
||||
if ($orderdetail->getSupplier() !== null && $orderdetail->getSupplierPartNr() !== '') {
|
||||
$fieldName = mb_strtolower($orderdetail->getSupplier()->getName()) . '#';
|
||||
|
||||
$result["fields"][$fieldName] = $this->createField($orderdetail->getSupplierPartNr());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@ use App\Services\InfoProviderSystem\DTOs\PriceDTO;
|
|||
use App\Services\InfoProviderSystem\DTOs\PurchaseInfoDTO;
|
||||
use App\Services\InfoProviderSystem\DTOs\SearchResultDTO;
|
||||
use App\Services\OAuth\OAuthTokenManager;
|
||||
use App\Settings\InfoProviderSystem\DigikeySettings;
|
||||
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
||||
|
||||
class DigikeyProvider implements InfoProviderInterface
|
||||
|
|
@ -56,16 +55,17 @@ class DigikeyProvider implements InfoProviderInterface
|
|||
];
|
||||
|
||||
public function __construct(HttpClientInterface $httpClient, private readonly OAuthTokenManager $authTokenManager,
|
||||
private readonly DigikeySettings $settings,)
|
||||
private readonly string $currency, private readonly string $clientId,
|
||||
private readonly string $language, private readonly string $country)
|
||||
{
|
||||
//Create the HTTP client with some default options
|
||||
$this->digikeyClient = $httpClient->withOptions([
|
||||
"base_uri" => self::BASE_URI,
|
||||
"headers" => [
|
||||
"X-DIGIKEY-Client-Id" => $this->settings->clientId,
|
||||
"X-DIGIKEY-Locale-Site" => $this->settings->country,
|
||||
"X-DIGIKEY-Locale-Language" => $this->settings->language,
|
||||
"X-DIGIKEY-Locale-Currency" => $this->settings->currency,
|
||||
"X-DIGIKEY-Client-Id" => $clientId,
|
||||
"X-DIGIKEY-Locale-Site" => $this->country,
|
||||
"X-DIGIKEY-Locale-Language" => $this->language,
|
||||
"X-DIGIKEY-Locale-Currency" => $this->currency,
|
||||
"X-DIGIKEY-Customer-Id" => 0,
|
||||
]
|
||||
]);
|
||||
|
|
@ -101,7 +101,7 @@ class DigikeyProvider implements InfoProviderInterface
|
|||
public function isActive(): bool
|
||||
{
|
||||
//The client ID has to be set and a token has to be available (user clicked connect)
|
||||
return $this->settings->clientId !== '' && $this->authTokenManager->hasToken(self::OAUTH_APP_NAME);
|
||||
return $this->clientId !== '' && $this->authTokenManager->hasToken(self::OAUTH_APP_NAME);
|
||||
}
|
||||
|
||||
public function searchByKeyword(string $keyword): array
|
||||
|
|
@ -268,7 +268,7 @@ class DigikeyProvider implements InfoProviderInterface
|
|||
$prices = [];
|
||||
|
||||
foreach ($price_breaks as $price_break) {
|
||||
$prices[] = new PriceDTO(minimum_discount_amount: $price_break['BreakQuantity'], price: (string) $price_break['UnitPrice'], currency_iso_code: $this->settings->currency);
|
||||
$prices[] = new PriceDTO(minimum_discount_amount: $price_break['BreakQuantity'], price: (string) $price_break['UnitPrice'], currency_iso_code: $this->currency);
|
||||
}
|
||||
|
||||
return [
|
||||
|
|
|
|||
|
|
@ -30,7 +30,6 @@ use App\Services\InfoProviderSystem\DTOs\PartDetailDTO;
|
|||
use App\Services\InfoProviderSystem\DTOs\PriceDTO;
|
||||
use App\Services\InfoProviderSystem\DTOs\PurchaseInfoDTO;
|
||||
use App\Services\OAuth\OAuthTokenManager;
|
||||
use App\Settings\InfoProviderSystem\OctopartSettings;
|
||||
use Psr\Cache\CacheItemPoolInterface;
|
||||
use Symfony\Component\HttpClient\HttpOptions;
|
||||
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
||||
|
|
@ -115,8 +114,9 @@ class OctopartProvider implements InfoProviderInterface
|
|||
|
||||
public function __construct(private readonly HttpClientInterface $httpClient,
|
||||
private readonly OAuthTokenManager $authTokenManager, private readonly CacheItemPoolInterface $partInfoCache,
|
||||
private readonly OctopartSettings $settings,
|
||||
)
|
||||
private readonly string $clientId, private readonly string $secret,
|
||||
private readonly string $currency, private readonly string $country,
|
||||
private readonly int $search_limit, private readonly bool $onlyAuthorizedSellers)
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -183,7 +183,7 @@ class OctopartProvider implements InfoProviderInterface
|
|||
{
|
||||
//The client ID has to be set and a token has to be available (user clicked connect)
|
||||
//return /*!empty($this->clientId) && */ $this->authTokenManager->hasToken(self::OAUTH_APP_NAME);
|
||||
return $this->settings->clientId !== '' && $this->settings->secret !== '';
|
||||
return $this->clientId !== '' && $this->secret !== '';
|
||||
}
|
||||
|
||||
private function mapLifeCycleStatus(?string $value): ?ManufacturingStatus
|
||||
|
|
@ -347,10 +347,10 @@ class OctopartProvider implements InfoProviderInterface
|
|||
|
||||
$result = $this->makeGraphQLCall($graphQL, [
|
||||
'keyword' => $keyword,
|
||||
'limit' => $this->settings->searchLimit,
|
||||
'currency' => $this->settings->currency,
|
||||
'country' => $this->settings->country,
|
||||
'authorizedOnly' => $this->settings->onlyAuthorizedSellers,
|
||||
'limit' => $this->search_limit,
|
||||
'currency' => $this->currency,
|
||||
'country' => $this->country,
|
||||
'authorizedOnly' => $this->onlyAuthorizedSellers,
|
||||
]);
|
||||
|
||||
$tmp = [];
|
||||
|
|
@ -383,9 +383,9 @@ class OctopartProvider implements InfoProviderInterface
|
|||
|
||||
$result = $this->makeGraphQLCall($graphql, [
|
||||
'ids' => [$id],
|
||||
'currency' => $this->settings->currency,
|
||||
'country' => $this->settings->country,
|
||||
'authorizedOnly' => $this->settings->onlyAuthorizedSellers,
|
||||
'currency' => $this->currency,
|
||||
'country' => $this->country,
|
||||
'authorizedOnly' => $this->onlyAuthorizedSellers,
|
||||
]);
|
||||
|
||||
$tmp = $this->partResultToDTO($result['data']['supParts'][0]);
|
||||
|
|
|
|||
|
|
@ -289,13 +289,6 @@ class ToolsTreeBuilder
|
|||
))->setIcon('fa-fw fa-treeview fa-solid fa-database');
|
||||
}
|
||||
|
||||
if ($this->security->isGranted('@config.change_system_settings')) {
|
||||
$nodes[] = (new TreeViewNode(
|
||||
$this->translator->trans('tree.tools.system.settings'),
|
||||
$this->urlGenerator->generate('system_settings')
|
||||
))->setIcon('fa fa-fw fa-gears fa-solid');
|
||||
}
|
||||
|
||||
return $nodes;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -179,7 +179,10 @@ class TreeViewGenerator
|
|||
}
|
||||
|
||||
if (($mode === 'list_parts_root' || $mode === 'devices') && $this->rootNodeEnabled) {
|
||||
$root_node = new TreeViewNode($this->entityClassToRootNodeString($class), $this->entityClassToRootNodeHref($class), $generic);
|
||||
//We show the root node as a link to the list of all parts
|
||||
$show_all_parts_url = $this->router->generate('parts_show_all');
|
||||
|
||||
$root_node = new TreeViewNode($this->entityClassToRootNodeString($class), $show_all_parts_url, $generic);
|
||||
$root_node->setExpanded($this->rootNodeExpandedByDefault);
|
||||
$root_node->setIcon($this->entityClassToRootNodeIcon($class));
|
||||
|
||||
|
|
@ -189,27 +192,6 @@ class TreeViewGenerator
|
|||
return array_merge($head, $generic);
|
||||
}
|
||||
|
||||
protected function entityClassToRootNodeHref(string $class): ?string
|
||||
{
|
||||
//If the root node should redirect to the new entity page, we return the URL for the new entity.
|
||||
if ($this->sidebarSettings->rootNodeRedirectsToNewEntity) {
|
||||
return match ($class) {
|
||||
Category::class => $this->router->generate('category_new'),
|
||||
StorageLocation::class => $this->router->generate('store_location_new'),
|
||||
Footprint::class => $this->router->generate('footprint_new'),
|
||||
Manufacturer::class => $this->router->generate('manufacturer_new'),
|
||||
Supplier::class => $this->router->generate('supplier_new'),
|
||||
Project::class => $this->router->generate('project_new'),
|
||||
default => null,
|
||||
};
|
||||
}
|
||||
|
||||
return match ($class) {
|
||||
Project::class => $this->router->generate('project_new'),
|
||||
default => $this->router->generate('parts_show_all')
|
||||
};
|
||||
}
|
||||
|
||||
protected function entityClassToRootNodeString(string $class): string
|
||||
{
|
||||
return match ($class) {
|
||||
|
|
|
|||
|
|
@ -105,9 +105,6 @@ class PermissionPresetsHelper
|
|||
$this->permissionResolver->setAllOperationsOfPermission($perm_holder, 'suppliers', PermissionData::ALLOW);
|
||||
$this->permissionResolver->setAllOperationsOfPermission($perm_holder, 'projects', PermissionData::ALLOW);
|
||||
|
||||
//Allow to change system settings
|
||||
$this->permissionResolver->setPermission($perm_holder, 'config', 'change_system_settings', PermissionData::ALLOW);
|
||||
|
||||
//Allow to manage Oauth tokens
|
||||
$this->permissionResolver->setPermission($perm_holder, 'system', 'manage_oauth_tokens', PermissionData::ALLOW);
|
||||
//Allow to show updates
|
||||
|
|
|
|||
|
|
@ -37,7 +37,4 @@ class BehaviorSettings
|
|||
|
||||
#[EmbeddedSettings]
|
||||
public ?TableSettings $table = null;
|
||||
|
||||
#[EmbeddedSettings]
|
||||
public ?PartInfoSettings $partInfo = null;
|
||||
}
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
<?php
|
||||
/*
|
||||
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||
*
|
||||
* Copyright (C) 2019 - 2025 Jan Böhmer (https://github.com/jbtronics)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published
|
||||
* by the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
namespace App\Settings\BehaviorSettings;
|
||||
|
||||
use App\Settings\SettingsIcon;
|
||||
use Jbtronics\SettingsBundle\Metadata\EnvVarMode;
|
||||
use Jbtronics\SettingsBundle\Settings\Settings;
|
||||
use Jbtronics\SettingsBundle\Settings\SettingsParameter;
|
||||
use Symfony\Component\Translation\TranslatableMessage as TM;
|
||||
|
||||
#[Settings(name: "part_info", label: new TM("settings.behavior.part_info"))]
|
||||
#[SettingsIcon('fa-circle-info')]
|
||||
class PartInfoSettings
|
||||
{
|
||||
/**
|
||||
* Whether to show the part image overlays in the part info view
|
||||
* @var bool
|
||||
*/
|
||||
#[SettingsParameter(label: new TM("settings.behavior.part_info.show_part_image_overlay"), description: new TM("settings.behavior.part_info.show_part_image_overlay.help"),
|
||||
envVar: "bool:SHOW_PART_IMAGE_OVERLAY", envVarMode: EnvVarMode::OVERWRITE)]
|
||||
public bool $showPartImageOverlay = true;
|
||||
}
|
||||
|
|
@ -67,10 +67,4 @@ class SidebarSettings
|
|||
*/
|
||||
#[SettingsParameter(label: new TM("settings.behavior.sidebar.rootNodeExpanded"))]
|
||||
public bool $rootNodeExpanded = true;
|
||||
|
||||
/**
|
||||
* @var bool Whether the root node should redirect to a new entity creation page when clicked.
|
||||
*/
|
||||
#[SettingsParameter(label: new TM("settings.behavior.sidebar.rootNodeRedirectsToNewEntity"))]
|
||||
public bool $rootNodeRedirectsToNewEntity = false;
|
||||
}
|
||||
|
|
@ -1,70 +0,0 @@
|
|||
<?php
|
||||
/*
|
||||
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||
*
|
||||
* Copyright (C) 2019 - 2025 Jan Böhmer (https://github.com/jbtronics)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published
|
||||
* by the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
namespace App\Settings\InfoProviderSystem;
|
||||
|
||||
use App\Settings\SettingsIcon;
|
||||
use Jbtronics\SettingsBundle\Metadata\EnvVarMode;
|
||||
use Jbtronics\SettingsBundle\Settings\Settings;
|
||||
use Jbtronics\SettingsBundle\Settings\SettingsTrait;
|
||||
use Symfony\Component\Form\Extension\Core\Type\CountryType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\CurrencyType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\LanguageType;
|
||||
use Symfony\Component\Translation\TranslatableMessage as TM;
|
||||
use Jbtronics\SettingsBundle\Settings\SettingsParameter;
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
|
||||
#[Settings(label: new TM("settings.ips.digikey"))]
|
||||
#[SettingsIcon("fa-plug")]
|
||||
class DigikeySettings
|
||||
{
|
||||
use SettingsTrait;
|
||||
|
||||
#[SettingsParameter(
|
||||
label: new TM("settings.ips.digikey.client_id"),
|
||||
envVar: "PROVIDER_DIGIKEY_CLIENT_ID", envVarMode: EnvVarMode::OVERWRITE
|
||||
)]
|
||||
public ?string $clientId = null;
|
||||
|
||||
#[SettingsParameter(
|
||||
label: new TM("settings.ips.digikey.secret"),
|
||||
envVar: "PROVIDER_DIGIKEY_SECRET", envVarMode: EnvVarMode::OVERWRITE
|
||||
)]
|
||||
public ?string $secret = null;
|
||||
|
||||
#[SettingsParameter(label: new TM("settings.ips.tme.currency"), formType: CurrencyType::class,
|
||||
formOptions: ["preferred_choices" => ["EUR", "USD", "CHF", "GBP"]],
|
||||
envVar: "PROVIDER_DIGIKEY_CURRENCY", envVarMode: EnvVarMode::OVERWRITE)]
|
||||
#[Assert\Currency()]
|
||||
public string $currency = "EUR";
|
||||
|
||||
#[SettingsParameter(label: new TM("settings.ips.tme.country"), formType: CountryType::class,
|
||||
envVar: "PROVIDER_DIGIKEY_COUNTRY", envVarMode: EnvVarMode::OVERWRITE)]
|
||||
#[Assert\Country]
|
||||
public string $country = "DE";
|
||||
|
||||
#[SettingsParameter(label: new TM("settings.ips.tme.language"), formType: LanguageType::class,
|
||||
envVar: "PROVIDER_DIGIKEY_LANGUAGE", envVarMode: EnvVarMode::OVERWRITE)]
|
||||
#[Assert\Language]
|
||||
public string $language = "en";
|
||||
}
|
||||
|
|
@ -24,7 +24,6 @@ declare(strict_types=1);
|
|||
namespace App\Settings\InfoProviderSystem;
|
||||
|
||||
use App\Settings\SettingsIcon;
|
||||
use Jbtronics\SettingsBundle\Metadata\EnvVarMode;
|
||||
use Jbtronics\SettingsBundle\Settings\Settings;
|
||||
use Jbtronics\SettingsBundle\Settings\SettingsParameter;
|
||||
use Jbtronics\SettingsBundle\Settings\SettingsTrait;
|
||||
|
|
@ -36,11 +35,9 @@ class Element14Settings
|
|||
{
|
||||
use SettingsTrait;
|
||||
|
||||
#[SettingsParameter(label: new TM("settings.ips.element14.apiKey"), description: new TM("settings.ips.element14.apiKey.help"),
|
||||
formOptions: ["help_html" => true], envVar: "PROVIDER_ELEMENT14_KEY", envVarMode: EnvVarMode::OVERWRITE)]
|
||||
#[SettingsParameter(label: new TM("settings.ips.element14.apiKey"), description: new TM("settings.ips.element14.apiKey.help"), formOptions: ["help_html" => true], envVar: "PROVIDER_ELEMENT14_KEY")]
|
||||
public ?string $apiKey = null;
|
||||
|
||||
#[SettingsParameter(label: new TM("settings.ips.element14.storeId"), description: new TM("settings.ips.element14.storeId.help"),
|
||||
formOptions: ["help_html" => true], envVar: "PROVIDER_ELEMENT14_STORE_ID", envVarMode: EnvVarMode::OVERWRITE)]
|
||||
#[SettingsParameter(label: new TM("settings.ips.element14.storeId"), description: new TM("settings.ips.element14.storeId.help"), formOptions: ["help_html" => true], envVar: "PROVIDER_ELEMENT14_STORE_ID")]
|
||||
public string $storeId = "de.farnell.com";
|
||||
}
|
||||
|
|
@ -32,9 +32,6 @@ class InfoProviderSettings
|
|||
{
|
||||
use SettingsTrait;
|
||||
|
||||
#[EmbeddedSettings]
|
||||
public ?DigikeySettings $digikey = null;
|
||||
|
||||
#[EmbeddedSettings]
|
||||
public ?MouserSettings $mouser = null;
|
||||
|
||||
|
|
@ -44,9 +41,6 @@ class InfoProviderSettings
|
|||
#[EmbeddedSettings]
|
||||
public ?Element14Settings $element14 = null;
|
||||
|
||||
#[EmbeddedSettings]
|
||||
public ?OctopartSettings $octopartSettings = null;
|
||||
|
||||
#[EmbeddedSettings]
|
||||
public ?LCSCSettings $lcsc = null;
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@ declare(strict_types=1);
|
|||
namespace App\Settings\InfoProviderSystem;
|
||||
|
||||
use App\Settings\SettingsIcon;
|
||||
use Jbtronics\SettingsBundle\Metadata\EnvVarMode;
|
||||
use Jbtronics\SettingsBundle\Settings\Settings;
|
||||
use Jbtronics\SettingsBundle\Settings\SettingsParameter;
|
||||
use Jbtronics\SettingsBundle\Settings\SettingsTrait;
|
||||
|
|
@ -38,12 +37,10 @@ class LCSCSettings
|
|||
{
|
||||
use SettingsTrait;
|
||||
|
||||
#[SettingsParameter(label: new TM("settings.ips.lcsc.enabled"),
|
||||
envVar: "bool:PROVIDER_LCSC_ENABLED", envVarMode: EnvVarMode::OVERWRITE)]
|
||||
#[SettingsParameter(label: new TM("settings.ips.lcsc.enabled"), envVar: "bool:PROVIDER_LCSC_ENABLED")]
|
||||
public bool $enabled = false;
|
||||
|
||||
#[SettingsParameter(label: new TM("settings.ips.lcsc.currency"), formType: CurrencyType::class,
|
||||
envVar: "string:PROVIDER_LCSC_CURRENCY", envVarMode: EnvVarMode::OVERWRITE)]
|
||||
#[SettingsParameter(label: new TM("settings.ips.lcsc.currency"), formType: CurrencyType::class, envVar: "string:PROVIDER_LCSC_CURRENCY")]
|
||||
#[Assert\Currency()]
|
||||
public string $currency = 'EUR';
|
||||
}
|
||||
|
|
@ -24,7 +24,6 @@ declare(strict_types=1);
|
|||
namespace App\Settings\InfoProviderSystem;
|
||||
|
||||
use App\Settings\SettingsIcon;
|
||||
use Jbtronics\SettingsBundle\Metadata\EnvVarMode;
|
||||
use Jbtronics\SettingsBundle\Settings\Settings;
|
||||
use Jbtronics\SettingsBundle\Settings\SettingsParameter;
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
|
|
@ -34,25 +33,22 @@ use Symfony\Component\Translation\TranslatableMessage as TM;
|
|||
#[SettingsIcon("fa-plug")]
|
||||
class MouserSettings
|
||||
{
|
||||
#[SettingsParameter(label: new TM("settings.ips.mouser.apiKey"), description: new TM("settings.ips.mouser.apiKey.help"),
|
||||
formOptions: ["help_html" => true], envVar: "PROVIDER_MOUSER_KEY", envVarMode: EnvVarMode::OVERWRITE)]
|
||||
#[SettingsParameter(label: new TM("settings.ips.mouser.apiKey"), description: new TM("settings.ips.mouser.apiKey.help"), formOptions: ["help_html" => true], envVar: "PROVIDER_MOUSER_KEY")]
|
||||
public ?string $apiKey = null;
|
||||
|
||||
/** @var int The number of results to get from Mouser while searching (please note that this value is max 50) */
|
||||
#[SettingsParameter(label: new TM("settings.ips.mouser.searchLimit"), description: new TM("settings.ips.mouser.searchLimit.help"),
|
||||
envVar: "int:PROVIDER_MOUSER_SEARCH_LIMIT", envVarMode: EnvVarMode::OVERWRITE)]
|
||||
#[SettingsParameter(label: new TM("settings.ips.mouser.searchLimit"), description: new TM("settings.ips.mouser.searchLimit.help"), envVar: "int:PROVIDER_MOUSER_SEARCH_LIMIT")]
|
||||
#[Assert\Range(min: 1, max: 50)]
|
||||
public int $searchLimit = 50;
|
||||
|
||||
/** @var MouserSearchOptions Filter search results by RoHS compliance and stock availability */
|
||||
#[SettingsParameter(label: new TM("settings.ips.mouser.searchOptions"), description: new TM("settings.ips.mouser.searchOptions.help"),
|
||||
envVar: "PROVIDER_MOUSER_SEARCH_OPTION", envVarMode: EnvVarMode::OVERWRITE, envVarMapper: [self::class, "mapSearchOptionEnvVar"])]
|
||||
#[SettingsParameter(label: new TM("settings.ips.mouser.searchOptions"), description: new TM("settings.ips.mouser.searchOptions.help"), envVar: "PROVIDER_MOUSER_SEARCH_OPTION", envVarMapper: [self::class, "mapSearchOptionEnvVar"])]
|
||||
public MouserSearchOptions $searchOption = MouserSearchOptions::NONE;
|
||||
|
||||
/** @var bool It is recommended to leave this set to 'true'. The option is not really documented by Mouser:
|
||||
* Used when searching for keywords in the language specified when you signed up for Search API. */
|
||||
//TODO: Put this into some expert mode only
|
||||
//#[SettingsParameter(envVar: "bool:PROVIDER_MOUSER_SEARCH_WITH_SIGNUP_LANGUAGE")]
|
||||
#[SettingsParameter(envVar: "bool:PROVIDER_MOUSER_SEARCH_WITH_SIGNUP_LANGUAGE")]
|
||||
public bool $searchWithSignUpLanguage = true;
|
||||
|
||||
public static function mapSearchOptionEnvVar(?string $value): MouserSearchOptions
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@ declare(strict_types=1);
|
|||
namespace App\Settings\InfoProviderSystem;
|
||||
|
||||
use App\Settings\SettingsIcon;
|
||||
use Jbtronics\SettingsBundle\Metadata\EnvVarMode;
|
||||
use Jbtronics\SettingsBundle\Settings\Settings;
|
||||
use Jbtronics\SettingsBundle\Settings\SettingsParameter;
|
||||
use Jbtronics\SettingsBundle\Settings\SettingsTrait;
|
||||
|
|
@ -42,17 +41,14 @@ class OEMSecretsSettings
|
|||
public const SUPPORTED_CURRENCIES = ["AUD", "CAD", "CHF", "CNY", "DKK", "EUR", "GBP", "HKD", "ILS", "INR", "JPY", "KRW", "NOK",
|
||||
"NZD", "RUB", "SEK", "SGD", "TWD", "USD"];
|
||||
|
||||
#[SettingsParameter(label: new TM("settings.ips.element14.apiKey"),
|
||||
envVar: "PROVIDER_OEMSECRETS_KEY", envVarMode: EnvVarMode::OVERWRITE)]
|
||||
#[SettingsParameter(label: new TM("settings.ips.element14.apiKey"), envVar: "PROVIDER_OEMSECRETS_KEY")]
|
||||
public ?string $apiKey = null;
|
||||
|
||||
#[Assert\Country]
|
||||
#[SettingsParameter(label: new TM("settings.ips.tme.country"), formType: CountryType::class, formOptions: ["preferred_choices" => ["DE", "PL", "GB", "FR", "US"]],
|
||||
envVar: "PROVIDER_OEMSECRETS_COUNTRY_CODE", envVarMode: EnvVarMode::OVERWRITE)]
|
||||
#[SettingsParameter(label: new TM("settings.ips.tme.country"), formType: CountryType::class, formOptions: ["preferred_choices" => ["DE", "PL", "GB", "FR", "US"]], envVar: "PROVIDER_OEMSECRETS_COUNTRY_CODE")]
|
||||
public ?string $country = "DE";
|
||||
|
||||
#[SettingsParameter(label: new TM("settings.ips.tme.currency"), formType: CurrencyType::class, formOptions: ["preferred_choices" => self::SUPPORTED_CURRENCIES],
|
||||
envVar: "PROVIDER_OEMSECRETS_CURRENCY", envVarMode: EnvVarMode::OVERWRITE)]
|
||||
#[SettingsParameter(label: new TM("settings.ips.tme.currency"), formType: CurrencyType::class, formOptions: ["preferred_choices" => self::SUPPORTED_CURRENCIES], envVar: "PROVIDER_OEMSECRETS_CURRENCY")]
|
||||
#[Assert\Choice(choices: self::SUPPORTED_CURRENCIES)]
|
||||
public string $currency = "EUR";
|
||||
|
||||
|
|
@ -60,8 +56,7 @@ class OEMSecretsSettings
|
|||
* @var bool If this is enabled, distributors with zero prices
|
||||
* will be discarded from the creation of a new part
|
||||
*/
|
||||
#[SettingsParameter(label: new TM("settings.ips.oemsecrets.keepZeroPrices"), description: new TM("settings.ips.oemsecrets.keepZeroPrices.help"),
|
||||
envVar: "bool:PROVIDER_OEMSECRETS_ZERO_PRICE", envVarMode: EnvVarMode::OVERWRITE)]
|
||||
#[SettingsParameter(label: new TM("settings.ips.oemsecrets.keepZeroPrices"), description: new TM("settings.ips.oemsecrets.keepZeroPrices.help"), envVar: "bool:PROVIDER_OEMSECRETS_ZERO_PRICE")]
|
||||
public bool $keepZeroPrices = false;
|
||||
|
||||
/**
|
||||
|
|
@ -69,8 +64,7 @@ class OEMSecretsSettings
|
|||
* # from the description transforming unstructured descriptions into structured parameters;
|
||||
* # each parameter in description should have the form: "...;name1:value1;name2:value2"
|
||||
*/
|
||||
#[SettingsParameter(label: new TM("settings.ips.oemsecrets.parseParams"), description: new TM("settings.ips.oemsecrets.parseParams.help"),
|
||||
envVar: "bool:PROVIDER_OEMSECRETS_SET_PARAM", envVarMode: EnvVarMode::OVERWRITE)]
|
||||
#[SettingsParameter(label: new TM("settings.ips.oemsecrets.parseParams"), description: new TM("settings.ips.oemsecrets.parseParams.help"), envVar: "bool:PROVIDER_OEMSECRETS_SET_PARAM")]
|
||||
public bool $parseParams = true;
|
||||
|
||||
#[SettingsParameter(label: new TM("settings.ips.oemsecrets.sortMode"), envVar: "PROVIDER_OEMSECRETS_SORT_CRITERIA", envVarMapper: [self::class, "mapSortModeEnvVar"])]
|
||||
|
|
|
|||
|
|
@ -1,78 +0,0 @@
|
|||
<?php
|
||||
/*
|
||||
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||
*
|
||||
* Copyright (C) 2019 - 2025 Jan Böhmer (https://github.com/jbtronics)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published
|
||||
* by the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
namespace App\Settings\InfoProviderSystem;
|
||||
|
||||
use App\Settings\SettingsIcon;
|
||||
use Jbtronics\SettingsBundle\Metadata\EnvVarMode;
|
||||
use Jbtronics\SettingsBundle\Settings\Settings;
|
||||
use Jbtronics\SettingsBundle\Settings\SettingsParameter;
|
||||
use Jbtronics\SettingsBundle\Settings\SettingsTrait;
|
||||
use Symfony\Component\Form\Extension\Core\Type\CountryType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\CurrencyType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\NumberType;
|
||||
use Symfony\Component\Translation\TranslatableMessage as TM;
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
|
||||
#[Settings(label: new TM("settings.ips.octopart"))]
|
||||
#[SettingsIcon("fa-plug")]
|
||||
class OctopartSettings
|
||||
{
|
||||
use SettingsTrait;
|
||||
|
||||
#[SettingsParameter(
|
||||
label: new TM("settings.ips.digikey.client_id"),
|
||||
envVar: "PROVIDER_OCTOPART_CLIENT_ID", envVarMode: EnvVarMode::OVERWRITE
|
||||
)]
|
||||
public ?string $clientId = null;
|
||||
|
||||
#[SettingsParameter(
|
||||
label: new TM("settings.ips.digikey.secret"),
|
||||
envVar: "PROVIDER_OCTOPART_SECRET", envVarMode: EnvVarMode::OVERWRITE
|
||||
)]
|
||||
public ?string $secret = null;
|
||||
|
||||
#[SettingsParameter(label: new TM("settings.ips.tme.currency"), formType: CurrencyType::class,
|
||||
formOptions: ["preferred_choices" => ["EUR", "USD", "CHF", "GBP"]],
|
||||
envVar: "PROVIDER_OCTOPART_CURRENCY", envVarMode: EnvVarMode::OVERWRITE)]
|
||||
#[Assert\Currency()]
|
||||
public string $currency = "EUR";
|
||||
|
||||
#[SettingsParameter(label: new TM("settings.ips.tme.country"), formType: CountryType::class,
|
||||
envVar: "PROVIDER_OCTOPART_COUNTRY", envVarMode: EnvVarMode::OVERWRITE)]
|
||||
#[Assert\Country]
|
||||
public string $country = "DE";
|
||||
|
||||
#[SettingsParameter(label: new TM("settings.ips.octopart.searchLimit"), description: new TM("settings.ips.octopart.searchLimit.help"),
|
||||
formType: NumberType::class, formOptions: ["attr" => ["min" => 1, "max" => 100]],
|
||||
envVar: "int:PROVIDER_OCTOPART_SEARCH_LIMIT", envVarMode: EnvVarMode::OVERWRITE)]
|
||||
#[Assert\Range(min: 1, max: 100)]
|
||||
public int $searchLimit = 10;
|
||||
|
||||
#[SettingsParameter(label: new TM("settings.ips.octopart.onlyAuthorizedSellers"),
|
||||
description: new TM("settings.ips.octopart.onlyAuthorizedSellers.help"),
|
||||
envVar: "bool:PROVIDER_OCTOPART_ONLY_AUTHORIZED_SELLERS", envVarMode: EnvVarMode::OVERWRITE
|
||||
)]
|
||||
public bool $onlyAuthorizedSellers = true;
|
||||
|
||||
}
|
||||
|
|
@ -24,7 +24,6 @@ declare(strict_types=1);
|
|||
namespace App\Settings\InfoProviderSystem;
|
||||
|
||||
use App\Settings\SettingsIcon;
|
||||
use Jbtronics\SettingsBundle\Metadata\EnvVarMode;
|
||||
use Jbtronics\SettingsBundle\Settings\Settings;
|
||||
use Jbtronics\SettingsBundle\Settings\SettingsParameter;
|
||||
use Symfony\Component\Translation\TranslatableMessage as TM;
|
||||
|
|
@ -33,7 +32,6 @@ use Symfony\Component\Translation\TranslatableMessage as TM;
|
|||
#[SettingsIcon("fa-plug")]
|
||||
class PollinSettings
|
||||
{
|
||||
#[SettingsParameter(label: new TM("settings.ips.lcsc.enabled"),
|
||||
envVar: "bool:PROVIDER_POLLIN_ENABLED", envVarMode: EnvVarMode::OVERWRITE)]
|
||||
#[SettingsParameter(label: new TM("settings.ips.lcsc.enabled"), envVar: "bool:PROVIDER_POLLIN_ENABLED")]
|
||||
public bool $enabled = false;
|
||||
}
|
||||
|
|
@ -24,7 +24,6 @@ declare(strict_types=1);
|
|||
namespace App\Settings\InfoProviderSystem;
|
||||
|
||||
use App\Settings\SettingsIcon;
|
||||
use Jbtronics\SettingsBundle\Metadata\EnvVarMode;
|
||||
use Jbtronics\SettingsBundle\Settings\Settings;
|
||||
use Jbtronics\SettingsBundle\Settings\SettingsParameter;
|
||||
use Jbtronics\SettingsBundle\Settings\SettingsTrait;
|
||||
|
|
@ -42,27 +41,22 @@ class ReicheltSettings
|
|||
|
||||
public const SUPPORTED_LANGUAGE = ["en", "de", "fr", "nl", "pl", "it", "es"];
|
||||
|
||||
#[SettingsParameter(label: new TM("settings.ips.lcsc.enabled"),
|
||||
envVar: "bool:PROVIDER_REICHELT_ENABLED", envVarMode: EnvVarMode::OVERWRITE)]
|
||||
#[SettingsParameter(label: new TM("settings.ips.lcsc.enabled"), envVar: "bool:PROVIDER_REICHELT_ENABLED")]
|
||||
public bool $enabled = false;
|
||||
|
||||
#[SettingsParameter(label: new TM("settings.ips.tme.currency"), formType: CurrencyType::class, formOptions: ["preferred_choices" => ["EUR"]],
|
||||
envVar: "PROVIDER_REICHELT_CURRENCY", envVarMode: EnvVarMode::OVERWRITE)]
|
||||
#[SettingsParameter(label: new TM("settings.ips.tme.currency"), formType: CurrencyType::class, formOptions: ["preferred_choices" => ["EUR"]], envVar: "PROVIDER_REICHELT_CURRENCY")]
|
||||
public string $currency = "EUR";
|
||||
|
||||
#[SettingsParameter(label: new TM("settings.ips.tme.language"), formType: LanguageType::class, formOptions: ["preferred_choices" => self::SUPPORTED_LANGUAGE],
|
||||
envVar: "PROVIDER_REICHELT_LANGUAGE", envVarMode: EnvVarMode::OVERWRITE)]
|
||||
#[SettingsParameter(label: new TM("settings.ips.tme.language"), formType: LanguageType::class, formOptions: ["preferred_choices" => self::SUPPORTED_LANGUAGE], envVar: "PROVIDER_REICHELT_LANGUAGE")]
|
||||
#[Assert\Language()]
|
||||
#[Assert\Choice(choices: self::SUPPORTED_LANGUAGE)]
|
||||
public string $language = "en";
|
||||
|
||||
#[SettingsParameter(label: new TM("settings.ips.tme.country"), formType: CountryType::class, formOptions: ["preferred_choices" => ["DE", "PL", "GB", "FR"]],
|
||||
envVar: "PROVIDER_REICHELT_COUNTRY", envVarMode: EnvVarMode::OVERWRITE)]
|
||||
#[SettingsParameter(label: new TM("settings.ips.tme.country"), envVar: "PROVIDER_REICHELT_COUNTRY", formType: CountryType::class, formOptions: ["preferred_choices" => ["DE", "PL", "GB", "FR"]])]
|
||||
#[Assert\Country]
|
||||
public string $country = "DE";
|
||||
|
||||
#[SettingsParameter(label: new TM("settings.ips.reichelt.include_vat"),
|
||||
envVar: "bool:PROVIDER_REICHELT_INCLUDE_VAT", envVarMode: EnvVarMode::OVERWRITE)]
|
||||
#[SettingsParameter(label: new TM("settings.ips.reichelt.include_vat"), envVar: "bool:PROVIDER_REICHELT_INCLUDE_VAT")]
|
||||
public bool $includeVAT = true;
|
||||
|
||||
}
|
||||
|
|
@ -24,7 +24,6 @@ declare(strict_types=1);
|
|||
namespace App\Settings\InfoProviderSystem;
|
||||
|
||||
use App\Settings\SettingsIcon;
|
||||
use Jbtronics\SettingsBundle\Metadata\EnvVarMode;
|
||||
use Jbtronics\SettingsBundle\Settings\Settings;
|
||||
use Jbtronics\SettingsBundle\Settings\SettingsParameter;
|
||||
use Jbtronics\SettingsBundle\Settings\SettingsTrait;
|
||||
|
|
@ -43,30 +42,24 @@ class TMESettings
|
|||
private const SUPPORTED_CURRENCIES = ["EUR", "USD", "PLN", "GBP"];
|
||||
|
||||
#[SettingsParameter(label: new TM("settings.ips.tme.token"),
|
||||
description: new TM("settings.ips.tme.token.help"), formOptions: ["help_html" => true],
|
||||
envVar: "PROVIDER_TME_KEY", envVarMode: EnvVarMode::OVERWRITE)]
|
||||
description: new TM("settings.ips.tme.token.help"), formOptions: ["help_html" => true], envVar: "PROVIDER_TME_KEY")]
|
||||
public ?string $apiToken = null;
|
||||
|
||||
#[SettingsParameter(label: new TM("settings.ips.tme.secret"),
|
||||
envVar: "PROVIDER_TME_SECRET", envVarMode: EnvVarMode::OVERWRITE)]
|
||||
#[SettingsParameter(label: new TM("settings.ips.tme.secret"), envVar: "PROVIDER_TME_SECRET")]
|
||||
public ?string $apiSecret = null;
|
||||
|
||||
#[SettingsParameter(label: new TM("settings.ips.tme.currency"), formType: CurrencyType::class, formOptions: ["preferred_choices" => self::SUPPORTED_CURRENCIES],
|
||||
envVar: "PROVIDER_TME_CURRENCY", envVarMode: EnvVarMode::OVERWRITE)]
|
||||
#[SettingsParameter(label: new TM("settings.ips.tme.currency"), formType: CurrencyType::class, formOptions: ["preferred_choices" => self::SUPPORTED_CURRENCIES], envVar: "PROVIDER_TME_CURRENCY")]
|
||||
#[Assert\Choice(choices: self::SUPPORTED_CURRENCIES)]
|
||||
public string $currency = "EUR";
|
||||
|
||||
#[SettingsParameter(label: new TM("settings.ips.tme.language"), formType: LanguageType::class, formOptions: ["preferred_choices" => ["en", "de", "fr", "pl"]],
|
||||
envVar: "PROVIDER_TME_LANGUAGE", envVarMode: EnvVarMode::OVERWRITE)]
|
||||
#[SettingsParameter(label: new TM("settings.ips.tme.language"), formType: LanguageType::class, formOptions: ["preferred_choices" => ["en", "de", "fr", "pl"]], envVar: "PROVIDER_TME_LANGUAGE")]
|
||||
#[Assert\Language]
|
||||
public string $language = "en";
|
||||
|
||||
#[SettingsParameter(label: new TM("settings.ips.tme.country"), formType: CountryType::class, formOptions: ["preferred_choices" => ["DE", "PL", "GB", "FR"]],
|
||||
envVar: "PROVIDER_TME_COUNTRY", envVarMode: EnvVarMode::OVERWRITE)]
|
||||
#[SettingsParameter(label: new TM("settings.ips.tme.country"), formType: CountryType::class, formOptions: ["preferred_choices" => ["DE", "PL", "GB", "FR"]], envVar: "PROVIDER_TME_COUNTRY")]
|
||||
#[Assert\Country]
|
||||
public string $country = "DE";
|
||||
|
||||
#[SettingsParameter(label: new TM("settings.ips.tme.grossPrices"),
|
||||
envVar: "bool:PROVIDER_TME_GET_GROSS_PRICES", envVarMode: EnvVarMode::OVERWRITE)]
|
||||
#[SettingsParameter(label: new TM("settings.ips.tme.grossPrices"), envVar: "bool:PROVIDER_TME_GET_GROSS_PRICES")]
|
||||
public bool $grossPrices = true;
|
||||
}
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
<?php
|
||||
/*
|
||||
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||
*
|
||||
* Copyright (C) 2019 - 2025 Jan Böhmer (https://github.com/jbtronics)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published
|
||||
* by the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
namespace App\Settings\MiscSettings;
|
||||
|
||||
use App\Settings\SettingsIcon;
|
||||
use Jbtronics\SettingsBundle\Metadata\EnvVarMode;
|
||||
use Jbtronics\SettingsBundle\Settings\Settings;
|
||||
use Jbtronics\SettingsBundle\Settings\SettingsParameter;
|
||||
use Symfony\Component\Translation\TranslatableMessage as TM;
|
||||
|
||||
#[Settings(name: "exchange_rate", label: new TM("settings.misc.exchange_rate"))]
|
||||
#[SettingsIcon("fa-money-bill-transfer")]
|
||||
class ExchangeRateSettings
|
||||
{
|
||||
#[SettingsParameter(label: new TM("settings.misc.exchange_rate.fixer_api_key"),
|
||||
description: new TM("settings.misc.exchange_rate.fixer_api_key.help"),
|
||||
envVar: "FIXER_API_KEY", envVarMode: EnvVarMode::OVERWRITE,
|
||||
)]
|
||||
public ?string $fixerApiKey = null;
|
||||
}
|
||||
|
|
@ -31,7 +31,4 @@ class MiscSettings
|
|||
{
|
||||
#[EmbeddedSettings]
|
||||
public ?KiCadEDASettings $kicadEDA = null;
|
||||
|
||||
#[EmbeddedSettings]
|
||||
public ?ExchangeRateSettings $exchangeRate = null;
|
||||
}
|
||||
|
|
@ -70,7 +70,6 @@ class HistorySettings
|
|||
description: new TM("settings.system.history.enforceComments.description"),
|
||||
options: ['type' => EnumType::class, 'nullable' => false, 'options' => ['class' => EventCommentType::class]],
|
||||
formType: EnforceEventCommentTypesType::class,
|
||||
formOptions: ['required' => false, "empty_data" => []],
|
||||
envVar: "ENFORCE_CHANGE_COMMENTS_FOR", envVarMode: EnvVarMode::OVERWRITE, envVarMapper: [self::class, 'mapEnforceComments']
|
||||
)]
|
||||
public array $enforceComments = [];
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@
|
|||
<div class="carousel-item {% if loop.first %}active{% endif %}">
|
||||
<a href="{{ entity_url(pic, 'file_view') }}" data-turbo="false" target="_blank" rel="noopener">
|
||||
<img class="d-block w-100 img-fluid img-thumbnail bg-light part-info-image" src="{{ entity_url(pic, 'file_view') }}" alt="">
|
||||
{% if settings_instance("part_info").showPartImageOverlay %}
|
||||
<div class="mask"></div>
|
||||
<div class="carousel-caption-hover">
|
||||
<div class="carousel-caption text-white">
|
||||
|
|
@ -22,7 +21,6 @@
|
|||
<div>{{ entity_type_label(pic.element) }}</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</a>
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
|
|
|||
|
|
@ -12922,107 +12922,5 @@ Please note, that you can not impersonate a disabled user. If you try you will g
|
|||
<target>Pollin.de offers no official API, so this info provider webscrapes the website to extract info. It could break at any time, use it at your own risk.</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="TEm7uIg" name="settings.behavior.sidebar.rootNodeRedirectsToNewEntity">
|
||||
<segment>
|
||||
<source>settings.behavior.sidebar.rootNodeRedirectsToNewEntity</source>
|
||||
<target>Root nodes redirect to new entity pages</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="j7HiQ80" name="settings.ips.digikey">
|
||||
<segment>
|
||||
<source>settings.ips.digikey</source>
|
||||
<target>Digikey</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="_ViyVdh" name="settings.ips.digikey.client_id">
|
||||
<segment>
|
||||
<source>settings.ips.digikey.client_id</source>
|
||||
<target>Client ID</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="eB9dDyp" name="settings.ips.digikey.secret">
|
||||
<segment>
|
||||
<source>settings.ips.digikey.secret</source>
|
||||
<target>Secret</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="5xjmMzf" name="settings.ips.octopart">
|
||||
<segment>
|
||||
<source>settings.ips.octopart</source>
|
||||
<target>Octopart / Nexar</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="vGv90iO" name="settings.ips.octopart.searchLimit">
|
||||
<segment>
|
||||
<source>settings.ips.octopart.searchLimit</source>
|
||||
<target>Number of results</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="au4Yeps" name="settings.ips.octopart.searchLimit.help">
|
||||
<segment>
|
||||
<source>settings.ips.octopart.searchLimit.help</source>
|
||||
<target>The number of results to get from Octopart while searching (please note that this counts towards your API limits)</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="Tiqmk.8" name="settings.ips.octopart.onlyAuthorizedSellers">
|
||||
<segment>
|
||||
<source>settings.ips.octopart.onlyAuthorizedSellers</source>
|
||||
<target>Only authorized sellers</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="ECQkeJy" name="settings.ips.octopart.onlyAuthorizedSellers.help">
|
||||
<segment>
|
||||
<source>settings.ips.octopart.onlyAuthorizedSellers.help</source>
|
||||
<target>Set to false to include non-authorized offers in the results</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="iRDDtdU" name="settings.misc.exchange_rate">
|
||||
<segment>
|
||||
<source>settings.misc.exchange_rate</source>
|
||||
<target>Money exchange rates</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="0REngfi" name="settings.misc.exchange_rate.fixer_api_key">
|
||||
<segment>
|
||||
<source>settings.misc.exchange_rate.fixer_api_key</source>
|
||||
<target>Fixer.io API Key</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="COLhoWD" name="settings.misc.exchange_rate.fixer_api_key.help">
|
||||
<segment>
|
||||
<source>settings.misc.exchange_rate.fixer_api_key.help</source>
|
||||
<target>If you need exchange rates between non-euro currencies, you can input an API key from fixer.io here.</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="Ffr5xYM" name="settings.behavior.part_info">
|
||||
<segment>
|
||||
<source>settings.behavior.part_info</source>
|
||||
<target>Part info page</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="weH3j.a" name="settings.behavior.part_info.show_part_image_overlay">
|
||||
<segment>
|
||||
<source>settings.behavior.part_info.show_part_image_overlay</source>
|
||||
<target>Show image overlay</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="SCUs3WS" name="settings.behavior.part_info.show_part_image_overlay.help">
|
||||
<segment>
|
||||
<source>settings.behavior.part_info.show_part_image_overlay.help</source>
|
||||
<target>Show the image overlay with attachment details on hovering over the part image gallery.</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="ALfPkeR" name="perm.config.change_system_settings">
|
||||
<segment>
|
||||
<source>perm.config.change_system_settings</source>
|
||||
<target>Change system settings</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="TlHeIjk" name="tree.tools.system.settings">
|
||||
<segment>
|
||||
<source>tree.tools.system.settings</source>
|
||||
<target>System settings</target>
|
||||
</segment>
|
||||
</unit>
|
||||
</file>
|
||||
</xliff>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue