From e19f83fdc10fe86cde662e33da2c7cab068287a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannes=20R=C3=BCger?= Date: Sun, 22 Feb 2026 21:08:51 +0100 Subject: [PATCH 1/2] feat(parts table): add eda reference prefix and value columns --- src/DataTables/PartsDataTable.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/DataTables/PartsDataTable.php b/src/DataTables/PartsDataTable.php index d2faba766..57238e046 100644 --- a/src/DataTables/PartsDataTable.php +++ b/src/DataTables/PartsDataTable.php @@ -228,6 +228,16 @@ public function configure(DataTable $dataTable, array $options): void ]) ->add('attachments', PartAttachmentsColumn::class, [ 'label' => $this->translator->trans('part.table.attachments'), + ]) + ->add('eda_info_reference_prefix', TextColumn::class, [ + 'label' => $this->translator->trans('eda_info.reference_prefix'), + 'render' => fn($value, Part $context) => htmlspecialchars($context->getEdaInfo()->getReferencePrefix() ?? ''), + 'orderField' => 'NATSORT(part.eda_info.reference_prefix)' + ]) + ->add('eda_info_value', TextColumn::class, [ + 'label' => $this->translator->trans('eda_info.value'), + 'render' => fn($value, Part $context) => htmlspecialchars($context->getEdaInfo()->getValue() ?? ''), + 'orderField' => 'NATSORT(part.eda_info.value)' ]); //Add a column to list the projects where the part is used, when the user has the permission to see the projects From 232c973a1884278e8c26ede0ef209226dff49025 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Sun, 1 Mar 2026 22:23:36 +0100 Subject: [PATCH 2/2] Use better labels for column names and made it visible as default column selection --- config/reference.php | 181 +++++++++--------- src/DataTables/PartsDataTable.php | 12 +- .../BehaviorSettings/PartTableColumns.php | 4 + translations/messages.en.xlf | 12 ++ 4 files changed, 115 insertions(+), 94 deletions(-) diff --git a/config/reference.php b/config/reference.php index 978a82f9f..bfac5a460 100644 --- a/config/reference.php +++ b/config/reference.php @@ -208,29 +208,29 @@ * initial_marking?: list, * events_to_dispatch?: list|null, * places?: list, + * name?: scalar|Param|null, + * metadata?: array, * }>, - * transitions: list, * to?: list, * weight?: int|Param, // Default: 1 - * metadata?: list, + * metadata?: array, * }>, - * metadata?: list, + * metadata?: array, * }>, * }, * router?: bool|array{ // Router configuration * enabled?: bool|Param, // Default: false - * resource: scalar|Param|null, + * resource?: scalar|Param|null, * type?: scalar|Param|null, * cache_dir?: scalar|Param|null, // Deprecated: Setting the "framework.router.cache_dir.cache_dir" configuration option is deprecated. It will be removed in version 8.0. // Default: "%kernel.build_dir%" * default_uri?: scalar|Param|null, // The default URI used to generate URLs in a non-HTTP context. // Default: null @@ -360,10 +360,10 @@ * mapping?: array{ * paths?: list, * }, - * default_context?: list, + * default_context?: array, * named_serializers?: array, + * default_context?: array, * include_built_in_normalizers?: bool|Param, // Whether to include the built-in normalizers // Default: true * include_built_in_encoders?: bool|Param, // Whether to include the built-in encoders // Default: true * }>, @@ -427,7 +427,7 @@ * }, * messenger?: bool|array{ // Messenger configuration * enabled?: bool|Param, // Default: false - * routing?: array, * }>, * serializer?: array{ @@ -440,7 +440,7 @@ * transports?: array, + * options?: array, * failure_transport?: scalar|Param|null, // Transport name to send failed messages to (after all retries have failed). // Default: null * retry_strategy?: string|array{ * service?: scalar|Param|null, // Service id to override the retry strategy entirely. // Default: null @@ -462,7 +462,7 @@ * allow_no_senders?: bool|Param, // Default: true * }, * middleware?: list, * }>, * }>, @@ -634,7 +634,7 @@ * lock_factory?: scalar|Param|null, // The service ID of the lock factory used by this limiter (or null to disable locking). // Default: "auto" * cache_pool?: scalar|Param|null, // The cache pool to use for storing the current limiter state. // Default: "cache.rate_limiter" * storage_service?: scalar|Param|null, // The service ID of a custom storage implementation, this precedes any configured "cache_pool". // Default: null - * policy: "fixed_window"|"token_bucket"|"sliding_window"|"compound"|"no_limit"|Param, // The algorithm to be used by this limiter. + * policy?: "fixed_window"|"token_bucket"|"sliding_window"|"compound"|"no_limit"|Param, // The algorithm to be used by this limiter. * limiters?: list, * limit?: int|Param, // The maximum allowed hits in a fixed interval or burst. * interval?: scalar|Param|null, // Configures the fixed interval if "policy" is set to "fixed_window" or "sliding_window". The value must be a number followed by "second", "minute", "hour", "day", "week" or "month" (or their plural equivalent). @@ -679,7 +679,7 @@ * enabled?: bool|Param, // Default: false * message_bus?: scalar|Param|null, // The message bus to use. // Default: "messenger.default_bus" * routing?: array, * }, @@ -694,7 +694,7 @@ * dbal?: array{ * default_connection?: scalar|Param|null, * types?: array, * driver_schemes?: array, @@ -910,7 +910,7 @@ * datetime_functions?: array, * }, * filters?: array, * }>, @@ -975,7 +975,7 @@ * providers?: list, * }, * entity?: array{ - * class: scalar|Param|null, // The full entity class name of your user class. + * class?: scalar|Param|null, // The full entity class name of your user class. * property?: scalar|Param|null, // Default: null * manager_name?: scalar|Param|null, // Default: null * }, @@ -986,8 +986,8 @@ * }>, * }, * ldap?: array{ - * service: scalar|Param|null, - * base_dn: scalar|Param|null, + * service?: scalar|Param|null, + * base_dn?: scalar|Param|null, * search_dn?: scalar|Param|null, // Default: null * search_password?: scalar|Param|null, // Default: null * extra_fields?: list, @@ -998,11 +998,11 @@ * password_attribute?: scalar|Param|null, // Default: null * }, * saml?: array{ - * user_class: scalar|Param|null, + * user_class?: scalar|Param|null, * default_roles?: list, * }, * }>, - * firewalls: array, @@ -1136,9 +1136,9 @@ * failure_path_parameter?: scalar|Param|null, // Default: "_failure_path" * }, * login_link?: array{ - * check_route: scalar|Param|null, // Route that will validate the login link - e.g. "app_login_link_verify". + * check_route?: scalar|Param|null, // Route that will validate the login link - e.g. "app_login_link_verify". * check_post_only?: scalar|Param|null, // If true, only HTTP POST requests to "check_route" will be handled by the authenticator. // Default: false - * signature_properties: list, + * signature_properties?: list, * lifetime?: int|Param, // The lifetime of the login link in seconds. // Default: 600 * max_uses?: int|Param, // Max number of times a login link can be used - null means unlimited within lifetime. // Default: null * used_link_cache?: scalar|Param|null, // Cache service id used to expired links of max_uses is set. @@ -1240,13 +1240,13 @@ * failure_handler?: scalar|Param|null, * realm?: scalar|Param|null, // Default: null * token_extractors?: list, - * token_handler: string|array{ + * token_handler?: string|array{ * id?: scalar|Param|null, * oidc_user_info?: string|array{ - * base_uri: scalar|Param|null, // Base URI of the userinfo endpoint on the OIDC server, or the OIDC server URI to use the discovery (require "discovery" to be configured). + * base_uri?: scalar|Param|null, // Base URI of the userinfo endpoint on the OIDC server, or the OIDC server URI to use the discovery (require "discovery" to be configured). * discovery?: array{ // Enable the OIDC discovery. * cache?: array{ - * id: scalar|Param|null, // Cache service id to use to cache the OIDC discovery configuration. + * id?: scalar|Param|null, // Cache service id to use to cache the OIDC discovery configuration. * }, * }, * claim?: scalar|Param|null, // Claim which contains the user identifier (e.g. sub, email, etc.). // Default: "sub" @@ -1254,27 +1254,27 @@ * }, * oidc?: array{ * discovery?: array{ // Enable the OIDC discovery. - * base_uri: list, + * base_uri?: list, * cache?: array{ - * id: scalar|Param|null, // Cache service id to use to cache the OIDC discovery configuration. + * id?: scalar|Param|null, // Cache service id to use to cache the OIDC discovery configuration. * }, * }, * claim?: scalar|Param|null, // Claim which contains the user identifier (e.g.: sub, email..). // Default: "sub" - * audience: scalar|Param|null, // Audience set in the token, for validation purpose. - * issuers: list, + * audience?: scalar|Param|null, // Audience set in the token, for validation purpose. + * issuers?: list, * algorithm?: array, - * algorithms: list, + * algorithms?: list, * key?: scalar|Param|null, // Deprecated: The "key" option is deprecated and will be removed in 8.0. Use the "keyset" option instead. // JSON-encoded JWK used to sign the token (must contain a "kty" key). * keyset?: scalar|Param|null, // JSON-encoded JWKSet used to sign the token (must contain a list of valid public keys). * encryption?: bool|array{ * enabled?: bool|Param, // Default: false * enforce?: bool|Param, // When enabled, the token shall be encrypted. // Default: false - * algorithms: list, - * keyset: scalar|Param|null, // JSON-encoded JWKSet used to decrypt the token (must contain a list of valid private keys). + * algorithms?: list, + * keyset?: scalar|Param|null, // JSON-encoded JWKSet used to decrypt the token (must contain a list of valid private keys). * }, * }, * cas?: array{ - * validation_url: scalar|Param|null, // CAS server validation URL + * validation_url?: scalar|Param|null, // CAS server validation URL * prefix?: scalar|Param|null, // CAS prefix // Default: "cas" * http_client?: scalar|Param|null, // HTTP Client service // Default: null * }, @@ -1379,7 +1379,7 @@ * use_microseconds?: scalar|Param|null, // Default: true * channels?: list, * handlers?: array, * mailer?: scalar|Param|null, // Default: null * email_prototype?: string|array{ - * id: scalar|Param|null, + * id?: scalar|Param|null, * method?: scalar|Param|null, // Default: null * }, * verbosity_levels?: array{ @@ -1531,7 +1531,7 @@ * generate_final_entities?: bool|Param, // Default: false * } * @psalm-type WebpackEncoreConfig = array{ - * output_path: scalar|Param|null, // The path where Encore is building the assets - i.e. Encore.setOutputPath() + * output_path?: scalar|Param|null, // The path where Encore is building the assets - i.e. Encore.setOutputPath() * crossorigin?: false|"anonymous"|"use-credentials"|Param, // crossorigin value when Encore.enableIntegrityHashes() is used, can be false (default), anonymous or use-credentials // Default: false * preload?: bool|Param, // preload all rendered script and link tags automatically via the http2 Link header. // Default: false * cache?: bool|Param, // Enable caching of the entry point file(s) // Default: false @@ -1561,27 +1561,27 @@ * cache_prefix?: scalar|Param|null, // Default: "media/cache" * }, * aws_s3?: array{ - * bucket: scalar|Param|null, + * bucket?: scalar|Param|null, * cache?: scalar|Param|null, // Default: false * use_psr_cache?: bool|Param, // Default: false * acl?: scalar|Param|null, // Default: "public-read" * cache_prefix?: scalar|Param|null, // Default: "" * client_id?: scalar|Param|null, // Default: null - * client_config: list, + * client_config?: list, * get_options?: array, * put_options?: array, * proxies?: array, * }, * flysystem?: array{ - * filesystem_service: scalar|Param|null, + * filesystem_service?: scalar|Param|null, * cache_prefix?: scalar|Param|null, // Default: "" - * root_url: scalar|Param|null, + * root_url?: scalar|Param|null, * visibility?: "public"|"private"|"noPredefinedVisibility"|Param, // Default: "public" * }, * }>, * loaders?: array, * chain?: array{ - * loaders: list, + * loaders?: list, * }, * }>, * driver?: scalar|Param|null, // Default: "gd" @@ -1746,23 +1746,23 @@ * providers?: array{ * apilayer_fixer?: array{ * priority?: int|Param, // Default: 0 - * api_key: scalar|Param|null, + * api_key?: scalar|Param|null, * }, * apilayer_currency_data?: array{ * priority?: int|Param, // Default: 0 - * api_key: scalar|Param|null, + * api_key?: scalar|Param|null, * }, * apilayer_exchange_rates_data?: array{ * priority?: int|Param, // Default: 0 - * api_key: scalar|Param|null, + * api_key?: scalar|Param|null, * }, * abstract_api?: array{ * priority?: int|Param, // Default: 0 - * api_key: scalar|Param|null, + * api_key?: scalar|Param|null, * }, * fixer?: array{ * priority?: int|Param, // Default: 0 - * access_key: scalar|Param|null, + * access_key?: scalar|Param|null, * enterprise?: bool|Param, // Default: false * }, * cryptonator?: array{ @@ -1770,7 +1770,7 @@ * }, * exchange_rates_api?: array{ * priority?: int|Param, // Default: 0 - * access_key: scalar|Param|null, + * access_key?: scalar|Param|null, * enterprise?: bool|Param, // Default: false * }, * webservicex?: array{ @@ -1805,38 +1805,38 @@ * }, * currency_data_feed?: array{ * priority?: int|Param, // Default: 0 - * api_key: scalar|Param|null, + * api_key?: scalar|Param|null, * }, * currency_layer?: array{ * priority?: int|Param, // Default: 0 - * access_key: scalar|Param|null, + * access_key?: scalar|Param|null, * enterprise?: bool|Param, // Default: false * }, * forge?: array{ * priority?: int|Param, // Default: 0 - * api_key: scalar|Param|null, + * api_key?: scalar|Param|null, * }, * open_exchange_rates?: array{ * priority?: int|Param, // Default: 0 - * app_id: scalar|Param|null, + * app_id?: scalar|Param|null, * enterprise?: bool|Param, // Default: false * }, * xignite?: array{ * priority?: int|Param, // Default: 0 - * token: scalar|Param|null, + * token?: scalar|Param|null, * }, * xchangeapi?: array{ * priority?: int|Param, // Default: 0 - * api_key: scalar|Param|null, + * api_key?: scalar|Param|null, * }, * currency_converter?: array{ * priority?: int|Param, // Default: 0 - * access_key: scalar|Param|null, + * access_key?: scalar|Param|null, * enterprise?: bool|Param, // Default: false * }, * array?: array{ * priority?: int|Param, // Default: 0 - * latestRates: mixed, + * latestRates?: mixed, * historicalRates?: mixed, * }, * }, @@ -2098,9 +2098,9 @@ * counter_checker?: scalar|Param|null, // This service will check if the counter is valid. By default it throws an exception (recommended). // Default: "Webauthn\\Counter\\ThrowExceptionIfInvalid" * top_origin_validator?: scalar|Param|null, // For cross origin (e.g. iframe), this service will be in charge of verifying the top origin. // Default: null * creation_profiles?: array, * metadata?: bool|array{ // Enable the support of the Metadata Statements. Please read the documentation for this feature. * enabled?: bool|Param, // Default: false - * mds_repository: scalar|Param|null, // The Metadata Statement repository. - * status_report_repository: scalar|Param|null, // The Status Report repository. + * mds_repository?: scalar|Param|null, // The Metadata Statement repository. + * status_report_repository?: scalar|Param|null, // The Status Report repository. * certificate_chain_checker?: scalar|Param|null, // A Certificate Chain checker. // Default: "Webauthn\\MetadataService\\CertificateChain\\PhpCertificateChainValidator" * }, * controllers?: bool|array{ * enabled?: bool|Param, // Default: false * creation?: array, * request?: array/saml/" * strict?: bool|Param, * debug?: bool|Param, - * idp: array{ - * entityId: scalar|Param|null, - * singleSignOnService: array{ - * url: scalar|Param|null, + * idp?: array{ + * entityId?: scalar|Param|null, + * singleSignOnService?: array{ + * url?: scalar|Param|null, * binding?: scalar|Param|null, * }, * singleLogoutService?: array{ @@ -2245,30 +2245,30 @@ * }, * contactPerson?: array{ * technical?: array{ - * givenName: scalar|Param|null, - * emailAddress: scalar|Param|null, + * givenName?: scalar|Param|null, + * emailAddress?: scalar|Param|null, * }, * support?: array{ - * givenName: scalar|Param|null, - * emailAddress: scalar|Param|null, + * givenName?: scalar|Param|null, + * emailAddress?: scalar|Param|null, * }, * administrative?: array{ - * givenName: scalar|Param|null, - * emailAddress: scalar|Param|null, + * givenName?: scalar|Param|null, + * emailAddress?: scalar|Param|null, * }, * billing?: array{ - * givenName: scalar|Param|null, - * emailAddress: scalar|Param|null, + * givenName?: scalar|Param|null, + * emailAddress?: scalar|Param|null, * }, * other?: array{ - * givenName: scalar|Param|null, - * emailAddress: scalar|Param|null, + * givenName?: scalar|Param|null, + * emailAddress?: scalar|Param|null, * }, * }, * organization?: list, * }>, * use_proxy_vars?: bool|Param, // Default: false @@ -2304,7 +2304,7 @@ * }, * auto_install?: bool|Param, // Default: false * fonts?: list, + * graphql_playground?: bool|array{ // Deprecated: The "graphql_playground" configuration is deprecated and will be ignored. + * enabled?: bool|Param, // Default: false + * }, * max_query_complexity?: int|Param, // Default: 500 * nesting_separator?: scalar|Param|null, // The separator to use to filter nested fields. // Default: "_" * collection?: array{ @@ -2512,7 +2514,7 @@ * }, * termsOfService?: scalar|Param|null, // A URL to the Terms of Service for the API. MUST be in the format of a URL. // Default: null * tags?: list, * license?: array{ @@ -2804,7 +2806,10 @@ final class App */ public static function config(array $config): array { - return AppReference::config($config); + /** @var ConfigType $config */ + $config = AppReference::config($config); + + return $config; } } diff --git a/src/DataTables/PartsDataTable.php b/src/DataTables/PartsDataTable.php index 57238e046..a1230534a 100644 --- a/src/DataTables/PartsDataTable.php +++ b/src/DataTables/PartsDataTable.php @@ -229,14 +229,14 @@ public function configure(DataTable $dataTable, array $options): void ->add('attachments', PartAttachmentsColumn::class, [ 'label' => $this->translator->trans('part.table.attachments'), ]) - ->add('eda_info_reference_prefix', TextColumn::class, [ - 'label' => $this->translator->trans('eda_info.reference_prefix'), - 'render' => fn($value, Part $context) => htmlspecialchars($context->getEdaInfo()->getReferencePrefix() ?? ''), + ->add('eda_reference', TextColumn::class, [ + 'label' => $this->translator->trans('part.table.eda_reference'), + 'render' => static fn($value, Part $context) => htmlspecialchars($context->getEdaInfo()->getReferencePrefix() ?? ''), 'orderField' => 'NATSORT(part.eda_info.reference_prefix)' ]) - ->add('eda_info_value', TextColumn::class, [ - 'label' => $this->translator->trans('eda_info.value'), - 'render' => fn($value, Part $context) => htmlspecialchars($context->getEdaInfo()->getValue() ?? ''), + ->add('eda_value', TextColumn::class, [ + 'label' => $this->translator->trans('part.table.eda_value'), + 'render' => static fn($value, Part $context) => htmlspecialchars($context->getEdaInfo()->getValue() ?? ''), 'orderField' => 'NATSORT(part.eda_info.value)' ]); diff --git a/src/Settings/BehaviorSettings/PartTableColumns.php b/src/Settings/BehaviorSettings/PartTableColumns.php index 2ea66525c..d4f6668f6 100644 --- a/src/Settings/BehaviorSettings/PartTableColumns.php +++ b/src/Settings/BehaviorSettings/PartTableColumns.php @@ -51,6 +51,10 @@ enum PartTableColumns : string implements TranslatableInterface case GTIN = "gtin"; case TAGS = "tags"; case ATTACHMENTS = "attachments"; + + case EDA_REFERENCE = "eda_reference"; + + case EDA_VALUE = "eda_value"; case EDIT = "edit"; public function trans(TranslatorInterface $translator, ?string $locale = null): string diff --git a/translations/messages.en.xlf b/translations/messages.en.xlf index d9418563d..d62532955 100644 --- a/translations/messages.en.xlf +++ b/translations/messages.en.xlf @@ -12509,5 +12509,17 @@ Buerklin-API Authentication server: Last stocktake + + + part.table.eda_reference + EDA Reference + + + + + part.table.eda_value + EDA value + +