mirror of
https://github.com/Part-DB/Part-DB-server.git
synced 2026-01-11 04:39:33 +00:00
Erweiterungstätigkeiten zur IPN-Vorschlagsliste anhand von Präfixen aus den Kategorien
This commit is contained in:
parent
cbfe1d4cc8
commit
7162199e61
32 changed files with 1482 additions and 6 deletions
18
.env
18
.env
|
|
@ -53,6 +53,8 @@ EMAIL_SENDER_EMAIL=noreply@partdb.changeme
|
|||
EMAIL_SENDER_NAME="Part-DB Mailer"
|
||||
# Set this to 1 to allow reset of a password per email
|
||||
ALLOW_EMAIL_PW_RESET=0
|
||||
# Set this to 0 to allow to enter already available IPN. In this case a unique increment is appended to the user input.
|
||||
ENFORCE_UNIQUE_IPN=1
|
||||
|
||||
###################################################################################
|
||||
# Error pages settings
|
||||
|
|
@ -126,6 +128,22 @@ 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=""
|
||||
|
||||
# Enable the part image overlay which shows name and filename of the picture
|
||||
SHOW_PART_IMAGE_OVERLAY=1
|
||||
|
||||
# Define the number of digits used for the incremental numbering of parts in the IPN (Internal Part Number) autocomplete system.
|
||||
AUTOCOMPLETE_PART_DIGITS=4
|
||||
|
||||
APP_ENV=prod
|
||||
APP_SECRET=a03498528f5a5fc089273ec9ae5b2849
|
||||
|
||||
# Set this to zero, if you want to disable the year 2038 bug check on 32-bit systems (it will cause errors with current 32-bit PHP versions)
|
||||
DISABLE_YEAR2038_BUG_CHECK=0
|
||||
|
||||
|
|
|
|||
220
assets/controllers/elements/ipn_suggestion_controller.js
Normal file
220
assets/controllers/elements/ipn_suggestion_controller.js
Normal file
|
|
@ -0,0 +1,220 @@
|
|||
import { Controller } from "@hotwired/stimulus";
|
||||
import "../../css/components/autocomplete_bootstrap_theme.css";
|
||||
|
||||
export default class extends Controller {
|
||||
static targets = ["input"];
|
||||
static values = {
|
||||
partId: Number,
|
||||
partCategoryId: Number,
|
||||
suggestions: Object,
|
||||
commonSectionHeader: String, // Dynamic header for common Prefixes
|
||||
partIncrementHeader: String, // Dynamic header for new possible part increment
|
||||
suggestUrl: String,
|
||||
};
|
||||
|
||||
connect() {
|
||||
this.configureAutocomplete();
|
||||
this.watchCategoryChanges();
|
||||
}
|
||||
|
||||
templates = {
|
||||
commonSectionHeader({ title, html }) {
|
||||
return html`
|
||||
<section class="aa-Source">
|
||||
<div class="aa-SourceHeader">
|
||||
<span class="aa-SourceHeaderTitle">${title}</span>
|
||||
<div class="aa-SourceHeaderLine"></div>
|
||||
</div>
|
||||
</section>
|
||||
`;
|
||||
},
|
||||
partIncrementHeader({ title, html }) {
|
||||
return html`
|
||||
<section class="aa-Source">
|
||||
<div class="aa-SourceHeader">
|
||||
<span class="aa-SourceHeaderTitle">${title}</span>
|
||||
<div class="aa-SourceHeaderLine"></div>
|
||||
</div>
|
||||
</section>
|
||||
`;
|
||||
},
|
||||
list({ html }) {
|
||||
return html`
|
||||
<ul class="aa-List" role="listbox"></ul>
|
||||
`;
|
||||
},
|
||||
item({ suggestion, description, html }) {
|
||||
return html`
|
||||
<li class="aa-Item" role="option" data-suggestion="${suggestion}" aria-selected="false">
|
||||
<div class="aa-ItemWrapper">
|
||||
<div class="aa-ItemContent">
|
||||
<div class="aa-ItemIcon aa-ItemIcon--noBorder">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor">
|
||||
<path d="M12 21c4.971 0 9-4.029 9-9s-4.029-9-9-9-9 4.029-9 9 4.029 9 9 9z"></path>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="aa-ItemContentBody">
|
||||
<div class="aa-ItemContentTitle">${suggestion}</div>
|
||||
<div class="aa-ItemContentDescription">${description}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
`;
|
||||
},
|
||||
};
|
||||
|
||||
configureAutocomplete() {
|
||||
const inputField = this.inputTarget;
|
||||
const commonPrefixes = this.suggestionsValue.commonPrefixes || [];
|
||||
const prefixesPartIncrement = this.suggestionsValue.prefixesPartIncrement || [];
|
||||
const commonHeader = this.commonSectionHeaderValue;
|
||||
const partIncrementHeader = this.partIncrementHeaderValue;
|
||||
|
||||
if (!inputField || (!commonPrefixes.length && !prefixesPartIncrement.length)) return;
|
||||
|
||||
// Check whether the panel should be created at the update
|
||||
if (this.isPanelInitialized) {
|
||||
const existingPanel = inputField.parentNode.querySelector(".aa-Panel");
|
||||
if (existingPanel) {
|
||||
// Only remove the panel in the update phase
|
||||
|
||||
existingPanel.remove();
|
||||
}
|
||||
}
|
||||
|
||||
// Create panel
|
||||
const panel = document.createElement("div");
|
||||
panel.classList.add("aa-Panel");
|
||||
panel.style.display = "none";
|
||||
|
||||
// Create panel layout
|
||||
const panelLayout = document.createElement("div");
|
||||
panelLayout.classList.add("aa-PanelLayout", "aa-Panel--scrollable");
|
||||
|
||||
// Section for common prefixes
|
||||
if (commonPrefixes.length) {
|
||||
const commonSection = document.createElement("section");
|
||||
commonSection.classList.add("aa-Source");
|
||||
|
||||
const commonSectionHeader = this.templates.commonSectionHeader({
|
||||
title: commonHeader,
|
||||
html: String.raw,
|
||||
});
|
||||
commonSection.innerHTML += commonSectionHeader;
|
||||
|
||||
const commonList = document.createElement("ul");
|
||||
commonList.classList.add("aa-List");
|
||||
commonList.setAttribute("role", "listbox");
|
||||
|
||||
commonPrefixes.forEach((prefix) => {
|
||||
const itemHTML = this.templates.item({
|
||||
suggestion: prefix.title,
|
||||
description: prefix.description,
|
||||
html: String.raw,
|
||||
});
|
||||
commonList.innerHTML += itemHTML;
|
||||
});
|
||||
|
||||
commonSection.appendChild(commonList);
|
||||
panelLayout.appendChild(commonSection);
|
||||
}
|
||||
|
||||
// Section for prefixes part increment
|
||||
if (prefixesPartIncrement.length) {
|
||||
const partIncrementSection = document.createElement("section");
|
||||
partIncrementSection.classList.add("aa-Source");
|
||||
|
||||
const partIncrementHeaderHtml = this.templates.partIncrementHeader({
|
||||
title: partIncrementHeader,
|
||||
html: String.raw,
|
||||
});
|
||||
partIncrementSection.innerHTML += partIncrementHeaderHtml;
|
||||
|
||||
const partIncrementList = document.createElement("ul");
|
||||
partIncrementList.classList.add("aa-List");
|
||||
partIncrementList.setAttribute("role", "listbox");
|
||||
|
||||
prefixesPartIncrement.forEach((prefix) => {
|
||||
const itemHTML = this.templates.item({
|
||||
suggestion: prefix.title,
|
||||
description: prefix.description,
|
||||
html: String.raw,
|
||||
});
|
||||
partIncrementList.innerHTML += itemHTML;
|
||||
});
|
||||
|
||||
partIncrementSection.appendChild(partIncrementList);
|
||||
panelLayout.appendChild(partIncrementSection);
|
||||
}
|
||||
|
||||
panel.appendChild(panelLayout);
|
||||
inputField.parentNode.appendChild(panel);
|
||||
|
||||
inputField.addEventListener("focus", () => {
|
||||
panel.style.display = "block";
|
||||
});
|
||||
|
||||
inputField.addEventListener("blur", () => {
|
||||
setTimeout(() => {
|
||||
panel.style.display = "none";
|
||||
}, 100);
|
||||
});
|
||||
|
||||
// Selection of an item
|
||||
panelLayout.addEventListener("mousedown", (event) => {
|
||||
const target = event.target.closest("li");
|
||||
|
||||
if (target) {
|
||||
inputField.value = target.dataset.suggestion;
|
||||
panel.style.display = "none";
|
||||
}
|
||||
});
|
||||
|
||||
this.isPanelInitialized = true;
|
||||
};
|
||||
|
||||
watchCategoryChanges() {
|
||||
const categoryField = document.querySelector('[data-ipn-suggestion="categoryField"]');
|
||||
this.previousCategoryId = Number(this.partCategoryIdValue);
|
||||
|
||||
if (categoryField) {
|
||||
categoryField.addEventListener("change", () => {
|
||||
const categoryId = Number(categoryField.value);
|
||||
|
||||
// Check whether the category has changed compared to the previous ID
|
||||
if (categoryId !== this.previousCategoryId) {
|
||||
this.fetchNewSuggestions(categoryId);
|
||||
this.previousCategoryId = categoryId;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
fetchNewSuggestions(categoryId) {
|
||||
const baseUrl = this.suggestUrlValue;
|
||||
const partId = this.partIdValue;
|
||||
const url = `${baseUrl}?partId=${partId}&categoryId=${categoryId}`;
|
||||
|
||||
fetch(url, {
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Accept": "application/json",
|
||||
},
|
||||
})
|
||||
.then((response) => {
|
||||
if (!response.ok) {
|
||||
throw new Error(`Error when calling up the IPN-suggestions: ${response.status}`);
|
||||
}
|
||||
return response.json();
|
||||
})
|
||||
.then((data) => {
|
||||
this.suggestionsValue = data;
|
||||
this.configureAutocomplete();
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Errors when loading the new IPN-suggestions:", error);
|
||||
});
|
||||
};
|
||||
}
|
||||
|
|
@ -9,6 +9,8 @@ parameters:
|
|||
# This is used as workaround for places where we can not access the settings directly (like the 2FA application names)
|
||||
partdb.title: '%env(string:settings:customization:instanceName)%' # The title shown inside of Part-DB (e.g. in the navbar and on homepage)
|
||||
partdb.locale_menu: ['en', 'de', 'it', 'fr', 'ru', 'ja', 'cs', 'da', 'zh', 'pl'] # The languages that are shown in user drop down menu
|
||||
partdb.enforce_change_comments_for: '%env(csv:ENFORCE_CHANGE_COMMENTS_FOR)%' # The actions for which a change comment is required (e.g. "part_edit", "part_create", etc.). If this is empty, change comments are not required at all.
|
||||
partdb.autocomplete_part_digits: '%env(trim:string:AUTOCOMPLETE_PART_DIGITS)%' # The number of digits used for the incremental numbering of parts in the IPN (Internal Part Number) autocomplete system.
|
||||
|
||||
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
|
||||
|
||||
|
|
@ -35,6 +37,7 @@ parameters:
|
|||
######################################################################################################################
|
||||
partdb.gdpr_compliance: true # If this option is activated, IP addresses are anonymized to be GDPR compliant
|
||||
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.users.enforce_unique_ipn: '%env(bool:ENFORCE_UNIQUE_IPN)%' # Config if users are able, to enter an already available IPN. In this case a unique increment is appended to the user input.
|
||||
|
||||
######################################################################################################################
|
||||
# Mail settings
|
||||
|
|
|
|||
|
|
@ -263,6 +263,30 @@ services:
|
|||
tags:
|
||||
- { name: 'doctrine.fixtures.purger_factory', alias: 'reset_autoincrement_purger' }
|
||||
|
||||
App\Controller\PartController:
|
||||
bind:
|
||||
$autocompletePartDigits: '%partdb.autocomplete_part_digits%'
|
||||
|
||||
App\Controller\TypeaheadController:
|
||||
bind:
|
||||
$autocompletePartDigits: '%partdb.autocomplete_part_digits%'
|
||||
|
||||
App\Repository\PartRepository:
|
||||
arguments:
|
||||
$translator: '@translator'
|
||||
tags: ['doctrine.repository_service']
|
||||
|
||||
App\EventSubscriber\UserSystem\PartUniqueIpnSubscriber:
|
||||
arguments:
|
||||
$enforceUniqueIpn: '%partdb.users.enforce_unique_ipn%'
|
||||
tags:
|
||||
- { name: doctrine.event_subscriber }
|
||||
|
||||
App\Validator\Constraints\UniquePartIpnValidator:
|
||||
arguments:
|
||||
$enforceUniqueIpn: '%partdb.users.enforce_unique_ipn%'
|
||||
tags: [ 'validator.constraint_validator' ]
|
||||
|
||||
# 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
|
||||
|
|
|
|||
|
|
@ -116,6 +116,10 @@ bundled with Part-DB. Set `DATABASE_MYSQL_SSL_VERIFY_CERT` if you want to accept
|
|||
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
|
||||
* `AUTOCOMPLETE_PART_DIGITS`: Defines the fixed number of digits used as the increment at the end of an IPN (Internal Part Number).
|
||||
IPN prefixes, maintained within part categories and their hierarchy, form the foundation for suggesting complete IPNs.
|
||||
These suggestions become accessible during IPN input of a part. The constant specifies the digits used to calculate and assign
|
||||
unique increments for parts within a category hierarchy, ensuring consistency and uniqueness in IPN generation.
|
||||
|
||||
### E-Mail settings (all env only)
|
||||
|
||||
|
|
@ -128,6 +132,8 @@ bundled with Part-DB. Set `DATABASE_MYSQL_SSL_VERIFY_CERT` if you want to accept
|
|||
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 mail provider first before via the MAILER_DSN setting.
|
||||
* `ENFORCE_UNIQUE_IPN`: Set this value to false, if you want to allow users to enter a already available IPN for a part entry.
|
||||
In this case a unique increment is appended to the user input.
|
||||
|
||||
### Table related settings
|
||||
|
||||
|
|
|
|||
23
migrations/Version20250325073036.php
Normal file
23
migrations/Version20250325073036.php
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
final class Version20250325073036 extends AbstractMigration
|
||||
{
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
$this->addSql('ALTER TABLE categories ADD part_ipn_prefix VARCHAR(255) NOT NULL AFTER partname_regex');
|
||||
$this->addSql('DROP INDEX UNIQ_6940A7FE3D721C14 ON parts');
|
||||
}
|
||||
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
$this->addSql('ALTER TABLE `categories` DROP part_ipn_prefix');
|
||||
$this->addSql('CREATE UNIQUE INDEX UNIQ_6940A7FE3D721C14 ON `parts` (ipn)');
|
||||
}
|
||||
}
|
||||
|
|
@ -76,6 +76,7 @@ final class PartController extends AbstractController
|
|||
private readonly EntityManagerInterface $em,
|
||||
private readonly EventCommentHelper $commentHelper,
|
||||
private readonly PartInfoSettings $partInfoSettings,
|
||||
private readonly int $autocompletePartDigits,
|
||||
) {
|
||||
}
|
||||
|
||||
|
|
@ -457,10 +458,13 @@ final class PartController extends AbstractController
|
|||
$template = 'parts/edit/update_from_ip.html.twig';
|
||||
}
|
||||
|
||||
$partRepository = $this->em->getRepository(Part::class);
|
||||
|
||||
return $this->render(
|
||||
$template,
|
||||
[
|
||||
'part' => $new_part,
|
||||
'ipnSuggestions' => $partRepository->autoCompleteIpn($data, $this->autocompletePartDigits),
|
||||
'form' => $form,
|
||||
'merge_old_name' => $merge_infos['tname_before'] ?? null,
|
||||
'merge_other' => $merge_infos['other_part'] ?? null,
|
||||
|
|
@ -470,7 +474,6 @@ final class PartController extends AbstractController
|
|||
);
|
||||
}
|
||||
|
||||
|
||||
#[Route(path: '/{id}/add_withdraw', name: 'part_add_withdraw', methods: ['POST'])]
|
||||
public function withdrawAddHandler(Part $part, Request $request, EntityManagerInterface $em, PartLotWithdrawAddHelper $withdrawAddHelper): Response
|
||||
{
|
||||
|
|
|
|||
|
|
@ -69,7 +69,8 @@ class TypeaheadController extends AbstractController
|
|||
public function __construct(
|
||||
protected AttachmentURLGenerator $urlGenerator,
|
||||
protected Packages $assets,
|
||||
protected TranslatorInterface $translator
|
||||
protected TranslatorInterface $translator,
|
||||
protected int $autocompletePartDigits,
|
||||
) {
|
||||
}
|
||||
|
||||
|
|
@ -271,4 +272,28 @@ class TypeaheadController extends AbstractController
|
|||
|
||||
return new JsonResponse($data, Response::HTTP_OK, [], true);
|
||||
}
|
||||
|
||||
#[Route(path: '/parts/ipn-suggestions', name: 'ipn_suggestions', methods: ['GET'])]
|
||||
public function ipnSuggestions(
|
||||
Request $request,
|
||||
EntityManagerInterface $entityManager
|
||||
): JsonResponse {
|
||||
$partId = $request->query->get('partId');
|
||||
if ($partId === '0' || $partId === 'undefined' || $partId === 'null') {
|
||||
$partId = null;
|
||||
}
|
||||
$categoryId = $request->query->getInt('categoryId');
|
||||
|
||||
/** @var Part $part */
|
||||
$part = $partId !== null ? $entityManager->getRepository(Part::class)->find($partId) : new Part();
|
||||
$category = $entityManager->getRepository(Category::class)->find($categoryId);
|
||||
|
||||
$clonedPart = clone $part;
|
||||
$clonedPart->setCategory($category);
|
||||
|
||||
$partRepository = $entityManager->getRepository(Part::class);
|
||||
$ipnSuggestions = $partRepository->autoCompleteIpn($clonedPart, $this->autocompletePartDigits);
|
||||
|
||||
return new JsonResponse($ipnSuggestions);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -118,6 +118,13 @@ class Category extends AbstractPartsContainingDBElement
|
|||
#[ORM\Column(type: Types::TEXT)]
|
||||
protected string $partname_regex = '';
|
||||
|
||||
/**
|
||||
* @var string The prefix for ipn generation for created parts in this category.
|
||||
*/
|
||||
#[Groups(['full', 'import', 'category:read', 'category:write'])]
|
||||
#[ORM\Column(type: Types::STRING, length: 255, nullable: false)]
|
||||
protected string $part_ipn_prefix = '';
|
||||
|
||||
/**
|
||||
* @var bool Set to true, if the footprints should be disabled for parts this category (not implemented yet).
|
||||
*/
|
||||
|
|
@ -225,6 +232,16 @@ class Category extends AbstractPartsContainingDBElement
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function getPartIpnPrefix(): string
|
||||
{
|
||||
return $this->part_ipn_prefix;
|
||||
}
|
||||
|
||||
public function setPartIpnPrefix(string $part_ipn_prefix): void
|
||||
{
|
||||
$this->part_ipn_prefix = $part_ipn_prefix;
|
||||
}
|
||||
|
||||
public function isDisableFootprints(): bool
|
||||
{
|
||||
return $this->disable_footprints;
|
||||
|
|
|
|||
|
|
@ -62,7 +62,6 @@ use Doctrine\Common\Collections\ArrayCollection;
|
|||
use Doctrine\Common\Collections\Collection;
|
||||
use Doctrine\Common\Collections\Criteria;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
|
||||
use Symfony\Component\Serializer\Annotation\Groups;
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
use Symfony\Component\Validator\Context\ExecutionContextInterface;
|
||||
|
|
@ -76,7 +75,6 @@ use Symfony\Component\Validator\Context\ExecutionContextInterface;
|
|||
* @extends AttachmentContainingDBElement<PartAttachment>
|
||||
* @template-use ParametersTrait<PartParameter>
|
||||
*/
|
||||
#[UniqueEntity(fields: ['ipn'], message: 'part.ipn.must_be_unique')]
|
||||
#[ORM\Entity(repositoryClass: PartRepository::class)]
|
||||
#[ORM\EntityListeners([TreeCacheInvalidationListener::class])]
|
||||
#[ORM\Table('`parts`')]
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ use Doctrine\ORM\Mapping as ORM;
|
|||
use Symfony\Component\Serializer\Annotation\Groups;
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
use Symfony\Component\Validator\Constraints\Length;
|
||||
use App\Validator\Constraints\UniquePartIpnConstraint;
|
||||
|
||||
/**
|
||||
* Advanced properties of a part, not related to a more specific group.
|
||||
|
|
@ -62,8 +63,9 @@ trait AdvancedPropertyTrait
|
|||
*/
|
||||
#[Assert\Length(max: 100)]
|
||||
#[Groups(['extended', 'full', 'import', 'part:read', 'part:write'])]
|
||||
#[ORM\Column(type: Types::STRING, length: 100, unique: true, nullable: true)]
|
||||
#[ORM\Column(type: Types::STRING, length: 100, nullable: true)]
|
||||
#[Length(max: 100)]
|
||||
#[UniquePartIpnConstraint]
|
||||
protected ?string $ipn = null;
|
||||
|
||||
/**
|
||||
|
|
|
|||
73
src/EventSubscriber/UserSystem/PartUniqueIpnSubscriber.php
Normal file
73
src/EventSubscriber/UserSystem/PartUniqueIpnSubscriber.php
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
<?php
|
||||
|
||||
namespace App\EventSubscriber\UserSystem;
|
||||
|
||||
use App\Entity\Parts\Part;
|
||||
use Doctrine\Common\EventSubscriber;
|
||||
use Doctrine\Persistence\Event\LifecycleEventArgs;
|
||||
use Doctrine\ORM\Events;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
|
||||
class PartUniqueIpnSubscriber implements EventSubscriber
|
||||
{
|
||||
public function __construct(
|
||||
private EntityManagerInterface $entityManager,
|
||||
private readonly bool $enforceUniqueIpn = false
|
||||
) {
|
||||
}
|
||||
|
||||
public function getSubscribedEvents(): array
|
||||
{
|
||||
return [
|
||||
Events::prePersist,
|
||||
Events::preUpdate,
|
||||
];
|
||||
}
|
||||
|
||||
public function prePersist(LifecycleEventArgs $args): void
|
||||
{
|
||||
$entity = $args->getObject();
|
||||
|
||||
if ($entity instanceof Part) {
|
||||
$this->ensureUniqueIpn($entity);
|
||||
}
|
||||
}
|
||||
|
||||
public function preUpdate(LifecycleEventArgs $args): void
|
||||
{
|
||||
$entity = $args->getObject();
|
||||
|
||||
if ($entity instanceof Part) {
|
||||
$this->ensureUniqueIpn($entity);
|
||||
}
|
||||
}
|
||||
|
||||
private function ensureUniqueIpn(Part $part): void
|
||||
{
|
||||
if ($part->getIpn() === null || $part->getIpn() === '') {
|
||||
return;
|
||||
}
|
||||
|
||||
$existingPart = $this->entityManager
|
||||
->getRepository(Part::class)
|
||||
->findOneBy(['ipn' => $part->getIpn()]);
|
||||
|
||||
if ($existingPart && $existingPart->getId() !== $part->getId()) {
|
||||
if ($this->enforceUniqueIpn) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Anhang eines Inkrements bis ein einzigartiger Wert gefunden wird
|
||||
$increment = 1;
|
||||
$originalIpn = $part->getIpn();
|
||||
|
||||
while ($this->entityManager
|
||||
->getRepository(Part::class)
|
||||
->findOneBy(['ipn' => $originalIpn . "_$increment"])) {
|
||||
$increment++;
|
||||
}
|
||||
|
||||
$part->setIpn($originalIpn . "_$increment");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -84,6 +84,17 @@ class CategoryAdminForm extends BaseEntityAdminForm
|
|||
'disabled' => !$this->security->isGranted($is_new ? 'create' : 'edit', $entity),
|
||||
]);
|
||||
|
||||
$builder->add('part_ipn_prefix', TextType::class, [
|
||||
'required' => false,
|
||||
'empty_data' => '',
|
||||
'label' => 'category.edit.part_ipn_prefix',
|
||||
'help' => 'category.edit.part_ipn_prefix.help',
|
||||
'attr' => [
|
||||
'placeholder' => 'category.edit.part_ipn_prefix.placeholder',
|
||||
],
|
||||
'disabled' => !$this->security->isGranted($is_new ? 'create' : 'edit', $entity),
|
||||
]);
|
||||
|
||||
$builder->add('default_description', RichTextEditorType::class, [
|
||||
'required' => false,
|
||||
'empty_data' => '',
|
||||
|
|
|
|||
|
|
@ -104,6 +104,9 @@ class PartBaseType extends AbstractType
|
|||
'disable_not_selectable' => true,
|
||||
//Do not require category for new parts, so that the user must select the category by hand and cannot forget it (the requirement is handled by the constraint in the entity)
|
||||
'required' => !$new_part,
|
||||
'attr' => [
|
||||
'data-ipn-suggestion' => 'categoryField',
|
||||
]
|
||||
])
|
||||
->add('footprint', StructuralEntityType::class, [
|
||||
'class' => Footprint::class,
|
||||
|
|
@ -175,6 +178,11 @@ class PartBaseType extends AbstractType
|
|||
'required' => false,
|
||||
'empty_data' => null,
|
||||
'label' => 'part.edit.ipn',
|
||||
'attr' => [
|
||||
'class' => 'ipn-suggestion-field',
|
||||
'data-elements--ipn-suggestion-target' => 'input',
|
||||
'autocomplete' => 'off',
|
||||
]
|
||||
]);
|
||||
|
||||
//Comment section
|
||||
|
|
|
|||
|
|
@ -22,17 +22,31 @@ declare(strict_types=1);
|
|||
|
||||
namespace App\Repository;
|
||||
|
||||
use App\Entity\Parts\Category;
|
||||
use App\Entity\Parts\Part;
|
||||
use App\Entity\Parts\PartLot;
|
||||
use Doctrine\ORM\NonUniqueResultException;
|
||||
use Doctrine\ORM\NoResultException;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
|
||||
/**
|
||||
* @extends NamedDBElementRepository<Part>
|
||||
*/
|
||||
class PartRepository extends NamedDBElementRepository
|
||||
{
|
||||
private TranslatorInterface $translator;
|
||||
|
||||
public function __construct(
|
||||
EntityManagerInterface $em,
|
||||
TranslatorInterface $translator
|
||||
) {
|
||||
parent::__construct($em, $em->getClassMetadata(Part::class));
|
||||
|
||||
$this->translator = $translator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the summed up instock of all parts (only parts without a measurement unit).
|
||||
*
|
||||
|
|
@ -94,4 +108,109 @@ class PartRepository extends NamedDBElementRepository
|
|||
|
||||
return $qb->getQuery()->getResult();
|
||||
}
|
||||
|
||||
public function autoCompleteIpn(Part $part, int $autocompletePartDigits): array
|
||||
{
|
||||
$category = $part->getCategory();
|
||||
$ipnSuggestions = ['commonPrefixes' => [], 'prefixesPartIncrement' => []];
|
||||
|
||||
// Validate the category and ensure it's an instance of Category
|
||||
if ($category instanceof Category) {
|
||||
$currentPath = $category->getPartIpnPrefix();
|
||||
$directIpnPrefixEmpty = $category->getPartIpnPrefix() === '';
|
||||
$currentPath = $currentPath === '' ? 'n.a.' : $currentPath;
|
||||
|
||||
$increment = $this->generateNextPossiblePartIncrement($currentPath, $part, $autocompletePartDigits);
|
||||
|
||||
$ipnSuggestions['commonPrefixes'][] = [
|
||||
'title' => $currentPath . '-',
|
||||
'description' => $directIpnPrefixEmpty ? $this->translator->trans('part.edit.tab.advanced.ipn.prefix_empty.direct_category', ['%name%' => $category->getName()]) : $this->translator->trans('part.edit.tab.advanced.ipn.prefix.direct_category')
|
||||
];
|
||||
|
||||
$ipnSuggestions['prefixesPartIncrement'][] = [
|
||||
'title' => $currentPath . '-' . $increment,
|
||||
'description' => $directIpnPrefixEmpty ? $this->translator->trans('part.edit.tab.advanced.ipn.prefix_empty.direct_category', ['%name%' => $category->getName()]) : $this->translator->trans('part.edit.tab.advanced.ipn.prefix.direct_category.increment')
|
||||
];
|
||||
|
||||
// Process parent categories
|
||||
$parentCategory = $category->getParent();
|
||||
|
||||
while ($parentCategory instanceof Category) {
|
||||
// Prepend the parent category's prefix to the current path
|
||||
$currentPath = $parentCategory->getPartIpnPrefix() . '-' . $currentPath;
|
||||
$currentPath = $parentCategory->getPartIpnPrefix() === '' ? 'n.a.-' . $currentPath : $currentPath;
|
||||
|
||||
$ipnSuggestions['commonPrefixes'][] = [
|
||||
'title' => $currentPath . '-',
|
||||
'description' => $this->translator->trans('part.edit.tab.advanced.ipn.prefix.hierarchical.no_increment')
|
||||
];
|
||||
|
||||
$increment = $this->generateNextPossiblePartIncrement($currentPath, $part, $autocompletePartDigits);
|
||||
|
||||
$ipnSuggestions['prefixesPartIncrement'][] = [
|
||||
'title' => $currentPath . '-' . $increment,
|
||||
'description' => $this->translator->trans('part.edit.tab.advanced.ipn.prefix.hierarchical.increment')
|
||||
];
|
||||
|
||||
// Move to the next parent category
|
||||
$parentCategory = $parentCategory->getParent();
|
||||
}
|
||||
} elseif ($part->getID() === null) {
|
||||
$ipnSuggestions['commonPrefixes'][] = [
|
||||
'title' => 'n.a.',
|
||||
'description' => $this->translator->trans('part.edit.tab.advanced.ipn.prefix.not_saved')
|
||||
];
|
||||
}
|
||||
|
||||
return $ipnSuggestions;
|
||||
}
|
||||
|
||||
public function generateNextPossiblePartIncrement(string $currentPath, Part $currentPart, int $autocompletePartDigits): string
|
||||
{
|
||||
$qb = $this->createQueryBuilder('part');
|
||||
|
||||
$expectedLength = strlen($currentPath) + 1 + $autocompletePartDigits; // Path + '-' + $autocompletePartDigits digits
|
||||
|
||||
// Fetch all parts in the given category, sorted by their ID in ascending order
|
||||
$qb->select('part')
|
||||
->where('part.ipn LIKE :ipnPattern')
|
||||
->andWhere('LENGTH(part.ipn) = :expectedLength')
|
||||
->setParameter('ipnPattern', $currentPath . '%')
|
||||
->setParameter('expectedLength', $expectedLength)
|
||||
->orderBy('part.id', 'ASC');
|
||||
|
||||
$parts = $qb->getQuery()->getResult();
|
||||
|
||||
// Collect all used increments in the category
|
||||
$usedIncrements = [];
|
||||
foreach ($parts as $part) {
|
||||
if ($part->getIpn() === null || $part->getIpn() === '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($part->getId() === $currentPart->getId()) {
|
||||
// Extract and return the current part's increment directly
|
||||
$incrementPart = substr($part->getIpn(), -$autocompletePartDigits);
|
||||
if (is_numeric($incrementPart)) {
|
||||
return str_pad((string) $incrementPart, $autocompletePartDigits, '0', STR_PAD_LEFT);
|
||||
}
|
||||
}
|
||||
|
||||
// Extract last $autocompletePartDigits digits for possible available part increment
|
||||
$incrementPart = substr($part->getIpn(), -$autocompletePartDigits);
|
||||
if (is_numeric($incrementPart)) {
|
||||
$usedIncrements[] = (int) $incrementPart;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Generate the next free $autocompletePartDigits-digit increment
|
||||
$nextIncrement = 1; // Start at the beginning
|
||||
|
||||
while (in_array($nextIncrement, $usedIncrements)) {
|
||||
$nextIncrement++;
|
||||
}
|
||||
|
||||
return str_pad((string) $nextIncrement, $autocompletePartDigits, '0', STR_PAD_LEFT);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
20
src/Validator/Constraints/UniquePartIpnConstraint.php
Normal file
20
src/Validator/Constraints/UniquePartIpnConstraint.php
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
<?php
|
||||
|
||||
namespace App\Validator\Constraints;
|
||||
|
||||
use Symfony\Component\Validator\Constraint;
|
||||
|
||||
/**
|
||||
* @Annotation
|
||||
* @Target({"PROPERTY"})
|
||||
*/
|
||||
#[\Attribute(\Attribute::TARGET_PROPERTY)]
|
||||
class UniquePartIpnConstraint extends Constraint
|
||||
{
|
||||
public string $message = 'part.ipn.must_be_unique';
|
||||
|
||||
public function validatedBy(): string
|
||||
{
|
||||
return UniquePartIpnValidator::class;
|
||||
}
|
||||
}
|
||||
38
src/Validator/Constraints/UniquePartIpnValidator.php
Normal file
38
src/Validator/Constraints/UniquePartIpnValidator.php
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
namespace App\Validator\Constraints;
|
||||
|
||||
use App\Entity\Parts\Part;
|
||||
use Symfony\Component\Validator\Constraint;
|
||||
use Symfony\Component\Validator\ConstraintValidator;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
|
||||
class UniquePartIpnValidator extends ConstraintValidator
|
||||
{
|
||||
private EntityManagerInterface $entityManager;
|
||||
private bool $enforceUniqueIpn;
|
||||
|
||||
public function __construct(EntityManagerInterface $entityManager, bool $enforceUniqueIpn)
|
||||
{
|
||||
$this->entityManager = $entityManager;
|
||||
$this->enforceUniqueIpn = $enforceUniqueIpn;
|
||||
}
|
||||
|
||||
public function validate($value, Constraint $constraint)
|
||||
{
|
||||
if (null === $value || '' === $value) {
|
||||
return;
|
||||
}
|
||||
|
||||
$repository = $this->entityManager->getRepository(Part::class);
|
||||
$existingPart = $repository->findOneBy(['ipn' => $value]);
|
||||
|
||||
if ($existingPart) {
|
||||
if ($this->enforceUniqueIpn) {
|
||||
$this->context->buildViolation($constraint->message)
|
||||
->setParameter('{{ value }}', $value)
|
||||
->addViolation();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -33,6 +33,7 @@
|
|||
<hr>
|
||||
{{ form_row(form.partname_regex) }}
|
||||
{{ form_row(form.partname_hint) }}
|
||||
{{ form_row(form.part_ipn_prefix) }}
|
||||
<hr>
|
||||
{{ form_row(form.default_description) }}
|
||||
{{ form_row(form.default_comment) }}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,14 @@
|
|||
{{ form_row(form.needsReview) }}
|
||||
{{ form_row(form.favorite) }}
|
||||
{{ form_row(form.mass) }}
|
||||
{{ form_row(form.ipn) }}
|
||||
<div {{ stimulus_controller('elements/ipn_suggestion', {
|
||||
partId: part.id,
|
||||
partCategoryId: part.category ? part.category.id : null,
|
||||
suggestions: ipnSuggestions,
|
||||
'commonSectionHeader': 'part.edit.tab.advanced.ipn.commonSectionHeader'|trans,
|
||||
'partIncrementHeader': 'part.edit.tab.advanced.ipn.partIncrementHeader'|trans,
|
||||
'suggestUrl': url('ipn_suggestions')
|
||||
}) }}>
|
||||
{{ form_row(form.ipn) }}
|
||||
</div>
|
||||
{{ form_row(form.partUnit) }}
|
||||
|
|
@ -1842,6 +1842,54 @@ Související prvky budou přesunuty nahoru.</target>
|
|||
<target>Pokročilé</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="a1k7Blf" name="part.edit.tab.advanced.ipn.commonSectionHeader">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.commonSectionHeader</source>
|
||||
<target>Návrhy bez přírůstku části</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="2achA.b" name="part.edit.tab.advanced.ipn.partIncrementHeader">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.partIncrementHeader</source>
|
||||
<target>Návrhy s číselnými přírůstky částí</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="dB1ChKc" name="part.edit.tab.advanced.ipn.prefix_empty.direct_category">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix_empty.direct_category</source>
|
||||
<target>IPN předpona přímé kategorie je prázdná, zadejte ji v kategorii „%name%“</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="ec2DiJd" name="part.edit.tab.advanced.ipn.prefix.direct_category">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix.direct_category</source>
|
||||
<target>IPN prefix přímé kategorie</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="2e.kJb4" name="part.edit.tab.advanced.ipn.prefix.direct_category.increment">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix.direct_category.increment</source>
|
||||
<target>IPN prefix přímé kategorie a specifického přírůstku pro část</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="ba1GCoq" name="part.edit.tab.advanced.ipn.prefix.hierarchical.no_increment">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix.hierarchical.no_increment</source>
|
||||
<target>IPN prefixy s hierarchickým pořadím kategorií rodičovských prefixů</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="d1uVFa3" name="part.edit.tab.advanced.ipn.prefix.hierarchical.increment">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix.hierarchical.increment</source>
|
||||
<target>IPN prefixy s hierarchickým pořadím kategorií rodičovských prefixů a specifickým přírůstkem pro část</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="a4rPagW" name="part.edit.tab.advanced.ipn.prefix.not_saved">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix.not_saved</source>
|
||||
<target>Nejprve vytvořte součást a přiřaďte ji do kategorie: s dostupnými kategoriemi a jejich vlastními IPN prefixy lze automaticky navrhnout IPN označení pro danou součást</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="c3S4jwK" name="part.edit.tab.part_lots">
|
||||
<notes>
|
||||
<note category="file-source" priority="1">Part-DB1\templates\Parts\edit\edit_part_info.html.twig:40</note>
|
||||
|
|
@ -6959,6 +7007,12 @@ Pokud jste to provedli nesprávně nebo pokud počítač již není důvěryhodn
|
|||
<target>Filtr názvů</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="dsG4xTQ" name="category.edit.part_ipn_prefix">
|
||||
<segment state="translated">
|
||||
<source>category.edit.part_ipn_prefix</source>
|
||||
<target>Předpona součásti IPN</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="yY_ld.7" name="category.edit.default_description">
|
||||
<notes>
|
||||
<note priority="1">obsolete</note>
|
||||
|
|
@ -10296,12 +10350,24 @@ Element 3</target>
|
|||
<target>např. "/Kondenzátor \d+ nF/i"</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="OXeGz1A" name="category.edit.part_ipn_prefix.placeholder">
|
||||
<segment state="translated">
|
||||
<source>category.edit.part_ipn_prefix.placeholder</source>
|
||||
<target>např. "B12A"</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="DL.TreI" name="category.edit.partname_regex.help">
|
||||
<segment state="translated">
|
||||
<source>category.edit.partname_regex.help</source>
|
||||
<target>Regulární výraz kompatibilní s PCRE, kterému musí název dílu odpovídat.</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="a1bUsfJ" name="category.edit.part_ipn_prefix.help">
|
||||
<segment state="translated">
|
||||
<source>category.edit.part_ipn_prefix.help</source>
|
||||
<target>Předpona navrhovaná při zadávání IPN části.</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="GzqIwHH" name="entity.select.add_hint">
|
||||
<segment state="translated">
|
||||
<source>entity.select.add_hint</source>
|
||||
|
|
|
|||
|
|
@ -1850,6 +1850,54 @@ Underelementer vil blive flyttet opad.</target>
|
|||
<target>Advanceret</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="a1k7Blf" name="part.edit.tab.advanced.ipn.commonSectionHeader">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.commonSectionHeader</source>
|
||||
<target>Forslag uden del-inkrement</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="2achA.b" name="part.edit.tab.advanced.ipn.partIncrementHeader">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.partIncrementHeader</source>
|
||||
<target>Forslag med numeriske deleforøgelser</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="dB1ChKc" name="part.edit.tab.advanced.ipn.prefix_empty.direct_category">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix_empty.direct_category</source>
|
||||
<target>IPN-præfikset for den direkte kategori er tomt, angiv det i kategorien "%name%"</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="ec2DiJd" name="part.edit.tab.advanced.ipn.prefix.direct_category">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix.direct_category</source>
|
||||
<target>IPN-præfiks for direkte kategori</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="2e.kJb4" name="part.edit.tab.advanced.ipn.prefix.direct_category.increment">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix.direct_category.increment</source>
|
||||
<target>IPN-præfiks for den direkte kategori og en delspecifik inkrement</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="ba1GCoq" name="part.edit.tab.advanced.ipn.prefix.hierarchical.no_increment">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix.hierarchical.no_increment</source>
|
||||
<target>IPN-præfikser med hierarkisk rækkefølge af overordnede præfikser</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="d1uVFa3" name="part.edit.tab.advanced.ipn.prefix.hierarchical.increment">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix.hierarchical.increment</source>
|
||||
<target>IPN-præfikser med hierarkisk rækkefølge af overordnede præfikser og en del-specifik inkrement</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="a4rPagW" name="part.edit.tab.advanced.ipn.prefix.not_saved">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix.not_saved</source>
|
||||
<target>Opret først en komponent, og tildel den en kategori: med eksisterende kategorier og deres egne IPN-præfikser kan IPN-betegnelsen for komponenten foreslås automatisk</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="uc9NwcF" name="part.edit.tab.part_lots">
|
||||
<notes>
|
||||
<note category="file-source" priority="1">Part-DB1\templates\Parts\edit\edit_part_info.html.twig:40</note>
|
||||
|
|
@ -6966,6 +7014,12 @@ Bemærk også, at uden to-faktor-godkendelse er din konto ikke længere så godt
|
|||
<target>Navnefilter</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="dsG4xTQ" name="category.edit.part_ipn_prefix">
|
||||
<segment state="translated">
|
||||
<source>category.edit.part_ipn_prefix</source>
|
||||
<target>IPN-komponentförstavelse</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="UH78POJ" name="category.edit.default_description">
|
||||
<notes>
|
||||
<note priority="1">obsolete</note>
|
||||
|
|
@ -10322,12 +10376,24 @@ Element 3</target>
|
|||
<target>f.eks. "/Kondensator \d+ nF/i"</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="OXeGz1A" name="category.edit.part_ipn_prefix.placeholder">
|
||||
<segment state="translated">
|
||||
<source>category.edit.part_ipn_prefix.placeholder</source>
|
||||
<target>f.eks. "B12A"</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="QFgP__5" name="category.edit.partname_regex.help">
|
||||
<segment state="translated">
|
||||
<source>category.edit.partname_regex.help</source>
|
||||
<target>Et PCRE-kompatibelt regulært udtryk, som delnavnet skal opfylde.</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="a1bUsfJ" name="category.edit.part_ipn_prefix.help">
|
||||
<segment state="translated">
|
||||
<source>category.edit.part_ipn_prefix.help</source>
|
||||
<target>Et prefix foreslået, når IPN for en del indtastes.</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="vr7oZKL" name="entity.select.add_hint">
|
||||
<segment state="translated">
|
||||
<source>entity.select.add_hint</source>
|
||||
|
|
|
|||
|
|
@ -1841,6 +1841,54 @@ Subelemente werden beim Löschen nach oben verschoben.</target>
|
|||
<target>Erweiterte Optionen</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="a1k7Blf" name="part.edit.tab.advanced.ipn.commonSectionHeader">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.commonSectionHeader</source>
|
||||
<target>Vorschläge ohne Teil-Inkrement</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="2achA.b" name="part.edit.tab.advanced.ipn.partIncrementHeader">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.partIncrementHeader</source>
|
||||
<target>Vorschläge mit numerischen Teil-Inkrement</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="dB1ChKc" name="part.edit.tab.advanced.ipn.prefix_empty.direct_category">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix_empty.direct_category</source>
|
||||
<target>IPN-Präfix der direkten Kategorie leer, geben Sie einen Präfix in Kategorie "%name%" an</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="ec2DiJd" name="part.edit.tab.advanced.ipn.prefix.direct_category">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix.direct_category</source>
|
||||
<target>IPN-Präfix der direkten Kategorie</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="2e.kJb4" name="part.edit.tab.advanced.ipn.prefix.direct_category.increment">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix.direct_category.increment</source>
|
||||
<target>IPN-Präfix der direkten Kategorie und eines teilspezifischen Inkrements</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="ba1GCoq" name="part.edit.tab.advanced.ipn.prefix.hierarchical.no_increment">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix.hierarchical.no_increment</source>
|
||||
<target>IPN-Präfixe mit hierarchischer Kategorienreihenfolge der Elternpräfixe</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="d1uVFa3" name="part.edit.tab.advanced.ipn.prefix.hierarchical.increment">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix.hierarchical.increment</source>
|
||||
<target>IPN-Präfixe mit hierarchischer Kategorienreihenfolge der Elternpräfixe und ein teilsspezifisches Inkrement</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="a4rPagW" name="part.edit.tab.advanced.ipn.prefix.not_saved">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix.not_saved</source>
|
||||
<target>Bitte erstellen Sie zuerst ein Bauteil und weisen Sie dieses einer Kategorie zu: mit vorhandenen Kategorien und derene eigenen IPN-Präfix kann die IPN-Angabe für das jeweilige Teil automatisch vorgeschlagen werden</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="c3S4jwK" name="part.edit.tab.part_lots">
|
||||
<notes>
|
||||
<note category="file-source" priority="1">Part-DB1\templates\Parts\edit\edit_part_info.html.twig:40</note>
|
||||
|
|
@ -6976,6 +7024,12 @@ Wenn Sie dies fehlerhafterweise gemacht haben oder ein Computer nicht mehr vertr
|
|||
<target>Namensfilter</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="dsG4xTQ" name="category.edit.part_ipn_prefix">
|
||||
<segment state="translated">
|
||||
<source>category.edit.part_ipn_prefix</source>
|
||||
<target>Bauteil IPN-Präfix</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="yY_ld.7" name="category.edit.default_description">
|
||||
<notes>
|
||||
<note priority="1">obsolete</note>
|
||||
|
|
@ -10388,12 +10442,24 @@ Element 1 -> Element 1.2</target>
|
|||
<target>z.B. "/Kondensator \d+ nF/i"</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="OXeGz1A" name="category.edit.part_ipn_prefix.placeholder">
|
||||
<segment state="translated">
|
||||
<source>category.edit.part_ipn_prefix.placeholder</source>
|
||||
<target>z.B. "B12A"</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="DL.TreI" name="category.edit.partname_regex.help">
|
||||
<segment state="translated">
|
||||
<source>category.edit.partname_regex.help</source>
|
||||
<target>Ein PCRE-kompatibler regulärer Ausdruck, den der Bauteilename erfüllen muss.</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="a1bUsfJ" name="category.edit.part_ipn_prefix.help">
|
||||
<segment state="translated">
|
||||
<source>category.edit.part_ipn_prefix.help</source>
|
||||
<target>Ein Präfix, der bei der IPN-Eingabe eines Bauteils vorgeschlagen wird.</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="GzqIwHH" name="entity.select.add_hint">
|
||||
<segment state="translated">
|
||||
<source>entity.select.add_hint</source>
|
||||
|
|
|
|||
|
|
@ -2476,5 +2476,71 @@
|
|||
<target>%name% (Το συνώνυμό σας: %synonym%)</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="dsG4xTQ" name="category.edit.part_ipn_prefix">
|
||||
<segment state="translated">
|
||||
<source>category.edit.part_ipn_prefix</source>
|
||||
<target>Πρόθεμα εξαρτήματος IPN</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="OXeGz1A" name="category.edit.part_ipn_prefix.placeholder">
|
||||
<segment state="translated">
|
||||
<source>category.edit.part_ipn_prefix.placeholder</source>
|
||||
<target>π.χ. "B12A"</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="a1bUsfJ" name="category.edit.part_ipn_prefix.help">
|
||||
<segment state="translated">
|
||||
<source>category.edit.part_ipn_prefix.help</source>
|
||||
<target>Μια προτεινόμενη πρόθεμα κατά την εισαγωγή του IPN ενός τμήματος.</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="a1k7Blf" name="part.edit.tab.advanced.ipn.commonSectionHeader">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.commonSectionHeader</source>
|
||||
<target>Προτάσεις χωρίς αύξηση μέρους</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="2achA.b" name="part.edit.tab.advanced.ipn.partIncrementHeader">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.partIncrementHeader</source>
|
||||
<target>Προτάσεις με αριθμητικές αυξήσεις μερών</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="dB1ChKc" name="part.edit.tab.advanced.ipn.prefix_empty.direct_category">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix_empty.direct_category</source>
|
||||
<target>Το IPN πρόθεμα της άμεσης κατηγορίας είναι κενό, καθορίστε το στην κατηγορία "%name%"</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="ec2DiJd" name="part.edit.tab.advanced.ipn.prefix.direct_category">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix.direct_category</source>
|
||||
<target>Πρόθεμα IPN για την άμεση κατηγορία</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="2e.kJb4" name="part.edit.tab.advanced.ipn.prefix.direct_category.increment">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix.direct_category.increment</source>
|
||||
<target>Πρόθεμα IPN της άμεσης κατηγορίας και μιας ειδικής για μέρος αύξησης</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="ba1GCoq" name="part.edit.tab.advanced.ipn.prefix.hierarchical.no_increment">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix.hierarchical.no_increment</source>
|
||||
<target>Προθέματα IPN με ιεραρχική σειρά κατηγοριών των προθέτων γονέων</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="d1uVFa3" name="part.edit.tab.advanced.ipn.prefix.hierarchical.increment">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix.hierarchical.increment</source>
|
||||
<target>Προθέματα IPN με ιεραρχική σειρά κατηγοριών των προθέτων γονέων και συγκεκριμένη αύξηση για το μέρος</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="a4rPagW" name="part.edit.tab.advanced.ipn.prefix.not_saved">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix.not_saved</source>
|
||||
<target>Δημιουργήστε πρώτα ένα εξάρτημα και αντιστοιχίστε το σε μια κατηγορία: με τις υπάρχουσες κατηγορίες και τα δικά τους προθέματα IPN, η ονομασία IPN για το εξάρτημα μπορεί να προταθεί αυτόματα</target>
|
||||
</segment>
|
||||
</unit>
|
||||
</file>
|
||||
</xliff>
|
||||
|
|
|
|||
|
|
@ -1842,6 +1842,54 @@ Sub elements will be moved upwards.</target>
|
|||
<target>Advanced</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="a1k7Blf" name="part.edit.tab.advanced.ipn.commonSectionHeader">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.commonSectionHeader</source>
|
||||
<target>Suggestions without part increment</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="2achA.b" name="part.edit.tab.advanced.ipn.partIncrementHeader">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.partIncrementHeader</source>
|
||||
<target>Suggestions with numeric part increment</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="dB1ChKc" name="part.edit.tab.advanced.ipn.prefix_empty.direct_category">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix_empty.direct_category</source>
|
||||
<target>IPN prefix of direct category empty, specify one in category "%name%"</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="ec2DiJd" name="part.edit.tab.advanced.ipn.prefix.direct_category">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix.direct_category</source>
|
||||
<target>IPN prefix of direct category</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="2e.kJb4" name="part.edit.tab.advanced.ipn.prefix.direct_category.increment">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix.direct_category.increment</source>
|
||||
<target>IPN prefix of direct category and part-specific increment</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="ba1GCoq" name="part.edit.tab.advanced.ipn.prefix.hierarchical.no_increment">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix.hierarchical.no_increment</source>
|
||||
<target>IPN prefixes with hierarchical category order of parent-prefix(es)</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="d1uVFa3" name="part.edit.tab.advanced.ipn.prefix.hierarchical.increment">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix.hierarchical.increment</source>
|
||||
<target>IPN prefixes with hierarchical category order of parent-prefix(es) and part-specific increment</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="a4rPagW" name="part.edit.tab.advanced.ipn.prefix.not_saved">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix.not_saved</source>
|
||||
<target>Please create part at first and assign it to a category: with existing categories and their own IPN prefix, the IPN for the part can be suggested automatically</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="c3S4jwK" name="part.edit.tab.part_lots">
|
||||
<notes>
|
||||
<note category="file-source" priority="1">Part-DB1\templates\Parts\edit\edit_part_info.html.twig:40</note>
|
||||
|
|
@ -6977,6 +7025,12 @@ If you have done this incorrectly or if a computer is no longer trusted, you can
|
|||
<target>Name filter</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="dsG4xTQ" name="category.edit.part_ipn_prefix">
|
||||
<segment state="translated">
|
||||
<source>category.edit.part_ipn_prefix</source>
|
||||
<target>Part IPN Prefix</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="yY_ld.7" name="category.edit.default_description">
|
||||
<notes>
|
||||
<note priority="1">obsolete</note>
|
||||
|
|
@ -10389,12 +10443,24 @@ Element 1 -> Element 1.2</target>
|
|||
<target>e.g "/Capacitor \d+ nF/i"</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="OXeGz1A" name="category.edit.part_ipn_prefix.placeholder">
|
||||
<segment state="translated">
|
||||
<source>category.edit.part_ipn_prefix.placeholder</source>
|
||||
<target>e.g "B12A"</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="DL.TreI" name="category.edit.partname_regex.help">
|
||||
<segment state="translated">
|
||||
<source>category.edit.partname_regex.help</source>
|
||||
<target>A PCRE-compatible regular expression, which a part name have to match.</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="a1bUsfJ" name="category.edit.part_ipn_prefix.help">
|
||||
<segment state="translated">
|
||||
<source>category.edit.part_ipn_prefix.help</source>
|
||||
<target>A prefix suggested when entering the IPN of a part.</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="GzqIwHH" name="entity.select.add_hint">
|
||||
<segment state="translated">
|
||||
<source>entity.select.add_hint</source>
|
||||
|
|
|
|||
|
|
@ -1842,6 +1842,54 @@ Subelementos serán desplazados hacia arriba.</target>
|
|||
<target>Avanzado</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="a1k7Blf" name="part.edit.tab.advanced.ipn.commonSectionHeader">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.commonSectionHeader</source>
|
||||
<target>Sugerencias sin incremento de parte</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="2achA.b" name="part.edit.tab.advanced.ipn.partIncrementHeader">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.partIncrementHeader</source>
|
||||
<target>Sugerencias con incrementos numéricos de partes</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="dB1ChKc" name="part.edit.tab.advanced.ipn.prefix_empty.direct_category">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix_empty.direct_category</source>
|
||||
<target>El prefijo IPN de la categoría directa está vacío, especifíquelo en la categoría "%name%"</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="ec2DiJd" name="part.edit.tab.advanced.ipn.prefix.direct_category">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix.direct_category</source>
|
||||
<target>Prefijo IPN de la categoría directa</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="2e.kJb4" name="part.edit.tab.advanced.ipn.prefix.direct_category.increment">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix.direct_category.increment</source>
|
||||
<target>Prefijo IPN de la categoría directa y un incremento específico de la pieza</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="ba1GCoq" name="part.edit.tab.advanced.ipn.prefix.hierarchical.no_increment">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix.hierarchical.no_increment</source>
|
||||
<target>Prefijos IPN con orden jerárquico de categorías de prefijos principales</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="d1uVFa3" name="part.edit.tab.advanced.ipn.prefix.hierarchical.increment">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix.hierarchical.increment</source>
|
||||
<target>Prefijos IPN con orden jerárquico de categorías de prefijos principales y un incremento específico para la parte</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="a4rPagW" name="part.edit.tab.advanced.ipn.prefix.not_saved">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix.not_saved</source>
|
||||
<target>Primero cree un componente y asígnele una categoría: con las categorías existentes y sus propios prefijos IPN, el identificador IPN para el componente puede ser sugerido automáticamente</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="c3S4jwK" name="part.edit.tab.part_lots">
|
||||
<notes>
|
||||
<note category="file-source" priority="1">Part-DB1\templates\Parts\edit\edit_part_info.html.twig:40</note>
|
||||
|
|
@ -6976,6 +7024,12 @@ Subelementos serán desplazados hacia arriba.</target>
|
|||
<target>Filtro de nombre</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="dsG4xTQ" name="category.edit.part_ipn_prefix">
|
||||
<segment state="translated">
|
||||
<source>category.edit.part_ipn_prefix</source>
|
||||
<target>Prefijo de IPN de la pieza</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="yY_ld.7" name="category.edit.default_description">
|
||||
<notes>
|
||||
<note priority="1">obsolete</note>
|
||||
|
|
@ -10332,12 +10386,24 @@ Elemento 3</target>
|
|||
<target>p.ej. "/Condensador \d+ nF/i"</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="OXeGz1A" name="category.edit.part_ipn_prefix.placeholder">
|
||||
<segment state="translated">
|
||||
<source>category.edit.part_ipn_prefix.placeholder</source>
|
||||
<target>p.ej. "B12A"</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="DL.TreI" name="category.edit.partname_regex.help">
|
||||
<segment state="translated">
|
||||
<source>category.edit.partname_regex.help</source>
|
||||
<target>Una expresión regular compatible con PCRE, la cual debe coincidir con el nombre de un componente.</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="a1bUsfJ" name="category.edit.part_ipn_prefix.help">
|
||||
<segment state="translated">
|
||||
<source>category.edit.part_ipn_prefix.help</source>
|
||||
<target>Un prefijo sugerido al ingresar el IPN de una parte.</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="GzqIwHH" name="entity.select.add_hint">
|
||||
<segment state="translated">
|
||||
<source>entity.select.add_hint</source>
|
||||
|
|
|
|||
|
|
@ -1820,6 +1820,54 @@ Show/Hide sidebar</target>
|
|||
<target>Avancé</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="a1k7Blf" name="part.edit.tab.advanced.ipn.commonSectionHeader">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.commonSectionHeader</source>
|
||||
<target>Suggestions sans incrément de partie</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="2achA.b" name="part.edit.tab.advanced.ipn.partIncrementHeader">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.partIncrementHeader</source>
|
||||
<target>Propositions avec incréments numériques de parties</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="dB1ChKc" name="part.edit.tab.advanced.ipn.prefix_empty.direct_category">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix_empty.direct_category</source>
|
||||
<target>Le préfixe IPN de la catégorie directe est vide, veuillez le spécifier dans la catégorie "%name%"</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="ec2DiJd" name="part.edit.tab.advanced.ipn.prefix.direct_category">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix.direct_category</source>
|
||||
<target>Préfixe IPN de la catégorie directe</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="2e.kJb4" name="part.edit.tab.advanced.ipn.prefix.direct_category.increment">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix.direct_category.increment</source>
|
||||
<target>Préfixe IPN de la catégorie directe et d'un incrément spécifique à la partie</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="ba1GCoq" name="part.edit.tab.advanced.ipn.prefix.hierarchical.no_increment">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix.hierarchical.no_increment</source>
|
||||
<target>Préfixes IPN avec un ordre hiérarchique des catégories des préfixes parents</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="d1uVFa3" name="part.edit.tab.advanced.ipn.prefix.hierarchical.increment">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix.hierarchical.increment</source>
|
||||
<target>Préfixes IPN avec un ordre hiérarchique des catégories des préfixes parents et un incrément spécifique à la pièce</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="a4rPagW" name="part.edit.tab.advanced.ipn.prefix.not_saved">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix.not_saved</source>
|
||||
<target>Créez d'abord une pièce et assignez-la à une catégorie : avec les catégories existantes et leurs propres préfixes IPN, l'identifiant IPN pour la pièce peut être proposé automatiquement</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="uc9NwcF" name="part.edit.tab.part_lots">
|
||||
<notes>
|
||||
<note category="file-source" priority="1">Part-DB1\templates\Parts\edit\edit_part_info.html.twig:40</note>
|
||||
|
|
@ -6918,6 +6966,12 @@ Si vous avez fait cela de manière incorrecte ou si un ordinateur n'est plus fia
|
|||
<target>Filtre de nom</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="dsG4xTQ" name="category.edit.part_ipn_prefix">
|
||||
<segment state="translated">
|
||||
<source>category.edit.part_ipn_prefix</source>
|
||||
<target>Préfixe de pièce IPN</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="UH78POJ" name="category.edit.default_description">
|
||||
<notes>
|
||||
<note priority="1">obsolete</note>
|
||||
|
|
@ -10050,5 +10104,17 @@ exemple de ville</target>
|
|||
<target>%name% (Votre synonyme : %synonym%)</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="OXeGz1A" name="category.edit.part_ipn_prefix.placeholder">
|
||||
<segment state="translated">
|
||||
<source>category.edit.part_ipn_prefix.placeholder</source>
|
||||
<target>par ex. "B12A"</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="a1bUsfJ" name="category.edit.part_ipn_prefix.help">
|
||||
<segment state="translated">
|
||||
<source>category.edit.part_ipn_prefix.help</source>
|
||||
<target>Un préfixe suggéré lors de la saisie de l'IPN d'une pièce.</target>
|
||||
</segment>
|
||||
</unit>
|
||||
</file>
|
||||
</xliff>
|
||||
|
|
|
|||
|
|
@ -1842,6 +1842,54 @@ I sub elementi saranno spostati verso l'alto.</target>
|
|||
<target>Avanzate</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="a1k7Blf" name="part.edit.tab.advanced.ipn.commonSectionHeader">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.commonSectionHeader</source>
|
||||
<target>Suggerimenti senza incremento di parte</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="2achA.b" name="part.edit.tab.advanced.ipn.partIncrementHeader">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.partIncrementHeader</source>
|
||||
<target>Suggerimenti con incrementi numerici delle parti</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="dB1ChKc" name="part.edit.tab.advanced.ipn.prefix_empty.direct_category">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix_empty.direct_category</source>
|
||||
<target>Il prefisso IPN della categoria diretta è vuoto, specificarlo nella categoria "%name%"</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="ec2DiJd" name="part.edit.tab.advanced.ipn.prefix.direct_category">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix.direct_category</source>
|
||||
<target>Prefisso IPN della categoria diretta</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="2e.kJb4" name="part.edit.tab.advanced.ipn.prefix.direct_category.increment">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix.direct_category.increment</source>
|
||||
<target>Prefisso IPN della categoria diretta e di un incremento specifico della parte</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="ba1GCoq" name="part.edit.tab.advanced.ipn.prefix.hierarchical.no_increment">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix.hierarchical.no_increment</source>
|
||||
<target>Prefissi IPN con ordine gerarchico delle categorie dei prefissi padre</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="d1uVFa3" name="part.edit.tab.advanced.ipn.prefix.hierarchical.increment">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix.hierarchical.increment</source>
|
||||
<target>Prefissi IPN con ordine gerarchico delle categorie dei prefissi padre e un incremento specifico per il pezzo</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="a4rPagW" name="part.edit.tab.advanced.ipn.prefix.not_saved">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix.not_saved</source>
|
||||
<target>Crea prima un componente e assegnagli una categoria: con le categorie esistenti e i loro propri prefissi IPN, l'identificativo IPN per il componente può essere suggerito automaticamente</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="c3S4jwK" name="part.edit.tab.part_lots">
|
||||
<notes>
|
||||
<note category="file-source" priority="1">Part-DB1\templates\Parts\edit\edit_part_info.html.twig:40</note>
|
||||
|
|
@ -6978,6 +7026,12 @@ Se è stato fatto in modo errato o se un computer non è più attendibile, puoi
|
|||
<target>Filtro nome</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="dsG4xTQ" name="category.edit.part_ipn_prefix">
|
||||
<segment state="translated">
|
||||
<source>category.edit.part_ipn_prefix</source>
|
||||
<target>Prefisso parte IPN</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="yY_ld.7" name="category.edit.default_description">
|
||||
<notes>
|
||||
<note priority="1">obsolete</note>
|
||||
|
|
@ -10334,12 +10388,24 @@ Element 3</target>
|
|||
<target>es. "/Condensatore \d+ nF/i"</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="OXeGz1A" name="category.edit.part_ipn_prefix.placeholder">
|
||||
<segment state="translated">
|
||||
<source>category.edit.part_ipn_prefix.placeholder</source>
|
||||
<target>es. "B12A"</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="DL.TreI" name="category.edit.partname_regex.help">
|
||||
<segment state="translated">
|
||||
<source>category.edit.partname_regex.help</source>
|
||||
<target>Un'espressione regolare compatibile con PCRE che il nome del componente deve soddisfare.</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="a1bUsfJ" name="category.edit.part_ipn_prefix.help">
|
||||
<segment state="translated">
|
||||
<source>category.edit.part_ipn_prefix.help</source>
|
||||
<target>Un prefisso suggerito durante l'inserimento dell'IPN di una parte.</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="GzqIwHH" name="entity.select.add_hint">
|
||||
<segment state="translated">
|
||||
<source>entity.select.add_hint</source>
|
||||
|
|
|
|||
|
|
@ -1820,6 +1820,54 @@
|
|||
<target>詳細</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="a1k7Blf" name="part.edit.tab.advanced.ipn.commonSectionHeader">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.commonSectionHeader</source>
|
||||
<target>部品の増加なしの提案。</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="2achA.b" name="part.edit.tab.advanced.ipn.partIncrementHeader">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.partIncrementHeader</source>
|
||||
<target>パーツの数値インクリメントを含む提案</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="dB1ChKc" name="part.edit.tab.advanced.ipn.prefix_empty.direct_category">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix_empty.direct_category</source>
|
||||
<target>直接カテゴリの IPN プレフィックスが空です。「%name%」カテゴリで指定してください</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="ec2DiJd" name="part.edit.tab.advanced.ipn.prefix.direct_category">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix.direct_category</source>
|
||||
<target>直接カテゴリのIPNプレフィックス</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="2e.kJb4" name="part.edit.tab.advanced.ipn.prefix.direct_category.increment">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix.direct_category.increment</source>
|
||||
<target>直接カテゴリのIPNプレフィックスと部品特有のインクリメント</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="ba1GCoq" name="part.edit.tab.advanced.ipn.prefix.hierarchical.no_increment">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix.hierarchical.no_increment</source>
|
||||
<target>親プレフィックスの階層カテゴリ順のIPNプレフィックス</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="d1uVFa3" name="part.edit.tab.advanced.ipn.prefix.hierarchical.increment">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix.hierarchical.increment</source>
|
||||
<target>親プレフィックスの階層カテゴリ順とパーツ固有の増分のIPNプレフィックス</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="a4rPagW" name="part.edit.tab.advanced.ipn.prefix.not_saved">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix.not_saved</source>
|
||||
<target>まずはコンポーネントを作成し、それをカテゴリに割り当ててください:既存のカテゴリとそれぞれのIPNプレフィックスを基に、コンポーネントのIPNを自動的に提案できます</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="uc9NwcF" name="part.edit.tab.part_lots">
|
||||
<notes>
|
||||
<note category="file-source" priority="1">Part-DB1\templates\Parts\edit\edit_part_info.html.twig:40</note>
|
||||
|
|
@ -6919,6 +6967,12 @@
|
|||
<target>名前のフィルター</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="dsG4xTQ" name="category.edit.part_ipn_prefix">
|
||||
<segment state="translated">
|
||||
<source>category.edit.part_ipn_prefix</source>
|
||||
<target>部品 IPN 接頭辞</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="UH78POJ" name="category.edit.default_description">
|
||||
<notes>
|
||||
<note priority="1">obsolete</note>
|
||||
|
|
@ -9763,5 +9817,17 @@ Exampletown</target>
|
|||
<target>%name% (あなたの同義語: %synonym%)</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="OXeGz1A" name="category.edit.part_ipn_prefix.placeholder">
|
||||
<segment state="translated">
|
||||
<source>category.edit.part_ipn_prefix.placeholder</source>
|
||||
<target>例: "B12A"</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="a1bUsfJ" name="category.edit.part_ipn_prefix.help">
|
||||
<segment state="translated">
|
||||
<source>category.edit.part_ipn_prefix.help</source>
|
||||
<target>部品のIPN入力時に提案される接頭辞。</target>
|
||||
</segment>
|
||||
</unit>
|
||||
</file>
|
||||
</xliff>
|
||||
|
|
|
|||
|
|
@ -1701,5 +1701,71 @@
|
|||
<target>%name% (Uw synoniem: %synonym%)</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="dsG4xTQ" name="category.edit.part_ipn_prefix">
|
||||
<segment state="translated">
|
||||
<source>category.edit.part_ipn_prefix</source>
|
||||
<target>IPN-voorvoegsel van onderdeel</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="OXeGz1A" name="category.edit.part_ipn_prefix.placeholder">
|
||||
<segment state="translated">
|
||||
<source>category.edit.part_ipn_prefix.placeholder</source>
|
||||
<target>bijv. "B12A"</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="a1bUsfJ" name="category.edit.part_ipn_prefix.help">
|
||||
<segment state="translated">
|
||||
<source>category.edit.part_ipn_prefix.help</source>
|
||||
<target>Een voorgesteld voorvoegsel bij het invoeren van de IPN van een onderdeel.</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="a1k7Blf" name="part.edit.tab.advanced.ipn.commonSectionHeader">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.commonSectionHeader</source>
|
||||
<target>Suggesties zonder toename van onderdelen</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="2achA.b" name="part.edit.tab.advanced.ipn.partIncrementHeader">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.partIncrementHeader</source>
|
||||
<target>Suggesties met numerieke verhogingen van onderdelen</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="dB1ChKc" name="part.edit.tab.advanced.ipn.prefix_empty.direct_category">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix_empty.direct_category</source>
|
||||
<target>Het IPN-prefix van de directe categorie is leeg, geef het op in de categorie "%name%"</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="ec2DiJd" name="part.edit.tab.advanced.ipn.prefix.direct_category">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix.direct_category</source>
|
||||
<target>IPN-prefix van de directe categorie</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="2e.kJb4" name="part.edit.tab.advanced.ipn.prefix.direct_category.increment">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix.direct_category.increment</source>
|
||||
<target>IPN-voorvoegsel van de directe categorie en een onderdeel specifiek increment</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="ba1GCoq" name="part.edit.tab.advanced.ipn.prefix.hierarchical.no_increment">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix.hierarchical.no_increment</source>
|
||||
<target>IPN-prefixen met een hiërarchische volgorde van hoofdcategorieën</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="d1uVFa3" name="part.edit.tab.advanced.ipn.prefix.hierarchical.increment">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix.hierarchical.increment</source>
|
||||
<target>IPN-prefixen met een hiërarchische volgorde van hoofdcategorieën en een specifieke toename voor het onderdeel</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="a4rPagW" name="part.edit.tab.advanced.ipn.prefix.not_saved">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix.not_saved</source>
|
||||
<target>Maak eerst een component en wijs het toe aan een categorie: met de bestaande categorieën en hun eigen IPN-prefixen kan de IPN voor het component automatisch worden voorgesteld</target>
|
||||
</segment>
|
||||
</unit>
|
||||
</file>
|
||||
</xliff>
|
||||
|
|
|
|||
|
|
@ -1847,6 +1847,54 @@ Po usunięciu pod elementy zostaną przeniesione na górę.</target>
|
|||
<target>Zaawansowane</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="a1k7Blf" name="part.edit.tab.advanced.ipn.commonSectionHeader">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.commonSectionHeader</source>
|
||||
<target>Sugestie bez zwiększenia części</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="2achA.b" name="part.edit.tab.advanced.ipn.partIncrementHeader">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.partIncrementHeader</source>
|
||||
<target>Propozycje z numerycznymi przyrostami części</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="dB1ChKc" name="part.edit.tab.advanced.ipn.prefix_empty.direct_category">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix_empty.direct_category</source>
|
||||
<target>Prefiks IPN kategorii bezpośredniej jest pusty, podaj go w kategorii "%name%".</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="ec2DiJd" name="part.edit.tab.advanced.ipn.prefix.direct_category">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix.direct_category</source>
|
||||
<target>Prefiks IPN kategorii bezpośredniej</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="2e.kJb4" name="part.edit.tab.advanced.ipn.prefix.direct_category.increment">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix.direct_category.increment</source>
|
||||
<target>Prefiks IPN bezpośredniej kategorii i specyficzny dla części przyrost</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="ba1GCoq" name="part.edit.tab.advanced.ipn.prefix.hierarchical.no_increment">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix.hierarchical.no_increment</source>
|
||||
<target>Prefiksy IPN z hierarchiczną kolejnością kategorii prefiksów nadrzędnych</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="d1uVFa3" name="part.edit.tab.advanced.ipn.prefix.hierarchical.increment">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix.hierarchical.increment</source>
|
||||
<target>Prefiksy IPN z hierarchiczną kolejnością kategorii prefiksów nadrzędnych i specyficznym przyrostem dla części</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="a4rPagW" name="part.edit.tab.advanced.ipn.prefix.not_saved">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix.not_saved</source>
|
||||
<target>Najpierw utwórz komponent i przypisz go do kategorii: dzięki istniejącym kategoriom i ich własnym prefiksom IPN identyfikator IPN dla komponentu może być proponowany automatycznie</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="c3S4jwK" name="part.edit.tab.part_lots">
|
||||
<notes>
|
||||
<note category="file-source" priority="1">Part-DB1\templates\Parts\edit\edit_part_info.html.twig:40</note>
|
||||
|
|
@ -6981,6 +7029,12 @@ Jeśli zrobiłeś to niepoprawnie lub komputer nie jest już godny zaufania, mo
|
|||
<target>Filtr nazwy</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="dsG4xTQ" name="category.edit.part_ipn_prefix">
|
||||
<segment state="translated">
|
||||
<source>category.edit.part_ipn_prefix</source>
|
||||
<target>Prefiks IPN części</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="yY_ld.7" name="category.edit.default_description">
|
||||
<notes>
|
||||
<note priority="1">obsolete</note>
|
||||
|
|
@ -10337,12 +10391,24 @@ Element 3</target>
|
|||
<target>np. "/Kondensator \d+ nF/i"</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="OXeGz1A" name="category.edit.part_ipn_prefix.placeholder">
|
||||
<segment state="translated">
|
||||
<source>category.edit.part_ipn_prefix.placeholder</source>
|
||||
<target>np. "B12A"</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="DL.TreI" name="category.edit.partname_regex.help">
|
||||
<segment state="translated">
|
||||
<source>category.edit.partname_regex.help</source>
|
||||
<target>Wyrażenie regularne zgodne z PCRE, do którego musi pasować nazwa komponentu.</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="a1bUsfJ" name="category.edit.part_ipn_prefix.help">
|
||||
<segment state="translated">
|
||||
<source>category.edit.part_ipn_prefix.help</source>
|
||||
<target>Een voorgesteld voorvoegsel bij het invoeren van de IPN van een onderdeel.</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="GzqIwHH" name="entity.select.add_hint">
|
||||
<segment state="translated">
|
||||
<source>entity.select.add_hint</source>
|
||||
|
|
|
|||
|
|
@ -1850,6 +1850,54 @@
|
|||
<target>Расширенные</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="a1k7Blf" name="part.edit.tab.advanced.ipn.commonSectionHeader">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.commonSectionHeader</source>
|
||||
<target>Предложения без увеличения частей.</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="2achA.b" name="part.edit.tab.advanced.ipn.partIncrementHeader">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.partIncrementHeader</source>
|
||||
<target>Предложения с числовыми приращениями частей</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="dB1ChKc" name="part.edit.tab.advanced.ipn.prefix_empty.direct_category">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix_empty.direct_category</source>
|
||||
<target>Префикс IPN для прямой категории пуст, укажите его в категории «%name%».</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="ec2DiJd" name="part.edit.tab.advanced.ipn.prefix.direct_category">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix.direct_category</source>
|
||||
<target>Префикс IPN для прямой категории</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="2e.kJb4" name="part.edit.tab.advanced.ipn.prefix.direct_category.increment">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix.direct_category.increment</source>
|
||||
<target>Префикс IPN прямой категории и специфическое для части приращение</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="ba1GCoq" name="part.edit.tab.advanced.ipn.prefix.hierarchical.no_increment">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix.hierarchical.no_increment</source>
|
||||
<target>IPN-префиксы с иерархическим порядком категорий родительских префиксов</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="d1uVFa3" name="part.edit.tab.advanced.ipn.prefix.hierarchical.increment">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix.hierarchical.increment</source>
|
||||
<target>IPN-префиксы с иерархическим порядком категорий родительских префиксов и специфическим увеличением для компонента</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="a4rPagW" name="part.edit.tab.advanced.ipn.prefix.not_saved">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix.not_saved</source>
|
||||
<target>Сначала создайте компонент и назначьте ему категорию: на основе существующих категорий и их собственных IPN-префиксов идентификатор IPN для компонента может быть предложен автоматически</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="c3S4jwK" name="part.edit.tab.part_lots">
|
||||
<notes>
|
||||
<note category="file-source" priority="1">Part-DB1\templates\Parts\edit\edit_part_info.html.twig:40</note>
|
||||
|
|
@ -6988,6 +7036,12 @@
|
|||
<target>Фильтр по имени</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="dsG4xTQ" name="category.edit.part_ipn_prefix">
|
||||
<segment state="translated">
|
||||
<source>category.edit.part_ipn_prefix</source>
|
||||
<target>Префикс IPN детали</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="yY_ld.7" name="category.edit.default_description">
|
||||
<notes>
|
||||
<note priority="1">obsolete</note>
|
||||
|
|
@ -10341,12 +10395,24 @@
|
|||
<target>e.g "/Конденсатор \d+ nF/i"</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="OXeGz1A" name="category.edit.part_ipn_prefix.placeholder">
|
||||
<segment state="translated">
|
||||
<source>category.edit.part_ipn_prefix.placeholder</source>
|
||||
<target>e.g "B12A"</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="DL.TreI" name="category.edit.partname_regex.help">
|
||||
<segment state="translated">
|
||||
<source>category.edit.partname_regex.help</source>
|
||||
<target>PCRE-совместимое регулярное выражение которому должно соответствовать имя компонента.</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="a1bUsfJ" name="category.edit.part_ipn_prefix.help">
|
||||
<segment state="translated">
|
||||
<source>category.edit.part_ipn_prefix.help</source>
|
||||
<target>Предлагаемый префикс при вводе IPN детали.</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="GzqIwHH" name="entity.select.add_hint">
|
||||
<segment state="translated">
|
||||
<source>entity.select.add_hint</source>
|
||||
|
|
|
|||
|
|
@ -1850,6 +1850,54 @@
|
|||
<target>高级</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="a1k7Blf" name="part.edit.tab.advanced.ipn.commonSectionHeader">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.commonSectionHeader</source>
|
||||
<target>Sugestie bez zwiększenia części</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="2achA.b" name="part.edit.tab.advanced.ipn.partIncrementHeader">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.partIncrementHeader</source>
|
||||
<target>包含部件数值增量的建议</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="dB1ChKc" name="part.edit.tab.advanced.ipn.prefix_empty.direct_category">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix_empty.direct_category</source>
|
||||
<target>直接类别的 IPN 前缀为空,请在类别“%name%”中指定。</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="ec2DiJd" name="part.edit.tab.advanced.ipn.prefix.direct_category">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix.direct_category</source>
|
||||
<target>直接类别的IPN前缀</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="2e.kJb4" name="part.edit.tab.advanced.ipn.prefix.direct_category.increment">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix.direct_category.increment</source>
|
||||
<target>直接类别的IPN前缀和部件特定的增量</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="ba1GCoq" name="part.edit.tab.advanced.ipn.prefix.hierarchical.no_increment">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix.hierarchical.no_increment</source>
|
||||
<target>具有父级前缀层级类别顺序的IPN前缀</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="d1uVFa3" name="part.edit.tab.advanced.ipn.prefix.hierarchical.increment">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix.hierarchical.increment</source>
|
||||
<target>具有父级前缀层级类别顺序和组件特定增量的IPN前缀</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="a4rPagW" name="part.edit.tab.advanced.ipn.prefix.not_saved">
|
||||
<segment state="translated">
|
||||
<source>part.edit.tab.advanced.ipn.prefix.not_saved</source>
|
||||
<target>请先创建组件并将其分配到类别:基于现有类别及其专属的IPN前缀,可以自动建议组件的IPN</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="uc9NwcF" name="part.edit.tab.part_lots">
|
||||
<notes>
|
||||
<note category="file-source" priority="1">Part-DB1\templates\Parts\edit\edit_part_info.html.twig:40</note>
|
||||
|
|
@ -6985,6 +7033,12 @@
|
|||
<target>名称过滤器</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="dsG4xTQ" name="category.edit.part_ipn_prefix">
|
||||
<segment state="translated">
|
||||
<source>category.edit.part_ipn_prefix</source>
|
||||
<target>部件 IPN 前缀</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="UH78POJ" name="category.edit.default_description">
|
||||
<notes>
|
||||
<note priority="1">obsolete</note>
|
||||
|
|
@ -10340,12 +10394,24 @@ Element 3</target>
|
|||
<target> </target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="OXeGz1A" name="category.edit.part_ipn_prefix.placeholder">
|
||||
<segment state="translated">
|
||||
<source>category.edit.part_ipn_prefix.placeholder</source>
|
||||
<target>例如:"B12A"</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="QFgP__5" name="category.edit.partname_regex.help">
|
||||
<segment state="translated">
|
||||
<source>category.edit.partname_regex.help</source>
|
||||
<target>与PCRE兼容的正则表达式,部分名称必须匹配。</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="a1bUsfJ" name="category.edit.part_ipn_prefix.help">
|
||||
<segment state="translated">
|
||||
<source>category.edit.part_ipn_prefix.help</source>
|
||||
<target>输入零件IPN时建议的前缀。</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="vr7oZKL" name="entity.select.add_hint">
|
||||
<segment state="translated">
|
||||
<source>entity.select.add_hint</source>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue